Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 109faf10 authored by schultezub's avatar schultezub
Browse files

* put class diagram under version control

 * Processors no longer have their own DataContainer, instead the DataContainer to work on is passed during process()
 * introduced VisualizationPipeline

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@180 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 5e424b90
#include "tumvispainter.h"
#include "tgt/assert.h"
#include "tgt/camera.h"
#include "tgt/quadric.h"
......@@ -6,7 +7,9 @@ namespace TUMVis {
const std::string TumVisPainter::loggerCat_ = "TUMVis.core.TumVisPainter";
TumVisPainter::TumVisPainter(tgt::GLCanvas* canvas)
: tgt::Painter(canvas) {
: tgt::Painter(canvas)
{
tgtAssert(getCanvas() != 0, "The given canvas must not be 0!");
}
void TumVisPainter::paint() {
......
......@@ -18,6 +18,8 @@ namespace TUMVis {
* also ensures (hopefully) that nobody can do messy things, such as adding the same AbstractData instance
* twice to a DataContainer (which would really mess up the lifetime management!).
*
* \todo We definately want thread-safety here!
*
* \todo If the original data changes, the other objects accessing that very DataHandle might want to
* get notified of the change. Hence, some observer pattern might be useful.
*/
......
......@@ -23,7 +23,7 @@ namespace TUMVis {
* given AbstractData instance. So do not delete it once it has been assigned to a
* DataHandle (respectively DataContainer).
*
* \todo
* \todo implement locks/mutexes as soon as we have a convenient library for that.
*/
class DataHandle {
......@@ -48,6 +48,7 @@ namespace TUMVis {
*/
AbstractData* getData();
private:
/**
* Creates a new DataHandle for \a data and takes its ownership in terms of lifetime management.
......
......@@ -4,6 +4,7 @@
#include "tgt/texture.h"
#include "tgt/vector.h"
#include "core/datastructures/imagedata.h"
#include "core/tools/typetraits.h"
#include "core/tools/weaklytypedpointer.h"
namespace TUMVis {
......
......@@ -3,34 +3,22 @@
namespace TUMVis {
const std::string AbstractPipeline::loggerCat_ = "TUMVis.core.datastructures.AbstractPipeline";
AbstractPipeline::AbstractPipeline(tgt::GLCanvas* canvas /*= 0*/)
: _canvas(canvas)
AbstractPipeline::AbstractPipeline()
{
}
AbstractPipeline::~AbstractPipeline() {
}
void AbstractPipeline::onEvent(tgt::Event* e) {
// cycle through event handlers, ask each one if it handles the event and if so, execute it.
for (std::vector<AbstractEventHandler*>::iterator it = _eventHandlers.begin(); it != _eventHandlers.end() && !e->isAccepted(); ++it) {
if ((*it)->accept(e)) {
(*it)->execute(e);
}
}
PropertyCollection& AbstractPipeline::getPropertyCollection() {
return _properties;
}
void AbstractPipeline::setCanvas(tgt::GLCanvas* canvas) {
if (_canvas != 0 && _canvas->getEventHandler() != 0) {
_canvas->getEventHandler()->removeListener(this);
}
_canvas = canvas;
if (_canvas->getEventHandler() != 0) {
_canvas->getEventHandler()->addListenerToFront(this);
}
void AbstractPipeline::init() {
// initialize all processors:
// for (std::vector<AbstractProcessor*>::iterator it = _processors.begin(); it != _processors.end(); ++it) {
// (*it)->initGL();
// }
}
PropertyCollection& AbstractPipeline::getPropertyCollection() {
return _properties;
}
}
#ifndef ABSTRACTPIPELINE_H__
#define ABSTRACTPIPELINE_H__
#include "tgt/glcanvas.h"
#include "tgt/logmanager.h"
#include "tgt/event/eventlistener.h"
#include "core/datastructures/datacontainer.h"
#include "core/eventhandlers/abstracteventhandler.h"
#include "core/pipeline/abstractprocessor.h"
#include "core/properties/propertycollection.h"
#include <vector>
......@@ -16,12 +14,12 @@ namespace TUMVis {
* Abstract base class for TUMVis Pipelines.
*
*/
class AbstractPipeline : public tgt::EventListener {
class AbstractPipeline {
public:
/**
* Creates a AbstractPipeline.
*/
AbstractPipeline(tgt::GLCanvas* canvas = 0);
AbstractPipeline();
/**
* Virtual Destructor
......@@ -30,22 +28,16 @@ namespace TUMVis {
/**
* Execute this pipeline.
**/
virtual void execute() = 0;
/**
* Performs the event handling for the assigned canvas.
* Default behaviour is to execute all assigned EventHandlers, may be overwritten by subclasses.
* \param e event parameters
* Initializes the OpenGL context of the pipeline and its processors.
*
* \note When overwriting this method, make sure to call the base class version first.
*/
virtual void onEvent(tgt::Event* e);
virtual void init();
/**
* Sets the target canvas for rendering.
* \param canvas Target canvas for rendering
*/
void setCanvas(tgt::GLCanvas* canvas);
* Execute this pipeline.
**/
virtual void execute() = 0;
/**
* Returns the PropertyCollection of this processor.
......@@ -55,9 +47,8 @@ namespace TUMVis {
protected:
DataContainer _data; ///< DataContainer containing local working set of data for this Pipeline
tgt::GLCanvas* _canvas; ///< Target canvas for rendering
std::vector<AbstractEventHandler*> _eventHandlers; ///< List of registered event handlers for the pipeline
std::vector<AbstractProcessor*> _processors; ///< List of all processors of this pipeline
PropertyCollection _properties; ///< PropertyCollection of this pipeline, put in here all properties you want to be publicly accessible
static const std::string loggerCat_;
......
......@@ -13,24 +13,12 @@ namespace TUMVis {
}
void AbstractProcessor::addDataHandle(const std::string& name, const DataHandle* dh) {
_dataContainer.addDataHandle(name, dh);
}
const DataContainer& AbstractProcessor::getDataContainer() const {
return _dataContainer;
}
const InvalidationLevel& AbstractProcessor::getInvalidationLevel() const {
return _invalidationLevel;
}
void AbstractProcessor::applyInvalidationLevel(InvalidationLevel::NamedLevels nl) {
_invalidationLevel.setLevel(nl);
}
void AbstractProcessor::onNotify(const PropertyObserverArgs& poa) {
_invalidationLevel.setLevel(poa._invalidationLevel);
void AbstractProcessor::applyInvalidationLevel(InvalidationLevel il) {
_invalidationLevel.setLevel(il);
// If processor is no longer valid, notify observers
if (! _invalidationLevel.isValid()) {
......@@ -38,7 +26,12 @@ namespace TUMVis {
}
}
void AbstractProcessor::onNotify(const PropertyObserverArgs& poa) {
applyInvalidationLevel(poa._invalidationLevel);
}
PropertyCollection& AbstractProcessor::getPropertyCollection() {
return _properties;
}
}
......@@ -33,10 +33,28 @@ namespace TUMVis {
/**
* Abstract base class for TUMVis Processors.
* A processor implements a specific task, which it performs on the DataCollection passed
* during process(). Properties provide a transparent layer for adjusting the processor's
* behaviour.
* Once a processor has finished it sets it should set its invalidation level to valid. As
* soon as one of its properties changes, the processor will be notified and possibliy
* change its invalidation level. Observing pipelines will be notified of this and can
* and have to decide which part of the pipeline has to be re-evaluated wrt. the processor's
* invalidation level.
*
* \sa AbstractPipeline
*/
class AbstractProcessor : GenericObserver<PropertyObserverArgs>, public GenericObservable<ProcessorObserverArgs> {
/**
* We have to find a trade-off:
* On the one hand, we want to follow the information-hiding concept and keep the processor's
* properties private. On the other hand pipelines will usually want direct access to them
* (e.g. in order to setup data IDs or property sharing) and the properties in the PropertyCollection
* are not strongly typed. Hence, we declare AbstractPipeline as our friend.
*/
friend class AbstractPipeline;
public:
/**
......@@ -52,23 +70,9 @@ namespace TUMVis {
/**
* Execute this processor.
* \param data DataContainer to work on.
**/
virtual void process() = 0;
/**
* Adds the given DataHandle \a data, accessible by the key \name, to this DataContainer.
* Already existing DataHandles with the same key will be removed from this DataContainer.
*
* \param name Key for accessing the DataHandle within this DataContainer
* \param data DataHandle to add.
**/
virtual void addDataHandle(const std::string& name, const DataHandle* dh);
/**
* Returns the local DataContainer of this Processor.
* \return _dataContainer
**/
const DataContainer& getDataContainer() const;
virtual void process(DataContainer& data) = 0;
/**
* Returns the invalidation level of this processor.
......@@ -78,7 +82,7 @@ namespace TUMVis {
/**
* Returns the PropertyCollection of this processor.
* \return _properties
* \return _properties
*/
PropertyCollection& getPropertyCollection();
......@@ -88,9 +92,8 @@ namespace TUMVis {
* If \a nl is one of the INVALID_X state, the processor's corresponding flag will be set.
* \param nl Invalidation level to apply.
*/
void applyInvalidationLevel(InvalidationLevel::NamedLevels nl);
void applyInvalidationLevel(InvalidationLevel il);
/**
* Gets called when one of the observed properties changed notifies its observers.
* \sa GenericObserver::onNotify, AbstractProperty
......@@ -100,7 +103,6 @@ namespace TUMVis {
protected:
DataContainer _dataContainer; ///< DataContainer containing local working set of data for this Processor
InvalidationLevel _invalidationLevel; ///< current invalidation level of this processor
PropertyCollection _properties; ///< PropertyCollection of this processor
......
#include "visualizationpipeline.h"
namespace TUMVis {
const std::string VisualizationPipeline::loggerCat_ = "TUMVis.core.datastructures.VisualizationPipeline";
VisualizationPipeline::VisualizationPipeline(tgt::GLCanvas* canvas /*= 0*/)
: _canvas(canvas)
{
}
VisualizationPipeline::~VisualizationPipeline() {
}
void VisualizationPipeline::onEvent(tgt::Event* e) {
// cycle through event handlers, ask each one if it handles the event and if so, execute it.
for (std::vector<AbstractEventHandler*>::iterator it = _eventHandlers.begin(); it != _eventHandlers.end() && !e->isAccepted(); ++it) {
if ((*it)->accept(e)) {
(*it)->execute(e);
}
}
}
void VisualizationPipeline::setCanvas(tgt::GLCanvas* canvas) {
if (_canvas != 0 && _canvas->getEventHandler() != 0) {
_canvas->getEventHandler()->removeListener(this);
}
_canvas = canvas;
if (_canvas->getEventHandler() != 0) {
_canvas->getEventHandler()->addListenerToFront(this);
}
}
PropertyCollection& VisualizationPipeline::getPropertyCollection() {
return _properties;
}
void VisualizationPipeline::init() {
AbstractPipeline::init();
// initialize all processors:
// for (std::vector<AbstractProcessor*>::iterator it = _processors.begin(); it != _processors.end(); ++it) {
// (*it)->initGL();
// }
}
void VisualizationPipeline::paint() {
// TODO: implement - is there a generic way to initiate the painting in the subclasses?
}
void VisualizationPipeline::sizeChanged(const tgt::ivec2& size) {
// nothing to change if nothing changes
if (size != _canvasSize) {
_canvasSize = size;
}
// TODO: initiate pipeline evaluation, is a simple execute() what we want?
execute();
}
}
#ifndef VISUALIZATIONPIPELINE_H__
#define VISUALIZATIONPIPELINE_H__
#include "tgt/glcanvas.h"
#include "tgt/painter.h"
#include "tgt/event/eventlistener.h"
#include "core/eventhandlers/abstracteventhandler.h"
#include "core/pipeline/abstractpipeline.h"
#include <vector>
namespace TUMVis {
/**
* Abstract base class for TUMVis Pipelines.
*
*/
class VisualizationPipeline : public AbstractPipeline, public tgt::EventListener, public tgt::Painter {
public:
/**
* Creates a VisualizationPipeline.
*/
VisualizationPipeline(tgt::GLCanvas* canvas = 0);
/**
* Virtual Destructor
**/
virtual ~VisualizationPipeline();
/**
* Initializes the OpenGL context of the pipeline and its processors.
* \todo merge with init() ?
* \note When overwriting this method, make sure to call the base class version first.
*/
virtual void init();
/**
* Execute this pipeline.
**/
virtual void execute() = 0;
/**
* Performs the event handling for the assigned canvas.
* Default behaviour is to execute all assigned EventHandlers, may be overwritten by subclasses.
* \param e event parameters
*/
virtual void onEvent(tgt::Event* e);
/**
* Acquires the OpenGL context, and executes the pipeline
*/
virtual void paint();
/**
* Is called when the viewport dimensions change, notifies the pipeline of that.
* \param size New viewport dimensions
*/
virtual void sizeChanged(const tgt::ivec2& size);
/**
* Sets the target canvas for rendering.
* \param canvas Target canvas for rendering
*/
void setCanvas(tgt::GLCanvas* canvas);
/**
* Returns the PropertyCollection of this processor.
* \return _properties
*/
PropertyCollection& getPropertyCollection();
protected:
DataContainer _data; ///< DataContainer containing local working set of data for this Pipeline
tgt::GLCanvas* _canvas; ///< Target canvas for rendering
tgt::ivec2 _canvasSize; ///< Viewport size of target canvas
std::vector<AbstractEventHandler*> _eventHandlers; ///< List of registered event handlers for the pipeline
std::vector<AbstractProcessor*> _processors; ///< List of all processors of this pipeline
PropertyCollection _properties; ///< PropertyCollection of this pipeline, put in here all properties you want to be publicly accessible
static const std::string loggerCat_;
};
}
#endif // VISUALIZATIONPIPELINE_H__
......@@ -36,6 +36,7 @@ namespace TUMVis {
* Abstract base class for TUMVis Property.
*
* \todo Add PropertyWidgets, add clone()?
* Think about a reasonable locking mechanism and implement that
*/
class AbstractProperty : public GenericObservable<PropertyObserverArgs> {
public:
......
......@@ -27,7 +27,7 @@ namespace TUMVis {
INT32, ///< signed 32 bit integer
FLOAT, ///< float
UINT64, ///< unsigned 64 bit integer
INT64, ///< signed 64 bit integer q
INT64, ///< signed 64 bit integer
DOUBLE ///< double
};
......
......@@ -17,20 +17,24 @@ namespace TUMVis {
MhdImageReader::MhdImageReader()
: AbstractProcessor()
, _url("url", "Image URL", "")
, _targetImageID("targetImageName", "Target Image ID", "MhdImageReader.output")
{
_properties.addProperty(&_url);
_properties.addProperty(&_targetImageID);
ImageDataRAMTraits<float, 2>::ImageType* img = new ImageDataRAMTraits<float, 2>::ImageType(2, tgt::svec3(2, 2, 1), 0);
// just testing some type traits...
//ImageDataRAMTraits<float, 2>::ImageType* img = new ImageDataRAMTraits<float, 2>::ImageType(2, tgt::svec3(2, 2, 1), 0);
}
MhdImageReader::~MhdImageReader() {
}
void MhdImageReader::process() {
void MhdImageReader::process(DataContainer& data) {
TextFileParser tfp(_url.getValue(), true, "=");
tfp.parse<TextFileParser::ItemSeparatorLines>();
// init optional parameters with sane default values
std::string url;
size_t dimensionality;
tgt::svec3 size;
......@@ -119,7 +123,7 @@ namespace TUMVis {
// all parsing done - lets create the image:
ImageDataDisk* image = new ImageDataDisk(url, dimensionality, size, pt, offset, e);
_dataContainer.addData("output.image.read", image);
data.addData(_targetImageID.getValue(), image);
}
catch (tgt::Exception& e) {
LERROR("Error while parsing MHD header: " << e.what());
......
......@@ -8,7 +8,7 @@
namespace TUMVis {
/**
*
* Reads a MHD image file into the pipeline.
*
* \note Full format specification at http://www.itk.org/Wiki/MetaIO/Documentation
*/
......@@ -25,13 +25,16 @@ namespace TUMVis {
virtual ~MhdImageReader();
virtual void process();
/**
* Reads the MHD file into an ImageDataDisk representation
* \param data DataContainer to work on
*/
virtual void process(DataContainer& data);
private:
void parseHeader();
// TODO make this a property as soon as the property system exists
GenericProperty<std::string> _url;
GenericProperty<std::string> _url; ///< URL for file to read
GenericProperty<std::string> _targetImageID; ///< image ID for read image
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