Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

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.