mm";
stream<<"; Index: <"< ";
mitk::ScalarType pixelValue = image3D->GetPixelValueByIndex(p, baseRenderer->GetTimeStep());
if (fabs(pixelValue)>1000000)
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<GetPixelValueByIndex(p, baseRenderer->GetTimeStep())<<" ";
}
else
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<GetPixelValueByIndex(p, baseRenderer->GetTimeStep())<<" ";
}
}
else
{
stream << "No image information at this position!";
}
statusText = stream.str();
mitk::StatusBar::GetInstance()->DisplayGreyValueText(statusText.c_str());
}
}
ok = true;
break;
}
}
default:
ok = true;
break;
}
return ok;
}
const DisplayPositionEvent *displPosEvent =
dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
if ( displPosEvent != NULL )
{
return true;
}
return false;
}
} // namespace
diff --git a/Core/Code/Controllers/mitkSliceNavigationController.h b/Core/Code/Controllers/mitkSliceNavigationController.h
index 1f70623b30..4a932958a9 100644
--- a/Core/Code/Controllers/mitkSliceNavigationController.h
+++ b/Core/Code/Controllers/mitkSliceNavigationController.h
@@ -1,510 +1,545 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef SLICENAVIGATIONCONTROLLER_H_HEADER_INCLUDED_C1C55A2F
#define SLICENAVIGATIONCONTROLLER_H_HEADER_INCLUDED_C1C55A2F
#include
#include "mitkBaseController.h"
#include "mitkRenderingManager.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkMessage.h"
#pragma GCC visibility push(default)
#include
#pragma GCC visibility pop
#include
#include
#include "mitkRestorePlanePositionOperation.h"
namespace mitk {
#define mitkTimeSlicedGeometryEventMacro( classname , super ) \
class MITK_CORE_EXPORT classname : public super { \
public: \
typedef classname Self; \
typedef super Superclass; \
classname(TimeSlicedGeometry* aTimeSlicedGeometry, unsigned int aPos) \
: Superclass(aTimeSlicedGeometry, aPos) {} \
virtual ~classname() {} \
virtual const char * GetEventName() const { return #classname; } \
virtual bool CheckEvent(const ::itk::EventObject* e) const \
{ return dynamic_cast(e); } \
virtual ::itk::EventObject* MakeObject() const \
{ return new Self(GetTimeSlicedGeometry(), GetPos()); } \
private: \
void operator=(const Self&); \
}
class PlaneGeometry;
class Geometry3D;
class BaseRenderer;
/**
* \brief Controls the selection of the slice the associated BaseRenderer
* will display
*
* A SliceNavigationController takes a Geometry3D as input world geometry
* (TODO what are the exact requirements?) and generates a TimeSlicedGeometry
* as output. The TimeSlicedGeometry holds a number of SlicedGeometry3Ds and
* these in turn hold a series of Geometry2Ds. One of these Geometry2Ds is
* selected as world geometry for the BaseRenderers associated to 2D views.
*
* The SliceNavigationController holds has Steppers (one for the slice, a
* second for the time step), which control the selection of a single
* Geometry2D from the TimeSlicedGeometry. SliceNavigationController generates
* ITK events to tell observers, like a BaseRenderer, when the selected slice
* or timestep changes.
*
* SliceNavigationControllers are registered as listeners to GlobalInteraction
* by the QmitkStdMultiWidget. In ExecuteAction, the controllers react to
* PositionEvents by setting the steppers to the slice which is nearest to the
* point of the PositionEvent.
*
* Example:
* \code
* // Initialization
* sliceCtrl = mitk::SliceNavigationController::New();
*
* // Tell the navigator the geometry to be sliced (with geometry a
* // Geometry3D::ConstPointer)
* sliceCtrl->SetInputWorldGeometry(geometry.GetPointer());
*
* // Tell the navigator in which direction it shall slice the data
- * sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Transversal);
+ * sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Axial);
*
* // Connect one or more BaseRenderer to this navigator, i.e.: events sent
* // by the navigator when stepping through the slices (e.g. by
* // sliceCtrl->GetSlice()->Next()) will be received by the BaseRenderer
* // (in this example only slice-changes, see also ConnectGeometryTimeEvent
* // and ConnectGeometryEvents.)
* sliceCtrl->ConnectGeometrySliceEvent(renderer.GetPointer());
*
* //create a world geometry and send the information to the connected renderer(s)
* sliceCtrl->Update();
* \endcode
*
*
* You can connect visible navigators to a SliceNavigationController, e.g., a
* QmitkSliderNavigator (for Qt):
*
* \code
* // Create the visible navigator (a slider with a spin-box)
* QmitkSliderNavigator* navigator =
* new QmitkSliderNavigator(parent, "slidernavigator");
*
* // Connect the navigator to the slice-stepper of the
* // SliceNavigationController. For initialization (position, mininal and
* // maximal values) the values of the SliceNavigationController are used.
* // Thus, accessing methods of a navigator is normally not necessary, since
* // everything can be set via the (Qt-independent) SliceNavigationController.
* // The QmitkStepperAdapter converts the Qt-signals to Qt-independent
* // itk-events.
* new QmitkStepperAdapter(navigator, sliceCtrl->GetSlice(), "navigatoradaptor");
* \endcode
*
* If you do not want that all renderwindows are updated when a new slice is
* selected, you can use a specific RenderingManager, which updates only those
* renderwindows that should be updated. This is sometimes useful when a 3D view
* does not need to be updated when the slices in some 2D views are changed.
* QmitkSliderNavigator (for Qt):
*
* \code
* // create a specific RenderingManager
* mitk::RenderingManager::Pointer myManager = mitk::RenderingManager::New();
*
* // tell the RenderingManager to update only renderwindow1 and renderwindow2
* myManager->AddRenderWindow(renderwindow1);
* myManager->AddRenderWindow(renderwindow2);
*
* // tell the SliceNavigationController of renderwindow1 and renderwindow2
* // to use the specific RenderingManager instead of the global one
* renderwindow1->GetSliceNavigationController()->SetRenderingManager(myManager);
* renderwindow2->GetSliceNavigationController()->SetRenderingManager(myManager);
* \endcode
*
* \todo implement for non-evenly-timed geometry!
* \ingroup NavigationControl
*/
class MITK_CORE_EXPORT SliceNavigationController : public BaseController
{
public:
mitkClassMacro(SliceNavigationController,BaseController);
itkNewMacro(Self);
mitkNewMacro1Param(Self, const char *);
/**
* \brief Possible view directions, \a Original will uses
* the Geometry2D instances in a SlicedGeometry3D provided
* as input world geometry (by SetInputWorldGeometry).
*/
- enum ViewDirection{Transversal, Sagittal, Frontal, Original};
+ enum ViewDirection
+ {
+#ifdef _MSC_VER
+ Transversal, // deprecated
+#endif
+ Axial = 0,
+ Sagittal,
+ Frontal,
+ Original
+ };
+
+#ifdef __GNUC__
+ __attribute__ ((deprecated)) static const ViewDirection Transversal = ViewDirection(Axial);
+#endif
/**
* \brief Set the input world geometry out of which the
* geometries for slicing will be created.
*/
void SetInputWorldGeometry(const mitk::Geometry3D* geometry);
itkGetConstObjectMacro(InputWorldGeometry, mitk::Geometry3D);
/**
* \brief Access the created geometry
*/
itkGetConstObjectMacro(CreatedWorldGeometry, mitk::Geometry3D);
/**
* \brief Set the desired view directions
*
* \sa ViewDirection
* \sa Update(ViewDirection viewDirection, bool top = true,
* bool frontside = true, bool rotated = false)
*/
itkSetEnumMacro(ViewDirection, ViewDirection);
itkGetEnumMacro(ViewDirection, ViewDirection);
/**
* \brief Set the default view direction
*
* This is used to re-initialize the view direction of the SNC to the
* default value with SetViewDirectionToDefault()
*
* \sa ViewDirection
* \sa Update(ViewDirection viewDirection, bool top = true,
* bool frontside = true, bool rotated = false)
*/
itkSetEnumMacro(DefaultViewDirection, ViewDirection);
itkGetEnumMacro(DefaultViewDirection, ViewDirection);
virtual void SetViewDirectionToDefault();
/**
* \brief Do the actual creation and send it to the connected
* observers (renderers)
*
*/
virtual void Update();
/**
* \brief Extended version of Update, additionally allowing to
* specify the direction/orientation of the created geometry.
*
*/
virtual void Update(ViewDirection viewDirection, bool top = true,
bool frontside = true, bool rotated = false);
/**
* \brief Send the created geometry to the connected
* observers (renderers)
*
* Called by Update().
*/
virtual void SendCreatedWorldGeometry();
/**
* \brief Tell observers to re-read the currently selected 2D geometry
*
* Called by mitk::SlicesRotator during rotation.
*/
virtual void SendCreatedWorldGeometryUpdate();
/**
* \brief Send the currently selected slice to the connected
* observers (renderers)
*
* Called by Update().
*/
virtual void SendSlice();
/**
* \brief Send the currently selected time to the connected
* observers (renderers)
*
* Called by Update().
*/
virtual void SendTime();
/**
* \brief Set the RenderingManager to be used
*
* If \a NULL, the default RenderingManager will be used.
*/
itkSetObjectMacro(RenderingManager, RenderingManager);
mitk::RenderingManager* GetRenderingManager() const;
#pragma GCC visibility push(default)
itkEventMacro( UpdateEvent, itk::AnyEvent );
#pragma GCC visibility pop
class MITK_CORE_EXPORT TimeSlicedGeometryEvent : public itk::AnyEvent
{
public:
typedef TimeSlicedGeometryEvent Self;
typedef itk::AnyEvent Superclass;
TimeSlicedGeometryEvent(
TimeSlicedGeometry* aTimeSlicedGeometry, unsigned int aPos)
: m_TimeSlicedGeometry(aTimeSlicedGeometry), m_Pos(aPos)
{}
virtual ~TimeSlicedGeometryEvent()
{}
virtual const char * GetEventName() const
{ return "TimeSlicedGeometryEvent"; }
virtual bool CheckEvent(const ::itk::EventObject* e) const
{ return dynamic_cast(e); }
virtual ::itk::EventObject* MakeObject() const
{ return new Self(m_TimeSlicedGeometry, m_Pos); }
TimeSlicedGeometry* GetTimeSlicedGeometry() const
{ return m_TimeSlicedGeometry; }
unsigned int GetPos() const
{ return m_Pos; }
private:
TimeSlicedGeometry::Pointer m_TimeSlicedGeometry;
unsigned int m_Pos;
// TimeSlicedGeometryEvent(const Self&);
void operator=(const Self&); //just hide
};
mitkTimeSlicedGeometryEventMacro(
GeometrySendEvent,TimeSlicedGeometryEvent );
mitkTimeSlicedGeometryEventMacro(
GeometryUpdateEvent, TimeSlicedGeometryEvent );
mitkTimeSlicedGeometryEventMacro(
GeometryTimeEvent, TimeSlicedGeometryEvent );
mitkTimeSlicedGeometryEventMacro(
GeometrySliceEvent, TimeSlicedGeometryEvent );
template
void ConnectGeometrySendEvent(T* receiver)
{
typedef typename itk::ReceptorMemberCommand::Pointer
ReceptorMemberCommandPointer;
ReceptorMemberCommandPointer eventReceptorCommand =
itk::ReceptorMemberCommand::New();
eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometry);
- AddObserver(GeometrySendEvent(NULL,0), eventReceptorCommand);
+ unsigned long tag = AddObserver(GeometrySendEvent(NULL,0), eventReceptorCommand);
+ m_ReceiverToObserverTagsMap[static_cast(receiver)].push_back(tag);
}
template
void ConnectGeometryUpdateEvent(T* receiver)
{
typedef typename itk::ReceptorMemberCommand::Pointer
ReceptorMemberCommandPointer;
ReceptorMemberCommandPointer eventReceptorCommand =
itk::ReceptorMemberCommand::New();
eventReceptorCommand->SetCallbackFunction(receiver, &T::UpdateGeometry);
- AddObserver(GeometryUpdateEvent(NULL,0), eventReceptorCommand);
+ unsigned long tag = AddObserver(GeometryUpdateEvent(NULL,0), eventReceptorCommand);
+ m_ReceiverToObserverTagsMap[static_cast(receiver)].push_back(tag);
}
template
void ConnectGeometrySliceEvent(T* receiver, bool connectSendEvent=true)
{
typedef typename itk::ReceptorMemberCommand::Pointer
ReceptorMemberCommandPointer;
ReceptorMemberCommandPointer eventReceptorCommand =
itk::ReceptorMemberCommand::New();
eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometrySlice);
- AddObserver(GeometrySliceEvent(NULL,0), eventReceptorCommand);
+ unsigned long tag = AddObserver(GeometrySliceEvent(NULL,0), eventReceptorCommand);
+ m_ReceiverToObserverTagsMap[static_cast(receiver)].push_back(tag);
if(connectSendEvent)
ConnectGeometrySendEvent(receiver);
}
template
void ConnectGeometryTimeEvent(T* receiver, bool connectSendEvent=true)
{
typedef typename itk::ReceptorMemberCommand::Pointer
ReceptorMemberCommandPointer;
ReceptorMemberCommandPointer eventReceptorCommand =
itk::ReceptorMemberCommand::New();
eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometryTime);
- AddObserver(GeometryTimeEvent(NULL,0), eventReceptorCommand);
+ unsigned long tag = AddObserver(GeometryTimeEvent(NULL,0), eventReceptorCommand);
+ m_ReceiverToObserverTagsMap[static_cast(receiver)].push_back(tag);
if(connectSendEvent)
ConnectGeometrySendEvent(receiver);
}
template
void ConnectGeometryEvents(T* receiver)
{
//connect sendEvent only once
ConnectGeometrySliceEvent(receiver, false);
ConnectGeometryTimeEvent(receiver);
}
+ // use a templated method to get the right offset when casting to void*
+ template
+ void Disconnect(T* receiver)
+ {
+ ObserverTagsMapType::iterator i = m_ReceiverToObserverTagsMap.find(static_cast(receiver));
+ if (i == m_ReceiverToObserverTagsMap.end()) return;
+ const std::list& tags = i->second;
+ for (std::list::const_iterator tagIter = tags.begin();
+ tagIter != tags.end(); ++tagIter)
+ {
+ RemoveObserver(*tagIter);
+ }
+ m_ReceiverToObserverTagsMap.erase(i);
+ }
+
Message<> crosshairPositionEvent;
/**
* \brief To connect multiple SliceNavigationController, we can
* act as an observer ourselves: implemented interface
* \warning not implemented
*/
virtual void SetGeometry(const itk::EventObject & geometrySliceEvent);
/**
* \brief To connect multiple SliceNavigationController, we can
* act as an observer ourselves: implemented interface
*/
virtual void SetGeometrySlice(const itk::EventObject & geometrySliceEvent);
/**
* \brief To connect multiple SliceNavigationController, we can
* act as an observer ourselves: implemented interface
*/
virtual void SetGeometryTime(const itk::EventObject & geometryTimeEvent);
/** \brief Positions the SNC according to the specified point */
void SelectSliceByPoint( const mitk::Point3D &point );
/** \brief Returns the TimeSlicedGeometry created by the SNC. */
const mitk::TimeSlicedGeometry *GetCreatedWorldGeometry();
/** \brief Returns the Geometry3D of the currently selected time step. */
const mitk::Geometry3D *GetCurrentGeometry3D();
/** \brief Returns the currently selected Plane in the current
* Geometry3D (if existent).
*/
const mitk::PlaneGeometry *GetCurrentPlaneGeometry();
/** \brief Sets the BaseRenderer associated with this SNC (if any). While
* the BaseRenderer is not directly used by SNC, this is a convenience
* method to enable BaseRenderer access via the SNC. */
void SetRenderer( BaseRenderer *renderer );
/** \brief Gets the BaseRenderer associated with this SNC (if any). While
* the BaseRenderer is not directly used by SNC, this is a convenience
* method to enable BaseRenderer access via the SNC. Returns NULL if no
* BaseRenderer has been specified*/
BaseRenderer *GetRenderer() const;
/** \brief Re-orients the slice stack to include the plane specified by
* the given point an normal vector.
*/
void ReorientSlices(
const mitk::Point3D &point, const mitk::Vector3D &normal );
virtual bool ExecuteAction(
Action* action, mitk::StateEvent const* stateEvent);
void ExecuteOperation(Operation* operation);
/**
* \brief Feature option to lock planes during mouse interaction.
* This option flag disables the mouse event which causes the center
* cross to move near by.
*/
itkSetMacro(SliceLocked, bool);
itkGetMacro(SliceLocked, bool);
itkBooleanMacro(SliceLocked);
/**
* \brief Feature option to lock slice rotation.
*
* This option flag disables separately the rotation of a slice which is
* implemented in mitkSliceRotator.
*/
itkSetMacro(SliceRotationLocked, bool);
itkGetMacro(SliceRotationLocked, bool);
itkBooleanMacro(SliceRotationLocked);
/**
* \brief Adjusts the numerical range of the slice stepper according to
* the current geometry orientation of this SNC's SlicedGeometry.
*/
void AdjustSliceStepperRange();
protected:
SliceNavigationController(const char * type = NULL);
virtual ~SliceNavigationController();
/*
template
static void buildstring( mitkIpPicDescriptor *pic, itk::Point p, std::string &s, T = 0)
{
std::string value;
std::stringstream stream;
stream.imbue(std::locale::classic());
stream<=0 && p[1] >=0 && p[2]>=0) && (unsigned int)p[0] < pic->n[0] && (unsigned int)p[1] < pic->n[1] && (unsigned int)p[2] < pic->n[2] )
{
if(pic->bpe!=24)
{
stream<<(((T*) pic->data)[ p[0] + p[1]*pic->n[0] + p[2]*pic->n[0]*pic->n[1] ]);
}
else
{
stream<<(((T*) pic->data)[p[0]*3 + 0 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 ]);
stream<<(((T*) pic->data)[p[0]*3 + 1 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 ]);
stream<<(((T*) pic->data)[p[0]*3 + 2 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 ]);
}
s = stream.str();
}
else
{
s+= "point out of data";
}
};
*/
mitk::Geometry3D::ConstPointer m_InputWorldGeometry;
mitk::Geometry3D::Pointer m_ExtendedInputWorldGeometry;
mitk::TimeSlicedGeometry::Pointer m_CreatedWorldGeometry;
ViewDirection m_ViewDirection;
ViewDirection m_DefaultViewDirection;
mitk::RenderingManager::Pointer m_RenderingManager;
mitk::BaseRenderer *m_Renderer;
itkSetMacro(Top, bool);
itkGetMacro(Top, bool);
itkBooleanMacro(Top);
itkSetMacro(FrontSide, bool);
itkGetMacro(FrontSide, bool);
itkBooleanMacro(FrontSide);
itkSetMacro(Rotated, bool);
itkGetMacro(Rotated, bool);
itkBooleanMacro(Rotated);
bool m_Top;
bool m_FrontSide;
bool m_Rotated;
bool m_BlockUpdate;
bool m_SliceLocked;
bool m_SliceRotationLocked;
unsigned int m_OldPos;
+
+ typedef std::map > ObserverTagsMapType;
+ ObserverTagsMapType m_ReceiverToObserverTagsMap;
};
} // namespace mitk
#endif /* SLICENAVIGATIONCONTROLLER_H_HEADER_INCLUDED_C1C55A2F */
diff --git a/Core/Code/DataManagement/mitkImageAccessByItk.h b/Core/Code/DataManagement/mitkImageAccessByItk.h
index 8fc5ae80ca..4dd691e82f 100644
--- a/Core/Code/DataManagement/mitkImageAccessByItk.h
+++ b/Core/Code/DataManagement/mitkImageAccessByItk.h
@@ -1,619 +1,620 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef MITKIMAGEACCESSBYITK_H_HEADER_INCLUDED
#define MITKIMAGEACCESSBYITK_H_HEADER_INCLUDED
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace mitk {
/**
* \brief Exception class thrown in #AccessByItk macros.
*
* This exception can be thrown by the invocation of the #AccessByItk macros,
* if the MITK image is of non-expected dimension or pixel type.
*
* \ingroup Adaptor
*/
class AccessByItkException : public virtual std::runtime_error
{
public:
AccessByItkException(const std::string& msg) : std::runtime_error(msg) {}
~AccessByItkException() throw() {}
};
}
#ifndef DOXYGEN_SKIP
#define _accessByItkPixelTypeException(pixelType, pixelTypeSeq) \
{ \
std::string msg("Pixel type "); \
msg.append(pixelType.GetItkTypeAsString()); \
msg.append(" is not in " MITK_PP_STRINGIZE(pixelTypeSeq)); \
throw mitk::AccessByItkException(msg); \
}
#define _accessByItkDimensionException(dim, validDims) \
{ \
std::stringstream msg; \
msg << "Dimension " << (dim) << " is not in " << validDims ; \
throw mitk::AccessByItkException(msg.str()); \
}
#define _checkSpecificDimensionIter(r, mitkImage, dim) \
if (mitkImage->GetDimension() == dim); else
#define _checkSpecificDimension(mitkImage, dimSeq) \
MITK_PP_SEQ_FOR_EACH(_checkSpecificDimensionIter, mitkImage, dimSeq) \
_accessByItkDimensionException(mitkImage->GetDimension(), MITK_PP_STRINGIZE(dimSeq))
#define _msvc_expand_bug(macro, arg) MITK_PP_EXPAND(macro arg)
//-------------------------------- 0-Arg Versions --------------------------------------
#define _accessByItk(itkImageTypeFunction, pixeltype, dimension) \
- if ( pixelType == typeid(pixeltype) && constImage->GetDimension() == dimension) \
- { \
- typedef itk::Image ImageType; \
+ if ( pixelType == mitk::MakePixelType< itk::Image >() && constImage->GetDimension() == dimension) \
+ {\
+ typedef itk::Image ImageType; \
typedef mitk::ImageToItk ImageToItkType; \
itk::SmartPointer imagetoitk = ImageToItkType::New(); \
imagetoitk->SetInput(constImage); \
imagetoitk->Update(); \
itkImageTypeFunction(imagetoitk->GetOutput()); \
} else
#define _accessByItkArgs(itkImageTypeFunction, type) \
(itkImageTypeFunction, MITK_PP_TUPLE_REM(2)type)
// product will be of the form (itkImageTypeFunction)(short)(2) for pixel type short and dimension 2
#ifdef _MSC_VER
#define _accessByItkProductIter(r, product) \
_msvc_expand_bug(_accessByItk, _msvc_expand_bug(_accessByItkArgs, (MITK_PP_SEQ_HEAD(product), MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)))))
#else
#define _accessByItkProductIter(r, product) \
MITK_PP_EXPAND(_accessByItk _accessByItkArgs(MITK_PP_SEQ_HEAD(product), MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product))))
#endif
#define _accessFixedTypeByItk(itkImageTypeFunction, pixelTypeSeq, dimSeq) \
MITK_PP_SEQ_FOR_EACH_PRODUCT(_accessByItkProductIter, ((itkImageTypeFunction))(pixelTypeSeq)(dimSeq))
//-------------------------------- n-Arg Versions --------------------------------------
#define _accessByItk_n(itkImageTypeFunction, pixeltype, dimension, args) \
- if ( pixelType == typeid(pixeltype) && constImage->GetDimension() == dimension) \
- { \
- typedef itk::Image ImageType; \
+ if ( pixelType == mitk::MakePixelType< itk::Image >() && constImage->GetDimension() == dimension) \
+ {\
+ typedef itk::Image ImageType; \
typedef mitk::ImageToItk ImageToItkType; \
itk::SmartPointer imagetoitk = ImageToItkType::New(); \
imagetoitk->SetInput(constImage); \
imagetoitk->Update(); \
itkImageTypeFunction(imagetoitk->GetOutput(), MITK_PP_TUPLE_REM(MITK_PP_SEQ_HEAD(args))MITK_PP_SEQ_TAIL(args)); \
} else
#define _accessByItkArgs_n(itkImageTypeFunction, type, args) \
(itkImageTypeFunction, MITK_PP_TUPLE_REM(2) type, args)
// product will be of the form ((itkImageTypeFunction)(3)(a,b,c))(short)(2)
// for the variable argument list a,b,c and for pixel type short and dimension 2
#ifdef _MSC_VER
#define _accessByItkProductIter_n(r, product) \
_msvc_expand_bug(_accessByItk_n, _msvc_expand_bug(_accessByItkArgs_n, (MITK_PP_SEQ_HEAD(MITK_PP_SEQ_HEAD(product)), MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)), MITK_PP_SEQ_TAIL(MITK_PP_SEQ_HEAD(product)))))
#else
#define _accessByItkProductIter_n(r, product) \
MITK_PP_EXPAND(_accessByItk_n _accessByItkArgs_n(MITK_PP_SEQ_HEAD(MITK_PP_SEQ_HEAD(product)), MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)), MITK_PP_SEQ_TAIL(MITK_PP_SEQ_HEAD(product))))
#endif
#define _accessFixedTypeByItk_n(itkImageTypeFunction, pixelTypeSeq, dimSeq, va_tuple) \
MITK_PP_SEQ_FOR_EACH_PRODUCT(_accessByItkProductIter_n, (((itkImageTypeFunction)(MITK_PP_ARG_COUNT va_tuple) va_tuple))(pixelTypeSeq)(dimSeq))
#endif //DOXYGEN_SKIP
/**
* \brief Access a MITK image by an ITK image
*
* Define a templated function or method (\a itkImageTypeFunction)
* within which the mitk-image (\a mitkImage) is accessed:
* \code
* template < typename TPixel, unsigned int VImageDimension >
* void ExampleFunction( itk::Image* itkImage );
* \endcode
*
* The itk::Image passed to the function/method has the same
* data-pointer as the mitk-image. So you have full read- and write-
* access to the data vector of the mitk-image using the itk-image.
* Call by:
* \code
* mitk::Image* inputMitkImage = ...
* try
* {
* AccessByItk(inputMitkImage, ExampleFunction);
* }
* catch (const mitk::AccessByItkException& e)
* {
* // mitk::Image is of wrong pixel type or dimension,
* // insert error handling here
* }
* \endcode
*
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* \note If your inputMitkImage is an mitk::Image::Pointer, use
* inputMitkImage.GetPointer()
* \note If you need to pass additional parameters to your
* access-function (\a itkImageTypeFunction), use #AccessByItk_n.
* \note If you know the dimension of your input mitk-image,
* it is better to use AccessFixedDimensionByItk (less code
* is generated).
* \sa AccessFixedDimensionByItk
* \sa AccessFixedTypeByItk
* \sa AccessFixedPixelTypeByItk
* \sa AccessByItk_n
*
* \ingroup Adaptor
*/
#define AccessByItk(mitkImage, itkImageTypeFunction) \
AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
/**
* \brief Access a mitk-image with known pixeltype (but unknown dimension) by an itk-image.
*
* For usage, see #AccessByItk.
*
* \param pixelTypeSeq A sequence of pixel types, like (short)(char)(int)
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* If the image has a different pixel type, a mitk::AccessByItkException exception is
* thrown. If you do not know the pixel type for sure, use #AccessByItk.
*
* \sa AccessByItk
* \sa AccessFixedDimensionByItk
* \sa AccessFixedTypeByItk
* \sa AccessFixedPixelTypeByItk_n
*
* \ingroup Adaptor
*/
#define AccessFixedPixelTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq) \
AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
/**
* \brief Access a mitk-image with an integral pixel type by an itk-image
*
* See #AccessByItk for details.
*
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* \sa AccessFixedPixelTypeByItk
* \sa AccessByItk
* \sa AccessIntegralPixelTypeByItk_n
*/
#define AccessIntegralPixelTypeByItk(mitkImage, itkImageTypeFunction) \
AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
/**
* \brief Access a mitk-image with a floating point pixel type by an ITK image
*
* See #AccessByItk for details.
*
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* \sa AccessFixedPixelTypeByItk
* \sa AccessByItk
* \sa AccessFloatingPixelTypeByItk_n
*/
#define AccessFloatingPixelTypeByItk(mitkImage, itkImageTypeFunction) \
AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
/**
* \brief Access a mitk-image with known dimension by an itk-image
*
* For usage, see #AccessByItk.
*
* \param dimension Dimension of the mitk-image. If the image has a different dimension,
* a mitk::AccessByItkException exception is thrown.
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* \note If you do not know the dimension for sure, use #AccessByItk.
*
* \sa AccessByItk
* \sa AccessFixedDimensionByItk_n
* \sa AccessFixedTypeByItk
* \sa AccessFixedPixelTypeByItk
*
* \ingroup Adaptor
*/
#define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension) \
AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension))
/**
* \brief Access a mitk-image with known type (pixel type and dimension) by an itk-image.
*
* The provided mitk-image must be in the set of types created by taking the
* cartesian product of the pixel type sequence and the dimension sequence.
* For example, a call to
* \code
* AccessFixedTypeByItk(myMitkImage, MyAccessFunction, (short)(int), (2)(3))
* \endcode
* asserts that the type of myMitkImage (pixeltype,dim) is in the set {(short,2),(short,3),(int,2),(int,3)}.
* For more information, see #AccessByItk.
*
* \param pixelTypeSeq A sequence of pixel types, like (short)(char)(int).
* \param dimension A sequence of dimensions, like (2)(3).
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* If the image has a different dimension or pixel type,
* a mitk::AccessByItkException exception is thrown.
*
* \note If you do not know the dimension for sure, use #AccessByItk.
*
* \sa AccessByItk
* \sa AccessFixedDimensionByItk
* \sa AccessFixedTypeByItk_n
* \sa AccessFixedPixelTypeByItk
*
* \ingroup Adaptor
*/
#define AccessFixedTypeByItk(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq) \
{ \
const mitk::PixelType& pixelType = mitkImage->GetPixelType(); \
const mitk::Image* constImage = mitkImage; \
const_cast(constImage)->Update(); \
_checkSpecificDimension(mitkImage, dimSeq); \
_accessFixedTypeByItk(itkImageTypeFunction, pixelTypeSeq, dimSeq) \
_accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
}
//------------------------------ n-Arg Access Macros -----------------------------------
/**
* \brief Access a MITK image by an ITK image with one or more parameters.
*
* Define a templated function or method (\a itkImageTypeFunction) with one ore more
* additional parameters, within which the mitk-image (\a mitkImage) is accessed:
* \code
* template < typename TPixel, unsigned int VImageDimension >
* void ExampleFunction( itk::Image* itkImage, SomeType param);
* \endcode
*
* The itk::Image passed to the function/method has the same
* data-pointer as the mitk-image. So you have full read- and write-
* access to the data vector of the mitk-image using the itk-image.
* Call by:
* \code
* SomeType param = ...
* mitk::Image* inputMitkImage = ...
* try
* {
* AccessByItk_n(inputMitkImage, ExampleFunction, (param));
* }
* catch (const mitk::AccessByItkException& e)
* {
* // mitk::Image is of wrong pixel type or dimension,
* // insert error handling here
* }
* \endcode
*
* \param va_tuple A variable length tuple containing the arguments to be passed
* to the access function itkImageTypeFunction, e.g. ("first", 2, THIRD).
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* \note If your inputMitkImage is an mitk::Image::Pointer, use
* inputMitkImage.GetPointer()
* \note If you know the dimension of your input mitk-image,
* it is better to use AccessFixedDimensionByItk_n (less code
* is generated).
* \sa AccessFixedDimensionByItk_n
* \sa AccessFixedTypeByItk_n
* \sa AccessFixedPixelTypeByItk_n
* \sa AccessByItk
*
* \ingroup Adaptor
*/
#define AccessByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
/**
* \brief Access a mitk-image with known pixeltype (but unknown dimension) by an itk-image
* with one or more parameters.
*
* For usage, see #AccessByItk_n.
*
* \param va_tuple A variable length tuple containing the arguments to be passed
* to the access function itkImageTypeFunction, e.g. ("first", 2, THIRD).
* \param pixelTypeSeq A sequence of pixel types, like (short)(char)(int).
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* If the image has a different pixel type, a mitk::AccessByItkException exception is
* thrown. If you do not know the pixel type for sure, use #AccessByItk_n.
*
* \sa AccessByItk_n
* \sa AccessFixedDimensionByItk_n
* \sa AccessFixedTypeByItk_n
* \sa AccessFixedPixelTypeByItk
*
* \ingroup Adaptor
*/
#define AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, va_tuple) \
AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
/**
* \brief Access an mitk::Image with an integral pixel type by an ITK image with
* one or more parameters.
*
* See #AccessByItk_n for details.
*
* \param va_tuple A variable length tuple containing the arguments to be passed
* to the access function itkImageTypeFunction, e.g. ("first", 2, THIRD).
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* \sa AccessFixedPixelTypeByItk_n
* \sa AccessByItk_n
* \sa AccessIntegralPixelTypeByItk
*/
#define AccessIntegralPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
/**
* \brief Access an mitk::Image with a floating point pixel type by an ITK image
* with one or more parameters.
*
* See #AccessByItk_n for details.
*
* \param va_tuple A variable length tuple containing the arguments to be passed
* to the access function itkImageTypeFunction, e.g. ("first", 2, THIRD).
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* \sa AccessFixedPixelTypeByItk_n
* \sa AccessByItk_n
* \sa AccessFloatingPixelTypeByItk
*/
#define AccessFloatingPixelTypeByItk_n(mitkImage, itkImageTypeFunction, va_tuple) \
AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ, va_tuple)
/**
* \brief Access a mitk-image with known dimension by an itk-image with
* one or more parameters.
*
* For usage, see #AccessByItk_n.
*
* \param dimension Dimension of the mitk-image. If the image has a different dimension,
* a mitk::AccessByItkException exception is thrown.
* \param va_tuple A variable length tuple containing the arguments to be passed
* to the access function itkImageTypeFunction, e.g. ("first", 2, THIRD).
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* \note If you do not know the dimension for sure, use #AccessByItk_n.
*
* \sa AccessByItk_n
* \sa AccessFixedDimensionByItk
* \sa AccessFixedTypeByItk_n
* \sa AccessFixedPixelTypeByItk_n
*
* \ingroup Adaptor
*/
#define AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple) \
AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dimension), va_tuple)
/**
* \brief Access a mitk-image with known type (pixel type and dimension) by an itk-image
* with one or more parameters.
*
* For usage, see AccessFixedTypeByItk.
*
* \param pixelTypeSeq A sequence of pixel types, like (short)(char)(int).
* \param dimension A sequence of dimensions, like (2)(3).
* \param va_tuple A variable length tuple containing the arguments to be passed
* to the access function itkImageTypeFunction, e.g. ("first", 2, THIRD).
* \param mitkImage The MITK input image.
* \param itkImageTypeFunction The templated access-function to be called.
*
* \throws mitk::AccessByItkException If mitkImage is of unsupported pixel type or dimension.
*
* If the image has a different dimension or pixel type,
* a mitk::AccessByItkException exception is thrown.
*
* \note If you do not know the dimension for sure, use #AccessByItk_n.
*
* \sa AccessByItk_n
* \sa AccessFixedDimensionByItk_n
* \sa AccessFixedTypeByItk
* \sa AccessFixedPixelTypeByItk_n
*
* \ingroup Adaptor
*/
#define AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, va_tuple) \
{ \
const mitk::PixelType& pixelType = mitkImage->GetPixelType(); \
const mitk::Image* constImage = mitkImage; \
const_cast(constImage)->Update(); \
_checkSpecificDimension(mitkImage, dimSeq); \
_accessFixedTypeByItk_n(itkImageTypeFunction, pixelTypeSeq, dimSeq, va_tuple) \
_accessByItkPixelTypeException(mitkImage->GetPixelType(), pixelTypeSeq) \
}
//------------------------- For back-wards compatibility -------------------------------
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1) AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1))
#define AccessFixedPixelTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1) AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1))
#define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1) AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1))
#define AccessFixedTypeByItk_1(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1) AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1))
#define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2) AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1,arg2))
#define AccessFixedPixelTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2) AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1,arg2))
#define AccessFixedDimensionByItk_2(mitkImage, itkImageTypeFunction, dimension, arg1, arg2) AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1,arg2))
#define AccessFixedTypeByItk_2(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2) AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1,arg2))
#define AccessByItk_3(mitkImage, itkImageTypeFunction, arg1, arg2, arg3) AccessByItk_n(mitkImage, itkImageTypeFunction, (arg1,arg2,arg3))
#define AccessFixedPixelTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, arg1, arg2, arg3) AccessFixedPixelTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, (arg1,arg2,arg3))
#define AccessFixedDimensionByItk_3(mitkImage, itkImageTypeFunction, dimension, arg1, arg2, arg3) AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, (arg1,arg2,arg3))
#define AccessFixedTypeByItk_3(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, arg1, arg2, arg3) AccessFixedTypeByItk_n(mitkImage, itkImageTypeFunction, pixelTypeSeq, dimSeq, (arg1,arg2,arg3))
//----------------------------- Access two MITK Images ---------------------------------
#ifndef DOXYGEN_SKIP
#define _accessTwoImagesByItk(itkImageTypeFunction, pixeltype1, dim1, pixeltype2, dim2) \
- if (pixelType1 == typeid(pixeltype1) && pixelType2 == typeid(pixeltype2) && \
+ if (pixelType1 == mitk::MakePixelType< itk::Image >() && \
+ pixelType2 == mitk::MakePixelType< itk::Image >() && \
constImage1->GetDimension() == dim1 && constImage2->GetDimension() == dim2) \
{ \
typedef itk::Image ImageType1; \
typedef itk::Image ImageType2; \
typedef mitk::ImageToItk ImageToItkType1; \
typedef mitk::ImageToItk ImageToItkType2; \
itk::SmartPointer imagetoitk1 = ImageToItkType1::New(); \
imagetoitk1->SetInput(constImage1); \
imagetoitk1->Update(); \
itk::SmartPointer imagetoitk2 = ImageToItkType2::New(); \
imagetoitk2->SetInput(constImage2); \
imagetoitk2->Update(); \
itkImageTypeFunction(imagetoitk1->GetOutput(), imagetoitk2->GetOutput()); \
} else
#define _accessTwoImagesByItkArgs2(itkImageTypeFunction, type1, type2) \
(itkImageTypeFunction, MITK_PP_TUPLE_REM(2) type1, MITK_PP_TUPLE_REM(2) type2)
#define _accessTwoImagesByItkArgs(product) \
MITK_PP_EXPAND(_accessTwoImagesByItkArgs2 MITK_PP_EXPAND((MITK_PP_SEQ_HEAD(product), MITK_PP_TUPLE_REM(2) MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)))))
// product is of the form (itkImageTypeFunction)((short,2))((char,2))
#ifdef _MSC_VER
#define _accessTwoImagesByItkIter(r, product) \
MITK_PP_EXPAND(_accessTwoImagesByItk _msvc_expand_bug(_accessTwoImagesByItkArgs2, (MITK_PP_SEQ_HEAD(product), _msvc_expand_bug(MITK_PP_TUPLE_REM(2), MITK_PP_EXPAND(MITK_PP_SEQ_TO_TUPLE (MITK_PP_SEQ_TAIL(product)))))))
#else
#define _accessTwoImagesByItkIter(r, product) \
MITK_PP_EXPAND(_accessTwoImagesByItk _accessTwoImagesByItkArgs(product))
#endif
#define _accessTwoImagesByItkForEach(itkImageTypeFunction, tseq1, tseq2) \
MITK_PP_SEQ_FOR_EACH_PRODUCT(_accessTwoImagesByItkIter, ((itkImageTypeFunction))(tseq1)(tseq2))
#endif // DOXYGEN_SKIP
/**
* \brief Access two mitk-images with known dimension by itk-images
*
* Define a templated function or method (\a itkImageTypeFunction)
* within which the mitk-images (\a mitkImage1 and \a mitkImage2) are accessed:
* \code
* template
* void ExampleFunctionTwoImages(itk::Image