/*
-----------------------------------------------------------------------
Copyright: 2010-2021, imec Vision Lab, University of Antwerp
2014-2021, CWI, Amsterdam
Contact: astra@astra-toolbox.com
Website: http://www.astra-toolbox.com/
This file is part of the ASTRA Toolbox.
The ASTRA Toolbox is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The ASTRA Toolbox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the ASTRA Toolbox. If not, see .
-----------------------------------------------------------------------
*/
#ifndef _INC_ASTRA_DATAPROJECTOR
#define _INC_ASTRA_DATAPROJECTOR
#include "Projector2D.h"
#include "TypeList.h"
#include "ProjectorTypelist.h"
#include "DataProjectorPolicies.h"
namespace astra
{
/**
* Interface class for the Data Projector. The sole purpose of this class is to force child classes to implement a series of methods
*/
class CDataProjectorInterface {
public:
CDataProjectorInterface() { }
virtual ~CDataProjectorInterface() { }
virtual void project() = 0;
virtual void projectSingleProjection(int _iProjection) = 0;
virtual void projectSingleRay(int _iProjection, int _iDetector) = 0;
// virtual void projectSingleVoxel(int _iRow, int _iCol) = 0;
// virtual void projectAllVoxels() = 0;
};
/**
* Templated Data Projector Class. In this class a specific projector and policies are combined.
*/
template
class CDataProjector: public CDataProjectorInterface {
private:
Projector* m_pProjector;
Policy m_pPolicy;
public:
CDataProjector() {};
CDataProjector(Projector* _p, Policy _a);
~CDataProjector();
virtual void project();
virtual void projectSingleProjection(int _iProjection);
virtual void projectSingleRay(int _iProjection, int _iDetector);
// virtual void projectSingleVoxel(int _iRow, int _iCol);
// virtual void projectAllVoxels();
};
//----------------------------------------------------------------------------------------
/**
* Constructor
*/
template
CDataProjector::CDataProjector(Projector* _p, Policy _a)
{
m_pProjector = _p;
m_pPolicy = _a;
}
//----------------------------------------------------------------------------------------
/**
* Destructor
*/
template
CDataProjector::~CDataProjector()
{
// does nothing
}
//----------------------------------------------------------------------------------------
/**
* Compute projection using the algorithm specific to the projector type
*/
template
void CDataProjector::project()
{
m_pProjector->project(m_pPolicy);
}
//----------------------------------------------------------------------------------------
/**
* Compute just one projection using the algorithm specific to the projector type
*/
template
void CDataProjector::projectSingleProjection(int _iProjection)
{
m_pProjector->projectSingleProjection(_iProjection, m_pPolicy);
}
//----------------------------------------------------------------------------------------
/**
* Compute projection of one ray using the algorithm specific to the projector type
*/
template
void CDataProjector::projectSingleRay(int _iProjection, int _iDetector)
{
m_pProjector->projectSingleRay(_iProjection, _iDetector, m_pPolicy);
}
//----------------------------------------------------------------------------------------
//template
//void CDataProjector::projectSingleVoxel(int _iRow, int _iCol)
//{
// m_pProjector->projectSingleVoxel(_iRow, _iCol, m_pPolicy);
//}
//----------------------------------------------------------------------------------------
//template
//void CDataProjector::projectAllVoxels()
//{
// m_pProjector->projectAllVoxels(m_pPolicy);
//}
//----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
// Create a new datainterface from the projector TypeList
namespace typelist {
template
struct CreateDataProjector {
template
static void find (U& functor, CProjector2D* _pProjector, const Policy& _pPolicy) {
if (functor(TList::Head::type)) {
functor.res = new CDataProjector(static_cast(_pProjector), _pPolicy);
}
CreateDataProjector::find(functor, _pProjector, _pPolicy);
}
};
template <>
struct CreateDataProjector {
template
static void find(U& functor, CProjector2D* _pProjector, const Policy& _pPolicy) {}
};
struct functor_find_datainterface {
functor_find_datainterface() { res = NULL; }
bool operator() (std::string name) {
return strcmp(tofind.c_str(), name.c_str()) == 0;
}
std::string tofind;
CDataProjectorInterface* res;
};
}
//-----------------------------------------------------------------------------------------
/**
* Data Projector Dispatcher - 1 Policy
*/
template
static CDataProjectorInterface* dispatchDataProjector(CProjector2D* _pProjector, const Policy& _policy)
{
typelist::functor_find_datainterface finder = typelist::functor_find_datainterface();
finder.tofind = _pProjector->getType();
typelist::CreateDataProjector::find(finder, _pProjector, _policy);
return finder.res;
}
/**
* Data Projector Dispatcher - 2 Policies
*/
template
static CDataProjectorInterface* dispatchDataProjector(CProjector2D* _pProjector,
const Policy1& _policy,
const Policy2& _policy2,
bool _bUsePolicy1 = true,
bool _bUsePolicy2 = true)
{
if (!_bUsePolicy1 && !_bUsePolicy2) {
return dispatchDataProjector(_pProjector, EmptyPolicy());
} else if (!_bUsePolicy1) {
return dispatchDataProjector(_pProjector, _policy2);
} else if (!_bUsePolicy2) {
return dispatchDataProjector(_pProjector, _policy);
} else {
return dispatchDataProjector(_pProjector, CombinePolicy(_policy, _policy2));
}
}
/**
* Data Projector Dispatcher - 3 Policies
*/
template
static CDataProjectorInterface* dispatchDataProjector(CProjector2D* _pProjector,
const Policy1& _policy1,
const Policy2& _policy2,
const Policy3& _policy3,
bool _bUsePolicy1 = true,
bool _bUsePolicy2 = true,
bool _bUsePolicy3 = true)
{
if (!_bUsePolicy1) {
return dispatchDataProjector(_pProjector, _policy2, _policy3, _bUsePolicy2, _bUsePolicy3);
} else if (!_bUsePolicy2) {
return dispatchDataProjector(_pProjector, _policy1, _policy3, _bUsePolicy1, _bUsePolicy3);
} else if (!_bUsePolicy3) {
return dispatchDataProjector(_pProjector, _policy1, _policy2, _bUsePolicy1, _bUsePolicy2);
} else {
return dispatchDataProjector(_pProjector, Combine3Policy(_policy1, _policy2, _policy3));
}
}
/**
* Data Projector Dispatcher - 4 Policies
*/
template
static CDataProjectorInterface* dispatchDataProjector(CProjector2D* _pProjector,
const Policy1& _policy1,
const Policy2& _policy2,
const Policy3& _policy3,
const Policy4& _policy4,
bool _bUsePolicy1 = true,
bool _bUsePolicy2 = true,
bool _bUsePolicy3 = true,
bool _bUsePolicy4 = true)
{
if (!_bUsePolicy1) {
return dispatchDataProjector(_pProjector, _policy2, _policy3, _policy4, _bUsePolicy2, _bUsePolicy3, _bUsePolicy4);
} else if (!_bUsePolicy2) {
return dispatchDataProjector(_pProjector, _policy1, _policy3, _policy4, _bUsePolicy1, _bUsePolicy3, _bUsePolicy4);
} else if (!_bUsePolicy3) {
return dispatchDataProjector(_pProjector, _policy1, _policy2, _policy4, _bUsePolicy1, _bUsePolicy2, _bUsePolicy4);
} else if (!_bUsePolicy4) {
return dispatchDataProjector(_pProjector, _policy1, _policy2, _policy3, _bUsePolicy1, _bUsePolicy2, _bUsePolicy3);
} else {
return dispatchDataProjector(_pProjector, Combine4Policy(_policy1, _policy2, _policy3, _policy4));
}
}
/**
* Data Projector Dispatcher - 5 Policies
*/
template
static CDataProjectorInterface* dispatchDataProjector(CProjector2D* _pProjector,
const Policy1& _policy1,
const Policy2& _policy2,
const Policy3& _policy3,
const Policy4& _policy4,
const Policy5& _policy5,
bool _bUsePolicy1 = true,
bool _bUsePolicy2 = true,
bool _bUsePolicy3 = true,
bool _bUsePolicy4 = true,
bool _bUsePolicy5 = true)
{
if (!_bUsePolicy1) {
return dispatchDataProjector(_pProjector, _policy2, _policy3, _policy4, _policy5, _bUsePolicy2, _bUsePolicy3, _bUsePolicy4, _bUsePolicy5);
} else if (!_bUsePolicy2) {
return dispatchDataProjector(_pProjector, _policy1, _policy3, _policy4, _policy5, _bUsePolicy1, _bUsePolicy3, _bUsePolicy4, _bUsePolicy5);
} else if (!_bUsePolicy3) {
return dispatchDataProjector(_pProjector, _policy1, _policy2, _policy4, _policy5, _bUsePolicy1, _bUsePolicy2, _bUsePolicy4, _bUsePolicy5);
} else if (!_bUsePolicy4) {
return dispatchDataProjector(_pProjector, _policy1, _policy2, _policy3, _policy5, _bUsePolicy1, _bUsePolicy2, _bUsePolicy3, _bUsePolicy5);
} else if (!_bUsePolicy5) {
return dispatchDataProjector(_pProjector, _policy1, _policy2, _policy3, _policy4, _bUsePolicy1, _bUsePolicy2, _bUsePolicy3, _bUsePolicy4);
} else {
return dispatchDataProjector(_pProjector, CombinePolicy< Combine4Policy, Policy5>(
Combine4Policy(_policy1, _policy2, _policy3, _policy4),
_policy5)
);
}
}
//-----------------------------------------------------------------------------------------
/**
* Data Projector Project
*/
template
static void projectData(CProjector2D* _pProjector, const Policy& _policy)
{
CDataProjectorInterface* dp = dispatchDataProjector(_pProjector, _policy);
dp->project();
delete dp;
}
} // namespace astra
#endif