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

Merge branch 'procfactory' into 'development'

Procfactory

See merge request !110
parents 75aa45ba a66c7701
......@@ -328,7 +328,7 @@ namespace campvis {
virtual size_t getVideoMemoryFootprint() const = 0;
virtual AbstractData* clone() const = 0;
};
/* DataHandle */
class DataHandle {
......
......@@ -82,6 +82,7 @@ namespace campvis {
* \note When overwriting this method, make sure to call the base class version at the end.
*/
virtual void deinit();
DataNameProperty p_sourceImageID; ///< image ID for input image
DataNameProperty p_entryImageID; ///< image ID for output entry points image
......
......@@ -76,7 +76,7 @@ namespace campvis {
/// \see AbstractProcessor::deinit
virtual void deinit();
/// \see cgt::EventListener::onEvent()
virtual void onEvent(cgt::Event* e);
......
......@@ -9,9 +9,11 @@ LIST(APPEND CampvisModulesHeaders
modulesapi.h
gen_pipelineregistration.h
pipelinefactory.h
processorfactory.h
)
LIST(APPEND CampvisModulesSources
pipelinefactory.cpp
processorfactory.cpp
)
......
......@@ -32,6 +32,7 @@
#include "core/properties/floatingpointproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace campvis {
/**
......@@ -49,9 +50,13 @@ namespace campvis {
* Destructor
**/
virtual ~LightSourceProvider();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "LightSourceProvider"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "LightSourceProvider"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Creates LightSourceData and stores it in the DataContainer."; };
/// \see AbstractProcessor::getAuthor()
......@@ -74,6 +79,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<LightSourceProvider>;
}
#endif // LIGHTSOURCEPROVIDER_H__
......@@ -43,6 +43,7 @@
#include "modules/vis/processors/sliceextractor.h"
#include <vector>
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
......@@ -113,9 +114,13 @@ namespace campvis {
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "MicroscopyImageSegmentation"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "MicroscopyImageSegmentation"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Combines a volume raycaster and 3 slice views for explorative volume visualization."; };
/// \see AbstractProcessor::getAuthor()
......@@ -223,6 +228,8 @@ namespace campvis {
int insertNextVoxelAt;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<MicroscopyImageSegmentation>;
}
#endif // MICROSCOPYIMAGESEGMENTATION_H__
......@@ -34,6 +34,7 @@
#include "core/properties/optionproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace cgt {
class BufferObject;
......@@ -60,9 +61,13 @@ namespace campvis {
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "GlGaussianFilter"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "GlGaussianFilter"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Performs a gaussian filtering on the input image using OpenGL."; };
/// \see AbstractProcessor::getAuthor()
......@@ -96,6 +101,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<GlGaussianFilter>;
}
#endif // GLGAUSSIANFILTER_H__
......@@ -32,6 +32,7 @@
#include "core/properties/datanameproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
......@@ -57,9 +58,13 @@ namespace campvis {
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "GlGradientVolumeGenerator"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "GlGradientVolumeGenerator"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Creates the gradient volume for the given intensity volume using OpenGL."; };
/// \see AbstractProcessor::getAuthor()
......@@ -83,6 +88,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<GlGradientVolumeGenerator>;
}
#endif // GLGRADIENTVOLUMEGENERATOR_H__
......@@ -32,6 +32,7 @@
#include "core/properties/datanameproperty.h"
#include "core/properties/transferfunctionproperty.h"
#include "core/properties/numericproperty.h"
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
......@@ -57,9 +58,13 @@ namespace campvis {
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "GlImageCrop"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "GlImageCrop"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Quantizes image intensities into a fixed number of bins using the GPU."; };
/// \see AbstractProcessor::getAuthor()
......@@ -84,6 +89,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<GlImageCrop>;
}
#endif // GLIMAGECROP_H__
......@@ -33,6 +33,7 @@
#include "core/properties/floatingpointproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
......@@ -58,9 +59,13 @@ namespace campvis {
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "GlImageResampler"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "GlImageResampler"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Resamples am image on the GPU using OpenGL."; };
/// \see AbstractProcessor::getAuthor()
......@@ -84,6 +89,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<GlImageResampler>;
}
#endif // GLIMAGERESAMPLER_H__
......
......@@ -34,6 +34,7 @@
#include "core/properties/numericproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
......@@ -59,9 +60,13 @@ namespace campvis {
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "GlIntensityQuantizer"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "GlIntensityQuantizer"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Quantizes image intensities into a fixed number of bins using the GPU."; };
/// \see AbstractProcessor::getAuthor()
......@@ -84,6 +89,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<GlIntensityQuantizer>;
}
#endif // GLINTENSITYQUANTIZER_H__
......@@ -34,6 +34,7 @@
#include "core/properties/stringproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
......@@ -59,9 +60,13 @@ namespace campvis {
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "GlMorphologyFilter"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "GlMorphologyFilter"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Creates the gradient volume for the given intensity volume using OpenGL."; };
/// \see AbstractProcessor::getAuthor()
......@@ -98,6 +103,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<GlMorphologyFilter>;
}
#endif // GLMORPHOLOGYFILTER_H__
......@@ -32,6 +32,7 @@
#include "core/properties/datanameproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
......@@ -57,9 +58,13 @@ namespace campvis {
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "GlSignalToNoiseRatioFilter"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "GlSignalToNoiseRatioFilter"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Creates the gradient volume for the given intensity volume using OpenGL."; };
/// \see AbstractProcessor::getAuthor()
......@@ -81,6 +86,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<GlSignalToNoiseRatioFilter>;
}
#endif // GLSIGNALTONOISERATIOFILTER_H__
......@@ -32,6 +32,7 @@
#include "core/properties/floatingpointproperty.h"
#include "modules/modulesapi.h"
#include "modules/processorfactory.h"
namespace cgt {
class Shader;
......@@ -57,9 +58,13 @@ namespace campvis {
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
/**
* To be used in ProcessorFactory static methods
*/
static const std::string getId() { return "GlVesselnessFilter"; };
/// \see AbstractProcessor::getName()
virtual const std::string getName() const { return "GlVesselnessFilter"; };
virtual const std::string getName() const { return getId(); };
/// \see AbstractProcessor::getDescription()
virtual const std::string getDescription() const { return "Computes a Vesselness Measure very similar to the one proposed by Frangi."; };
/// \see AbstractProcessor::getAuthor()
......@@ -87,6 +92,8 @@ namespace campvis {
static const std::string loggerCat_;
};
// Instantiate template to register the pipelines.
template class SmartProcessorRegistrar<GlVesselnessFilter>;
}
#endif // GLVESSELNESSFILTER_H__
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#include "processorfactory.h"
//#include "gen_processorregistration.h"
#include <sstream>
namespace campvis {
// declare one single symbol for the ProcessorFactory singleton
tbb::atomic<ProcessorFactory*> ProcessorFactory::_singleton;
ProcessorFactory& ProcessorFactory::getRef() {
if (_singleton == 0) {
std::cout << "creating ProcessorFactory...\n";
ProcessorFactory* tmp = new ProcessorFactory();
if (_singleton.compare_and_swap(tmp, 0) != 0) {
delete tmp;
}
}
return *_singleton;
}
void ProcessorFactory::deinit() {
delete _singleton;
_singleton = nullptr;
}
std::vector<std::string> ProcessorFactory::getRegisteredProcessors() const {
tbb::spin_mutex::scoped_lock lock(_mutex);
std::vector<std::string> toReturn;
toReturn.reserve(_processorMapWithIVec2Param.size()+_processorMapDefault.size());
for (auto it = _processorMapWithIVec2Param.begin(); it != _processorMapWithIVec2Param.end(); ++it)
toReturn.push_back(it->first);
for (auto it = _processorMapDefault.begin(); it != _processorMapDefault.end(); ++it)
toReturn.push_back(it->first);
return toReturn;
}
AbstractProcessor* ProcessorFactory::createProcessor(const std::string& id, IVec2Property* viewPortSizeProp) const {
tbb::spin_mutex::scoped_lock lock(_mutex);
if (viewPortSizeProp != nullptr) {
auto it = _processorMapWithIVec2Param.find(id);
if (it == _processorMapWithIVec2Param.end())
return nullptr;
else
return (it->second)(viewPortSizeProp);
} else {
auto it = _processorMapDefault.find(id);
if (it == _processorMapDefault.end())
return nullptr;
else
return (it->second)();
}
}
}
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#ifndef PROCESSORFACTORY_H__
#define PROCESSORFACTORY_H__
#include "cgt/logmanager.h"
#include "cgt/singleton.h"
#include <tbb/atomic.h>
#include <tbb/spin_mutex.h>
#include "modules/modulesapi.h"
#include <functional>
#include <map>
#include <string>
#include <type_traits>
#include <typeindex>
#include <vector>
#include "core/pipeline/visualizationprocessor.h"
namespace campvis {
class AbstractProcessor;
class DataContainer;
/**
* Factory for creating processors by their name.
* Using some template-magic, ProcessorFactory is able to register processors during static
* initialization in cooperation with the ProcessorRegistrar.
*
* \note ProcessorFactory is a thread-safe lazy-instantiated singleton.
*/
class CAMPVIS_MODULES_API ProcessorFactory {
public:
/**
* Returns a reference to the ProcessorFactory singleton.
* Creates the singleton if necessary
* \return *_singleton
*/
static ProcessorFactory& getRef();
static void deinit();
std::vector<std::string> getRegisteredProcessors() const;
AbstractProcessor* createProcessor(const std::string& id, IVec2Property* viewPortSizeProp = 0) const;
/**
* Statically registers the processor of type T with construction T() using \a callee as factory method.
* \note The template instantiation of ProcessorRegistrar takes care of calling this method.
* \param callee Factory method to call to create an instance of type T
* \return The registration index.
*/
template<typename T>
size_t registerProcessorWithDefaultConstructor(std::function<AbstractProcessor*()> callee) {
tbb::spin_mutex::scoped_lock lock(_mutex);
auto it = _processorTypeMap.find(T::getId());
if (it != _processorTypeMap.end()) {
// check, whether the type is the same, then a double registration is okay since it
// may occur due to having the ProcessorRegistrar being referenced in both
// campvis-application and campvis-modules.
cgtAssert(std::type_index(typeid(T)) == it->second, "Tried to register two different processor types with the same ID.");
}
else {
_processorTypeMap.insert(it, std::make_pair(T::getId(), std::type_index(typeid(T))));
}
_processorMapDefault[T::getId()] = callee;
return _processorMapDefault.size();
}
/**
* Statically registers the processor of type T with constructor T(IVec2Property) using \a callee as factory method.
* \note The template instantiation of ProcessorRegistrar takes care of calling this method.
* \param callee Factory method to call to create an instance of type T
* \return The registration index.
*/
template<typename T>
size_t registerProcessorWithIVec2PropParam(std::function<AbstractProcessor*(IVec2Property*)> callee) {
tbb::spin_mutex::scoped_lock lock(_mutex);
auto it = _processorTypeMap.find(T::getId());
if (it != _processorTypeMap.end()) {
// check, whether the type is the same, then a double registration is okay since it
// may occur due to having the ProcessorRegistrar being referenced in both
// campvis-application and campvis-modules.
cgtAssert(std::type_index(typeid(T)) == it->second, "Tried to register two different processor types with the same ID.");
}
else {
_processorTypeMap.insert(it, std::make_pair(T::getId(), std::type_index(typeid(T))));
}
_processorMapWithIVec2Param[T::getId()] = callee;
return _processorMapWithIVec2Param.size();
}
private:
mutable tbb::spin_mutex _mutex;
static tbb::atomic<ProcessorFactory*> _singleton; ///< the singleton object
std::map< std::string, std::type_index> _processorTypeMap;
std::map< std::string, std::function<AbstractProcessor*()> > _processorMapDefault;
std::map< std::string, std::function<AbstractProcessor*(IVec2Property*)> > _processorMapWithIVec2Param;
};
// ================================================================================================
template<typename T, bool>
class ProcessorRegistrarSwitch {
};
template<typename T>
class ProcessorRegistrarSwitch<T, false> {
public:
/**
* Static factory method for creating the processor of type T.
* \return A newly created processor of type T. Caller has to take ownership of the pointer.
*/
static AbstractProcessor* create() {
return new T();
}
/// static helper field to ensure registration at static initialization time.
static const size_t _factoryId;
};
template<typename T>
const size_t ProcessorRegistrarSwitch<T, false>::_factoryId = ProcessorFactory::getRef().registerProcessorWithDefaultConstructor<T>(&ProcessorRegistrarSwitch<T, false>::create);
template<typename T>
class ProcessorRegistrarSwitch<T, true> {
public:
/**
* Static factory method for creating the processor of type T.
* \param viewPortSizeProp viewPortSizeProp for the created processor to work on.
* \return A newly created processor of type T. Caller has to take ownership of the pointer.
*/
static AbstractProcessor* create(IVec2Property* viewPortSizeProp) {
return new T(viewPortSizeProp);