Page MenuHomePhabricator

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/Core/Code/Algorithms/itkImportMitkImageContainer.h b/Core/Code/Algorithms/itkImportMitkImageContainer.h
index c9c10ec3f0..5e9848b9bb 100644
--- a/Core/Code/Algorithms/itkImportMitkImageContainer.h
+++ b/Core/Code/Algorithms/itkImportMitkImageContainer.h
@@ -1,99 +1,98 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 13129 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __itkImportMitkImageContainer_h
#define __itkImportMitkImageContainer_h
#include <itkImportImageContainer.h>
#include <mitkImageDataItem.h>
namespace itk
{
/** \class ImportMitkImageContainer
* Defines an itk::Image front-end to an mitk::Image. This container
* conforms to the ImageContainerInterface. This is a full-fleged Object,
* so there is modification time, debug, and reference count information.
*
* Template parameters for ImportMitkImageContainer:
*
* TElementIdentifier =
* An INTEGRAL type for use in indexing the imported buffer.
*
* TElement =
* The element type stored in the container.
*/
template <typename TElementIdentifier, typename TElement>
class ImportMitkImageContainer: public ImportImageContainer<TElementIdentifier, TElement>
{
public:
/** Standard class typedefs. */
typedef ImportMitkImageContainer Self;
typedef Object Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Save the template parameters. */
typedef TElementIdentifier ElementIdentifier;
typedef TElement Element;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Standard part of every itk Object. */
itkTypeMacro(ImportMitkImageContainer, ImportImageContainer);
///** Get the pointer from which the image data is imported. */
//TElement *GetImportPointer() {return m_ImportPointer;};
/** \brief Set the mitk::ImageDataItem to be imported */
void SetImageDataItem(mitk::ImageDataItem* imageDataItem);
protected:
ImportMitkImageContainer();
virtual ~ImportMitkImageContainer();
/** PrintSelf routine. Normally this is a protected internal method. It is
* made public here so that Image can call this method. Users should not
* call this method but should call Print() instead. */
void PrintSelf(std::ostream& os, Indent indent) const;
private:
ImportMitkImageContainer(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
mitk::ImageDataItem::Pointer m_ImageDataItem;
};
} // end namespace itk
// Define instantiation macro for this template.
#define ITK_TEMPLATE_ImportMitkImageContainer(_, EXPORT, x, y) namespace itk { \
_(2(class EXPORT ImportMitkImageContainer< ITK_TEMPLATE_2 x >)) \
namespace Templates { typedef ImportMitkImageContainer< ITK_TEMPLATE_2 x > ImportMitkImageContainer##y; } \
}
//#if ITK_TEMPLATE_EXPLICIT
//# include "Templates/itkImportMitkImageContainer+-.h"
//#endif
#if ITK_TEMPLATE_TXX
# include "itkImportMitkImageContainer.txx"
#endif
#endif
diff --git a/Core/Code/Algorithms/itkImportMitkImageContainer.txx b/Core/Code/Algorithms/itkImportMitkImageContainer.txx
index d6c7acb16c..07b2a33bd0 100644
--- a/Core/Code/Algorithms/itkImportMitkImageContainer.txx
+++ b/Core/Code/Algorithms/itkImportMitkImageContainer.txx
@@ -1,65 +1,64 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 13129 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _itkImportMitkImageContainer_txx
#define _itkImportMitkImageContainer_txx
#include "itkImportMitkImageContainer.h"
namespace itk
{
template <typename TElementIdentifier, typename TElement>
ImportMitkImageContainer<TElementIdentifier , TElement>
::ImportMitkImageContainer()
{
}
template <typename TElementIdentifier, typename TElement>
ImportMitkImageContainer< TElementIdentifier , TElement >
::~ImportMitkImageContainer()
{
m_ImageDataItem = NULL;
}
template <typename TElementIdentifier, typename TElement>
void
ImportMitkImageContainer< TElementIdentifier , TElement >
::SetImageDataItem(mitk::ImageDataItem* imageDataItem)
{
m_ImageDataItem = imageDataItem;
this->SetImportPointer( (TElement*) m_ImageDataItem->GetData(), m_ImageDataItem->GetSize()/sizeof(Element), false);
this->Modified();
}
template <typename TElementIdentifier, typename TElement>
void
ImportMitkImageContainer< TElementIdentifier , TElement >
::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os,indent);
os << indent << "ImageDataItem: " << m_ImageDataItem << std::endl;
}
} // end namespace itk
#endif
diff --git a/Core/Code/Algorithms/itkLocalVariationImageFilter.h b/Core/Code/Algorithms/itkLocalVariationImageFilter.h
index fd2b4521aa..447d37578e 100644
--- a/Core/Code/Algorithms/itkLocalVariationImageFilter.h
+++ b/Core/Code/Algorithms/itkLocalVariationImageFilter.h
@@ -1,120 +1,119 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
-Version: $Revision: 18127 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __itkLocalVariationImageFilter_h
#define __itkLocalVariationImageFilter_h
#include "itkImageToImageFilter.h"
#include "itkImage.h"
namespace itk
{
template<class TPixelType>
class SquaredEuclideanMetric
{
public:
static double Calc(TPixelType p);
};
/** \class LocalVariationImageFilter
* \brief Calculates the local variation in each pixel
*
* Reference: Tony F. Chan et al., The digital TV filter and nonlinear denoising
*
* \sa Image
* \sa Neighborhood
* \sa NeighborhoodOperator
* \sa NeighborhoodIterator
*
* \ingroup IntensityImageFilters
*/
template <class TInputImage, class TOutputImage>
class LocalVariationImageFilter :
public ImageToImageFilter< TInputImage, TOutputImage >
{
public:
/** Extract dimension from input and output image. */
itkStaticConstMacro(InputImageDimension, unsigned int,
TInputImage::ImageDimension);
itkStaticConstMacro(OutputImageDimension, unsigned int,
TOutputImage::ImageDimension);
/** Convenient typedefs for simplifying declarations. */
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
/** Standard class typedefs. */
typedef LocalVariationImageFilter Self;
typedef ImageToImageFilter< InputImageType, OutputImageType> Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(LocalVariationImageFilter, ImageToImageFilter);
/** Image typedef support. */
typedef typename InputImageType::PixelType InputPixelType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
typedef typename InputImageType::SizeType InputSizeType;
/** MedianImageFilter needs a larger input requested region than
* the output requested region. As such, MedianImageFilter needs
* to provide an implementation for GenerateInputRequestedRegion()
* in order to inform the pipeline execution model.
*
* \sa ImageToImageFilter::GenerateInputRequestedRegion() */
virtual void GenerateInputRequestedRegion()
throw(InvalidRequestedRegionError);
protected:
LocalVariationImageFilter();
virtual ~LocalVariationImageFilter() {}
void PrintSelf(std::ostream& os, Indent indent) const;
/** MedianImageFilter can be implemented as a multithreaded filter.
* Therefore, this implementation provides a ThreadedGenerateData()
* routine which is called for each processing thread. The output
* image data is allocated automatically by the superclass prior to
* calling ThreadedGenerateData(). ThreadedGenerateData can only
* write to the portion of the output image specified by the
* parameter "outputRegionForThread"
*
* \sa ImageToImageFilter::ThreadedGenerateData(),
* ImageToImageFilter::GenerateData() */
void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
int threadId );
private:
LocalVariationImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkLocalVariationImageFilter.txx"
#endif
#endif //LocalVariationImageFilter
diff --git a/Core/Code/Algorithms/itkMITKScalarImageToHistogramGenerator.h b/Core/Code/Algorithms/itkMITKScalarImageToHistogramGenerator.h
index 6767ab25f9..f5024f8137 100644
--- a/Core/Code/Algorithms/itkMITKScalarImageToHistogramGenerator.h
+++ b/Core/Code/Algorithms/itkMITKScalarImageToHistogramGenerator.h
@@ -1,107 +1,106 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __itkMITKScalarImageToHistogramGenerator_h
#define __itkMITKScalarImageToHistogramGenerator_h
#include "itkScalarImageToListAdaptor.h"
#include "itkListSampleToHistogramGenerator.h"
#include "itkObject.h"
namespace itk {
namespace Statistics {
template< class TImageType, class TMeasurementType =
ITK_TYPENAME TImageType::PixelType>
class MITKScalarImageToHistogramGenerator : public Object
{
public:
/** Standard typedefs */
typedef MITKScalarImageToHistogramGenerator Self;
typedef Object Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(MITKScalarImageToHistogramGenerator, Object);
/** standard New() method support */
itkNewMacro(Self);
typedef TImageType ImageType;
typedef itk::Statistics::ScalarImageToListAdaptor<
ImageType
> AdaptorType;
typedef typename AdaptorType::Pointer AdaptorPointer;
typedef typename ImageType::PixelType PixelType;
typedef itk::Statistics::ListSampleToHistogramGenerator<
AdaptorType,
TMeasurementType
> GeneratorType;
typedef typename GeneratorType::Pointer GeneratorPointer;
typedef typename GeneratorType::HistogramType HistogramType;
typedef typename HistogramType::Pointer HistogramPointer;
typedef typename HistogramType::ConstPointer HistogramConstPointer;
public:
/** Triggers the Computation of the histogram */
void Compute( void );
/** Connects the input image for which the histogram is going to be computed */
void SetInput( const ImageType * );
/** Return the histogram. o
\warning This output is only valid after the Compute() method has been invoked
\sa Compute */
const HistogramType * GetOutput() const;
/** Set number of histogram bins */
void SetNumberOfBins( unsigned int numberOfBins );
/** Set marginal scale value to be passed to the histogram generator */
void SetMarginalScale( double marginalScale );
protected:
MITKScalarImageToHistogramGenerator();
virtual ~MITKScalarImageToHistogramGenerator() {};
void PrintSelf(std::ostream& os, Indent indent) const;
private:
AdaptorPointer m_ImageToListAdaptor;
GeneratorPointer m_HistogramGenerator;
};
} // end of namespace Statistics
} // end of namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkMITKScalarImageToHistogramGenerator.txx"
#endif
#endif
diff --git a/Core/Code/Algorithms/itkTotalVariationDenoisingImageFilter.h b/Core/Code/Algorithms/itkTotalVariationDenoisingImageFilter.h
index f35d97c303..391c8d72a1 100644
--- a/Core/Code/Algorithms/itkTotalVariationDenoisingImageFilter.h
+++ b/Core/Code/Algorithms/itkTotalVariationDenoisingImageFilter.h
@@ -1,109 +1,108 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
-Version: $Revision: 18127 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __itkTotalVariationDenoisingImageFilter_h
#define __itkTotalVariationDenoisingImageFilter_h
#include "itkTotalVariationSingleIterationImageFilter.h"
#include "itkImageToImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkImage.h"
namespace itk
{
/** \class TotalVariationDenoisingImageFilter
* \brief Applies a total variation denoising filter to an image
*
* Reference: Tony F. Chan et al., The digital TV filter and nonlinear denoising
*
* \sa Image
* \sa Neighborhood
* \sa NeighborhoodOperator
* \sa NeighborhoodIterator
*
* \ingroup IntensityImageFilters
*/
template <class TInputImage, class TOutputImage>
class TotalVariationDenoisingImageFilter :
public ImageToImageFilter< TInputImage, TOutputImage >
{
public:
/** Extract dimension from input and output image. */
itkStaticConstMacro(InputImageDimension, unsigned int,
TInputImage::ImageDimension);
itkStaticConstMacro(OutputImageDimension, unsigned int,
TOutputImage::ImageDimension);
/** Convenient typedefs for simplifying declarations. */
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
/** Standard class typedefs. */
typedef TotalVariationDenoisingImageFilter Self;
typedef ImageToImageFilter< InputImageType, OutputImageType> Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(TotalVariationDenoisingImageFilter, ImageToImageFilter);
/** Image typedef support. */
typedef typename InputImageType::PixelType InputPixelType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
typedef typename InputImageType::SizeType InputSizeType;
typedef TotalVariationSingleIterationImageFilter<TOutputImage, TOutputImage>
SingleIterationFilterType;
typedef typename itk::CastImageFilter< TInputImage, TOutputImage > CastType;
itkSetMacro(Lambda, double);
itkGetMacro(Lambda, double);
itkSetMacro(NumberIterations, int);
itkGetMacro(NumberIterations, int);
protected:
TotalVariationDenoisingImageFilter();
virtual ~TotalVariationDenoisingImageFilter() {}
void PrintSelf(std::ostream& os, Indent indent) const;
void GenerateData();
double m_Lambda;
int m_NumberIterations;
private:
TotalVariationDenoisingImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkTotalVariationDenoisingImageFilter.txx"
#endif
#endif //__itkTotalVariationDenoisingImageFilter__
diff --git a/Core/Code/Algorithms/itkTotalVariationSingleIterationImageFilter.h b/Core/Code/Algorithms/itkTotalVariationSingleIterationImageFilter.h
index 496319fbdf..9decad13cf 100644
--- a/Core/Code/Algorithms/itkTotalVariationSingleIterationImageFilter.h
+++ b/Core/Code/Algorithms/itkTotalVariationSingleIterationImageFilter.h
@@ -1,133 +1,132 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
-Version: $Revision: 18127 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __itkTotalVariationSingleIterationImageFilter_h
#define __itkTotalVariationSingleIterationImageFilter_h
#include "itkImageToImageFilter.h"
#include "itkImage.h"
namespace itk
{
/** \class TotalVariationSingleIterationImageFilter
* \brief Applies a total variation denoising filter to an image
*
* Reference: Tony F. Chan et al., The digital TV filter and nonlinear denoising
*
* \sa Image
* \sa Neighborhood
* \sa NeighborhoodOperator
* \sa NeighborhoodIterator
*
* \ingroup IntensityImageFilters
*/
template <class TInputImage, class TOutputImage>
class TotalVariationSingleIterationImageFilter :
public ImageToImageFilter< TInputImage, TOutputImage >
{
public:
/** Extract dimension from input and output image. */
itkStaticConstMacro(InputImageDimension, unsigned int,
TInputImage::ImageDimension);
itkStaticConstMacro(OutputImageDimension, unsigned int,
TOutputImage::ImageDimension);
/** Convenient typedefs for simplifying declarations. */
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
typedef itk::Image<float,InputImageDimension> LocalVariationImageType;
/** Standard class typedefs. */
typedef TotalVariationSingleIterationImageFilter Self;
typedef ImageToImageFilter< InputImageType, OutputImageType> Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(TotalVariationSingleIterationImageFilter, ImageToImageFilter);
/** Image typedef support. */
typedef typename InputImageType::PixelType InputPixelType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
typedef typename InputImageType::SizeType InputSizeType;
/** A larger input requested region than
* the output requested region is required.
* Therefore, an implementation for GenerateInputRequestedRegion()
* is provided.
*
* \sa ImageToImageFilter::GenerateInputRequestedRegion() */
virtual void GenerateInputRequestedRegion()
throw(InvalidRequestedRegionError);
itkSetMacro(Lambda, double);
itkGetMacro(Lambda, double);
void SetOriginalImage(InputImageType* in)
{ this->m_OriginalImage = in; }
typename InputImageType::Pointer GetOriginialImage()
{ return this->m_OriginalImage; }
protected:
TotalVariationSingleIterationImageFilter();
virtual ~TotalVariationSingleIterationImageFilter() {}
void PrintSelf(std::ostream& os, Indent indent) const;
/** MedianImageFilter can be implemented as a multithreaded filter.
* Therefore, this implementation provides a ThreadedGenerateData()
* routine which is called for each processing thread. The output
* image data is allocated automatically by the superclass prior to
* calling ThreadedGenerateData(). ThreadedGenerateData can only
* write to the portion of the output image specified by the
* parameter "outputRegionForThread"
*
* \sa ImageToImageFilter::ThreadedGenerateData(),
* ImageToImageFilter::GenerateData() */
void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
int threadId );
void BeforeThreadedGenerateData();
typename LocalVariationImageType::Pointer m_LocalVariation;
typename InputImageType::Pointer m_OriginalImage;
double m_Lambda;
private:
TotalVariationSingleIterationImageFilter(const Self&);
void operator=(const Self&);
};
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkTotalVariationSingleIterationImageFilter.txx"
#endif
#endif //__itkTotalVariationSingleIterationImageFilter__
diff --git a/Core/Code/Algorithms/mitkBaseDataSource.cpp b/Core/Code/Algorithms/mitkBaseDataSource.cpp
index 6e7a4ab5ee..6c334f85ca 100644
--- a/Core/Code/Algorithms/mitkBaseDataSource.cpp
+++ b/Core/Code/Algorithms/mitkBaseDataSource.cpp
@@ -1,69 +1,68 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkBaseDataSource.h"
mitk::BaseDataSource::BaseDataSource()
{
// Pure virtual functions may not be called in the constructor...
// see ( see Bjarne Stroustrup's C++ PL 3rd ed section 15.4.3 )
//OutputType::Pointer output = static_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
//Superclass::SetNumberOfRequiredOutputs( 1 );
//Superclass::SetNthOutput( 0, output.GetPointer() );
}
mitk::BaseDataSource::~BaseDataSource()
{
}
void mitk::BaseDataSource::SetOutput( OutputType* output )
{
this->SetNthOutput( 0, output );
}
void mitk::BaseDataSource::SetOutput( unsigned int idx, OutputType* output )
{
this->SetNthOutput(idx, output);
}
mitk::BaseDataSource::OutputType* mitk::BaseDataSource::GetOutput()
{
if ( this->GetNumberOfOutputs() < 1 )
{
return 0;
}
return static_cast<OutputType*> ( Superclass::GetOutput( 0 ) );
}
mitk::BaseDataSource::OutputType* mitk::BaseDataSource::GetOutput ( unsigned int idx )
{
return static_cast<OutputType*> ( Superclass::GetOutput( idx ) );
}
diff --git a/Core/Code/Algorithms/mitkBaseDataSource.h b/Core/Code/Algorithms/mitkBaseDataSource.h
index 63dfeb9c03..57d71a0c5a 100644
--- a/Core/Code/Algorithms/mitkBaseDataSource.h
+++ b/Core/Code/Algorithms/mitkBaseDataSource.h
@@ -1,95 +1,94 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_BASE_DATA_SOURCE_H
#define _MITK_BASE_DATA_SOURCE_H
#include "mitkBaseProcess.h"
#include "mitkBaseData.h"
namespace mitk
{
/**
* @brief Superclass of all classes generating base data (instances of class
* mitk::BaseData) as output.
*
* In itk and vtk the generated result of a ProcessObject is only guaranteed
* to be up-to-date, when Update() of the ProcessObject or the generated
* DataObject is called immediately before access of the data stored in the
* DataObject. This is also true for subclasses of mitk::BaseProcess and thus
* for mitk::BaseDataSource.
* @ingroup Process
*/
class MITK_CORE_EXPORT BaseDataSource : public BaseProcess
{
public:
mitkClassMacro( BaseDataSource, BaseProcess );
typedef mitk::BaseData OutputType;
typedef OutputType::Pointer OutputTypePointer;
/**
* Allocates a new output object and returns it. This function
* is pure virtual because mitk::BaseData contains pure virtual functions
* and can not directly be instantiated. This must be done by subclasses, which
* know which subclasses of mitk::BaseData they want to instantiate. Thus, these
* classes have to set their output themselves via this->SetOutput(MakeOutput(0))
* in the constructor!
* @param idx the index of the output for which an object should be created
* @returns the new object
*/
virtual itk::DataObject::Pointer MakeOutput ( unsigned int idx ) = 0;
/**
* Allows to set the output of the base data source.
* @param output the intended output of the base data source
*/
virtual void SetOutput( OutputType* output );
/**
* Allows to set the n-th output of the base data source.
* @param idx The index of the output
* @param output The intended output of the base data source
*/
virtual void SetOutput( unsigned int idx, OutputType* output );
/**
* Returns the output with index 0 of the base data source
* @returns the output
*/
virtual OutputType* GetOutput();
/**
* Returns the n'th output of the base data source
* @param idx the index of the wanted output
* @returns the output with index idx.
*/
virtual OutputType* GetOutput ( unsigned int idx );
protected:
BaseDataSource();
virtual ~BaseDataSource();
};
}
#endif // #define _MITK_BASE_DATA_SOURCE_H
diff --git a/Core/Code/Algorithms/mitkBaseProcess.cpp b/Core/Code/Algorithms/mitkBaseProcess.cpp
index e8737b6324..91b6aeb2fc 100644
--- a/Core/Code/Algorithms/mitkBaseProcess.cpp
+++ b/Core/Code/Algorithms/mitkBaseProcess.cpp
@@ -1,151 +1,150 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkBaseProcess.h"
#include "mitkBaseData.h"
#define MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
mitk::BaseProcess::BaseProcess() : m_Unregistering(false), m_CalculatingExternalReferenceCount(false), m_ExternalReferenceCount(-1)
{
}
mitk::BaseProcess::~BaseProcess()
{
}
int mitk::BaseProcess::GetExternalReferenceCount() const
{
if(m_CalculatingExternalReferenceCount==false) //this is only needed because a smart-pointer to m_Outputs (private!!) must be created by calling GetOutputs.
{
m_CalculatingExternalReferenceCount = true;
m_ExternalReferenceCount = -1;
DataObjectPointerArray& outputs = const_cast<mitk::BaseProcess*>(this)->GetOutputs();
int realReferenceCount = GetReferenceCount();
unsigned int idx;
for (idx = 0; idx < outputs.size(); ++idx)
{
//references of outputs that are not referenced from someone else (reference additional to the reference from this BaseProcess object) are interpreted as non-existent
if((outputs[idx]) && (outputs[idx]->GetReferenceCount()==1))
--realReferenceCount;
}
m_ExternalReferenceCount = realReferenceCount;
if(m_ExternalReferenceCount<0)
m_ExternalReferenceCount=0;
}
else
return -1;
m_CalculatingExternalReferenceCount = false; //do not move in if-part!!!
return m_ExternalReferenceCount;
}
void mitk::BaseProcess::UnRegister() const
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
if((m_Unregistering==false) && (m_CalculatingExternalReferenceCount==false))
{
m_Unregistering=true;
int realReferenceCount = GetExternalReferenceCount()-1; //-1 because someone is trying to unregister us
if(realReferenceCount<0)
m_ExternalReferenceCount=realReferenceCount=0;
if(realReferenceCount==0)
{
DataObjectPointerArray& outputs = const_cast<mitk::BaseProcess*>(this)->GetOutputs();
//disconnect all outputs from us
//size of outputs will not change until the very last output
//is removed, because we remove from front to back
unsigned int idx;
for (idx = 0; idx < outputs.size(); ++idx)
{
const_cast<mitk::BaseProcess*>(this)->RemoveOutput(outputs[idx]);
}
//now the referenceCount should be one!
int testReferenceCount=GetReferenceCount();
if(testReferenceCount!=1)
{
itkWarningMacro(<<"Reference count of process object unexpectedly "
<< "not 1 before final unregister but " << testReferenceCount);
}
}
m_Unregistering=false;
}
else
{
if(GetReferenceCount()==1)
{
//the calling UnRegister will do the last cleanup
return;
}
}
#endif
Superclass::UnRegister();
}
/**
* Set an output of this filter. This method specifically
* does not do a Register()/UnRegister() because of the
* desire to break the reference counting loop.
*/
void mitk::BaseProcess::SetNthOutput(unsigned int idx, itk::DataObject *output)
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
output = dynamic_cast<mitk::BaseData*>(output);
// does this change anything?
if ( idx < GetOutputs().size() && output == GetOutputs()[idx])
{
return;
}
if (output)
{
dynamic_cast<mitk::BaseData*>(output)->ConnectSource(this, idx);
}
#endif
this->Register();
Superclass::SetNthOutput(idx, output);
this->UnRegister();
}
/**
* Adds an output to the first null position in the output list.
* Expands the list memory if necessary
*/
void mitk::BaseProcess::AddOutput(itk::DataObject *output)
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
unsigned int idx=0;
output = dynamic_cast<mitk::BaseData*>(output);
if (output)
{
dynamic_cast<mitk::BaseData*>(output)->ConnectSource(this, idx);
}
#endif
Superclass::AddOutput(output);
}
diff --git a/Core/Code/Algorithms/mitkBaseProcess.h b/Core/Code/Algorithms/mitkBaseProcess.h
index b3586b5132..6e2738955a 100644
--- a/Core/Code/Algorithms/mitkBaseProcess.h
+++ b/Core/Code/Algorithms/mitkBaseProcess.h
@@ -1,111 +1,110 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 BASEPROCESS_H_HEADER_INCLUDED_C19BE6FC
#define BASEPROCESS_H_HEADER_INCLUDED_C19BE6FC
#if(_MSC_VER==1200)
#include <itkFixedArray.h>
#endif
#include <MitkExports.h>
#include <mitkCommon.h>
#include <itkProcessObject.h>
namespace mitk {
class BaseData;
//##Documentation
//## @brief Superclass of all classes generating some kind of mitk::BaseData.
//##
//## Superclass of all classes generating some kind of mitk::BaseData.
//## In itk and vtk the generated result of a ProcessObject is only guaranteed
//## to be up-to-date, when Update() of the ProcessObject or the generated
//## DataObject is called immediately before access of the data stored in the
//## DataObject. This is also true for subclasses of mitk::BaseProcess. But
//## many of the subclasses of mitk::BaseProcess define additional access
//## functions to the generated output that guarantee an up-to-date result, see
//## for example mitk::ImageSource.
//## @ingroup Process
class MITK_CORE_EXPORT BaseProcess : public itk::ProcessObject
{
public:
mitkClassMacro(BaseProcess, itk::ProcessObject);
//##Documentation
//## @brief Access itk::ProcessObject::m_Updating
//##
//## m_Updating indicates when the pipeline is executing.
//## It prevents infinite recursion when pipelines have loops.
//## \sa itk::ProcessObject::m_Updating
bool Updating() const
{
return m_Updating;
}
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
virtual void UnRegister() const;
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
virtual int GetExternalReferenceCount() const;
protected:
BaseProcess();
virtual ~BaseProcess();
//##Documentation
//## @brief Protected methods for setting outputs.
//##
//## Subclasses make use of them for getting output.
//## These are only overwritten because of itk::DataObject::ConnectSource being
//## private and non-virtual: the important stuff is done in
//## mitk::BaseData::ConnectSource.
virtual void SetNthOutput(unsigned int num, itk::DataObject *output);
//##Documentation
//## @brief Protected methods for setting outputs.
//##
//## Subclasses make use of them for getting output.
//## These are only overwritten because of itk::DataObject::ConnectSource being
//## private and non-virtual: the important stuff is done in
//## mitk::BaseData::ConnectSource.
virtual void AddOutput(itk::DataObject *output);
private:
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
mutable bool m_Unregistering;
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
mutable bool m_CalculatingExternalReferenceCount;
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
mutable int m_ExternalReferenceCount;
};
} // namespace mitk
#endif /* BASEPROCESS_H_HEADER_INCLUDED_C19BE6FC */
diff --git a/Core/Code/Algorithms/mitkBilateralFilter.cpp b/Core/Code/Algorithms/mitkBilateralFilter.cpp
index 0b17ac997c..e58b808377 100644
--- a/Core/Code/Algorithms/mitkBilateralFilter.cpp
+++ b/Core/Code/Algorithms/mitkBilateralFilter.cpp
@@ -1,83 +1,88 @@
-/*=========================================================================
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+/*===================================================================
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkBilateralFilter.h"
#include <itkBilateralImageFilter.h>
#include "mitkImageAccessByItk.h"
#include "mitkITKImageImport.h"
mitk::BilateralFilter::BilateralFilter()
: m_DomainSigma(2.0f), m_RangeSigma(50.0f), m_AutoKernel(true), m_KernelRadius(1u)
{
//default parameters DomainSigma: 2 , RangeSigma: 50, AutoKernel: true, KernelRadius: 1
}
mitk::BilateralFilter::~BilateralFilter()
{
}
void mitk::BilateralFilter::GenerateData()
{
mitk::Image::ConstPointer inputImage = this->GetInput(0);
if ( (inputImage->GetDimension() > 4) || (inputImage->GetDimension() < 2) )
{
MITK_ERROR << "mitk::BilateralFilter:GenerateData works only with 2D, 2D+t, 3D, 3D+t and 4D images, sorry." << std::endl;
itkExceptionMacro("mitk::BilateralFilter:GenerateData works only with 2D, 2D+t, 3D, 3D+t and 4D images, sorry.");
return;
}
switch(inputImage->GetDimension())
{
case 2:
{
AccessFixedDimensionByItk( inputImage.GetPointer(), ItkImageProcessing, 2 ); break;
}
case 3:
{
AccessFixedDimensionByItk( inputImage.GetPointer(), ItkImageProcessing, 3 ); break;
}
case 4:
{
AccessFixedDimensionByItk( inputImage.GetPointer(), ItkImageProcessing, 4 ); break;
}
default: break;
}
}
template<typename TPixel, unsigned int VImageDimension>
void mitk::BilateralFilter::ItkImageProcessing( itk::Image<TPixel,VImageDimension>* itkImage )
{
//ITK Image type given from the input image
typedef itk::Image< TPixel, VImageDimension > ItkImageType;
//bilateral filter with same type
typedef itk::BilateralImageFilter<ItkImageType,ItkImageType> BilateralFilterType;
typename BilateralFilterType::Pointer bilateralFilter = BilateralFilterType::New();
bilateralFilter->SetInput(itkImage);
//set parameters
if(!m_AutoKernel){
bilateralFilter->SetAutomaticKernelSize(m_AutoKernel);
bilateralFilter->SetRadius(m_KernelRadius);
}
bilateralFilter->SetDomainSigma(m_DomainSigma);
bilateralFilter->SetRangeSigma(m_RangeSigma);
bilateralFilter->UpdateLargestPossibleRegion();
//get Pointer to output image
mitk::Image::Pointer resultImage = this->GetOutput();
//write into output image
mitk::CastToMitkImage(bilateralFilter->GetOutput(), resultImage);
}
void mitk::BilateralFilter::GenerateOutputInformation()
{
mitk::Image::Pointer inputImage = (mitk::Image*) this->GetInput();
mitk::Image::Pointer output = this->GetOutput();
itkDebugMacro(<<"GenerateOutputInformation()");
if(inputImage.IsNull()) return;
}
diff --git a/Core/Code/Algorithms/mitkBilateralFilter.h b/Core/Code/Algorithms/mitkBilateralFilter.h
index e6cd48309e..446baa515c 100644
--- a/Core/Code/Algorithms/mitkBilateralFilter.h
+++ b/Core/Code/Algorithms/mitkBilateralFilter.h
@@ -1,79 +1,77 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Module: $RCSfile$
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkBilateralFilter_h
#define __mitkBilateralFilter_h
//MITK
#include <mitkImage.h>
#include "mitkImageToImageFilter.h"
#include <itkImage.h>
namespace mitk
{
class MITK_CORE_EXPORT BilateralFilter : public ImageToImageFilter
{
public:
mitkClassMacro( BilateralFilter , ImageToImageFilter );
itkNewMacro( Self );
itkSetMacro(DomainSigma,float);
itkSetMacro(RangeSigma,float);
itkSetMacro(AutoKernel,bool);
itkSetMacro(KernelRadius,unsigned int);
itkGetMacro(DomainSigma,float);
itkGetMacro(RangeSigma,float);
itkGetMacro(AutoKernel,bool);
itkGetMacro(KernelRadius,unsigned int);
protected:
/*!
\brief standard constructor
*/
BilateralFilter();
/*!
\brief standard destructor
*/
~BilateralFilter();
/*!
\brief Method generating the output information of this filter (e.g. image dimension, image type, etc.).
The interface ImageToImageFilter requires this implementation. Everything is taken from the input image.
*/
virtual void GenerateOutputInformation();
/*!
\brief Method generating the output of this filter. Called in the updated process of the pipeline.
This method generates the smoothed output image.
*/
virtual void GenerateData();
/*!
\brief Internal templated method calling the ITK bilteral filter. Here the actual filtering is performed.
*/
template<typename TPixel, unsigned int VImageDimension>
void ItkImageProcessing( itk::Image<TPixel,VImageDimension>* itkImage );
float m_DomainSigma; ///Sigma of the gaussian kernel. See ITK docu
float m_RangeSigma; ///Sigma of the range mask kernel. See ITK docu
bool m_AutoKernel; //true: kernel size is calculated from DomainSigma. See ITK Doc; false: set by m_KernelRadius
unsigned int m_KernelRadius; //use in combination with m_AutoKernel = true
};
} //END mitk namespace
#endif
diff --git a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h
index b5eca2af94..f6558c1e79 100644
--- a/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h
+++ b/Core/Code/Algorithms/mitkClippedSurfaceBoundsCalculator.h
@@ -1,107 +1,105 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Module: $RCSfile: mitkPropertyManager.cpp,v $
-Language: C++
-Date: $Date: 2005/06/28 12:37:25 $
-Version: $Revision: 1.12 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 ClippedSurfaceBoundsCalculator_h_included
#define ClippedSurfaceBoundsCalculator_h_included
#include "mitkImage.h"
#include "mitkPlaneGeometry.h"
#include <vector>
/**
* \brief Find image slices visible on a given plane.
*
* The class name is not helpful in finding this class. Good suggestions welcome.
*
* Given a PlaneGeometry (e.g. the 2D plane of a render window), this class
* calculates which slices of an mitk::Image are visible on this plane.
* Calculation is done for X, Y, and Z direction, the result is available in
* form of a pair (minimum,maximum) slice index.
*
* Such calculations are useful if you want to display information about the
* currently visible slice (overlays, statistics, ...) and you don't want to
* depend on any prior information about hat the renderwindow is currently showing.
*
* \warning The interface attempts to look like an ITK filter but it is far from being one.
*/
namespace mitk
{
class MITK_CORE_EXPORT ClippedSurfaceBoundsCalculator
{
public:
ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry* geometry = NULL,
mitk::Image::Pointer image = NULL);
ClippedSurfaceBoundsCalculator(const mitk::Geometry3D* geometry,
mitk::Image::Pointer image);
virtual ~ClippedSurfaceBoundsCalculator();
void SetInput(const mitk::PlaneGeometry* geometry, mitk::Image* image);
void SetInput(const mitk::Geometry3D *geometry, mitk::Image *image);
/**
\brief Request calculation.
How cut/visible slice indices are determined:
1. construct a bounding box of the image. This is the box that connect the outer voxel centers(!).
2. check the edges of this box.
3. intersect each edge with the plane geometry
- if the intersection point is within the image box,
we update the visible/cut slice indices for all dimensions.
- else we ignore the cut
*/
void Update();
/**
\brief Minimum (first) and maximum (second) slice index.
*/
typedef std::pair<int, int> OutputType;
/**
\brief What X coordinates (slice indices) are cut/visible in given plane.
*/
OutputType GetMinMaxSpatialDirectionX();
/**
\brief What Y coordinates (slice indices) are cut/visible in given plane.
*/
OutputType GetMinMaxSpatialDirectionY();
/**
\brief What Z coordinates (slice indices) are cut/visible in given plane.
*/
OutputType GetMinMaxSpatialDirectionZ();
protected:
void CalculateIntersectionPoints(const mitk::PlaneGeometry* geometry);
mitk::PlaneGeometry::ConstPointer m_PlaneGeometry;
mitk::Geometry3D::ConstPointer m_Geometry3D;
mitk::Image::Pointer m_Image;
std::vector< OutputType > m_MinMaxOutput;
};
} //namespace mitk
#endif
diff --git a/Core/Code/Algorithms/mitkCoreObjectFactory.cpp b/Core/Code/Algorithms/mitkCoreObjectFactory.cpp
index 2d3ad23ab9..dda9067235 100755
--- a/Core/Code/Algorithms/mitkCoreObjectFactory.cpp
+++ b/Core/Code/Algorithms/mitkCoreObjectFactory.cpp
@@ -1,404 +1,403 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkConfig.h"
#include "mitkCoreObjectFactory.h"
#include "mitkAffineInteractor.h"
#include "mitkColorProperty.h"
#include "mitkDataNode.h"
#include "mitkEnumerationProperty.h"
#include "mitkGeometry2DData.h"
#include "mitkGeometry2DDataMapper2D.h"
#include "mitkGeometry2DDataVtkMapper3D.h"
#include "mitkGeometry3D.h"
#include "mitkGeometryData.h"
#include "mitkImage.h"
#include <mitkImageVtkMapper2D.h>
#include "mitkLevelWindowProperty.h"
#include "mitkLookupTable.h"
#include "mitkLookupTableProperty.h"
#include "mitkPlaneGeometry.h"
#include "mitkPointSet.h"
#include "mitkPointSetGLMapper2D.h"
#include "mitkPointSetVtkMapper3D.h"
#include "mitkPolyDataGLMapper2D.h"
#include "mitkProperties.h"
#include "mitkPropertyList.h"
#include "mitkSlicedGeometry3D.h"
#include "mitkSmartPointerProperty.h"
#include "mitkStringProperty.h"
#include "mitkSurface.h"
#include "mitkSurface.h"
#include "mitkSurfaceGLMapper2D.h"
#include "mitkSurfaceVtkMapper3D.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkTransferFunctionProperty.h"
#include "mitkVolumeDataVtkMapper3D.h"
#include "mitkVtkInterpolationProperty.h"
#include "mitkVtkRepresentationProperty.h"
#include "mitkVtkResliceInterpolationProperty.h"
//#include "mitkPicFileIOFactory.h"
#include "mitkPointSetIOFactory.h"
#include "mitkItkImageFileIOFactory.h"
#include "mitkSTLFileIOFactory.h"
#include "mitkVtkSurfaceIOFactory.h"
#include "mitkVtkImageIOFactory.h"
#include "mitkVtiFileIOFactory.h"
//#include "mitkPicVolumeTimeSeriesIOFactory.h"
#include "mitkImageWriterFactory.h"
#include "mitkPointSetWriterFactory.h"
#include "mitkSurfaceVtkWriterFactory.h"
mitk::CoreObjectFactory::FileWriterList mitk::CoreObjectFactory::m_FileWriters;
void mitk::CoreObjectFactory::RegisterExtraFactory(CoreObjectFactoryBase* factory) {
MITK_DEBUG << "CoreObjectFactory: registering extra factory of type " << factory->GetNameOfClass();
m_ExtraFactories.insert(CoreObjectFactoryBase::Pointer(factory));
}
void mitk::CoreObjectFactory::UnRegisterExtraFactory(CoreObjectFactoryBase *factory)
{
MITK_DEBUG << "CoreObjectFactory: un-registering extra factory of type " << factory->GetNameOfClass();
try
{
m_ExtraFactories.erase(factory);
}
catch( std::exception const& e)
{
MITK_ERROR << "Caugt exception while unregistering: " << e.what();
}
}
mitk::CoreObjectFactory::Pointer mitk::CoreObjectFactory::GetInstance() {
static mitk::CoreObjectFactory::Pointer instance;
if (instance.IsNull())
{
instance = mitk::CoreObjectFactory::New();
}
return instance;
}
#include <mitkDataNodeFactory.h>
void mitk::CoreObjectFactory::SetDefaultProperties(mitk::DataNode* node)
{
if(node==NULL)
return;
mitk::DataNode::Pointer nodePointer = node;
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(node->GetData());
if(image.IsNotNull() && image->IsInitialized())
{
mitk::ImageVtkMapper2D::SetDefaultProperties(node);
mitk::VolumeDataVtkMapper3D::SetDefaultProperties(node);
}
mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface*>(node->GetData());
if(surface.IsNotNull())
{
mitk::SurfaceGLMapper2D::SetDefaultProperties(node);
mitk::SurfaceVtkMapper3D::SetDefaultProperties(node);
}
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
if(pointSet.IsNotNull())
{
mitk::PointSetGLMapper2D::SetDefaultProperties(node);
mitk::PointSetVtkMapper3D::SetDefaultProperties(node);
}
for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) {
(*it)->SetDefaultProperties(node);
}
}
mitk::CoreObjectFactory::CoreObjectFactory()
{
static bool alreadyDone = false;
if (!alreadyDone)
{
MITK_DEBUG << "CoreObjectFactory c'tor" << std::endl;
// FIXME itk::ObjectFactoryBase::RegisterFactory( PicFileIOFactory::New() );
itk::ObjectFactoryBase::RegisterFactory( PointSetIOFactory::New() );
itk::ObjectFactoryBase::RegisterFactory( STLFileIOFactory::New() );
itk::ObjectFactoryBase::RegisterFactory( VtkSurfaceIOFactory::New() );
itk::ObjectFactoryBase::RegisterFactory( VtkImageIOFactory::New() );
itk::ObjectFactoryBase::RegisterFactory( VtiFileIOFactory::New() );
itk::ObjectFactoryBase::RegisterFactory( ItkImageFileIOFactory::New() );
// FIXME itk::ObjectFactoryBase::RegisterFactory( PicVolumeTimeSeriesIOFactory::New() );
mitk::SurfaceVtkWriterFactory::RegisterOneFactory();
mitk::PointSetWriterFactory::RegisterOneFactory();
mitk::ImageWriterFactory::RegisterOneFactory();
CreateFileExtensionsMap();
alreadyDone = true;
}
}
mitk::Mapper::Pointer mitk::CoreObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId id)
{
mitk::Mapper::Pointer newMapper = NULL;
mitk::Mapper::Pointer tmpMapper = NULL;
// check whether extra factories provide mapper
for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) {
tmpMapper = (*it)->CreateMapper(node,id);
if(tmpMapper.IsNotNull())
newMapper = tmpMapper;
}
if (newMapper.IsNull())
{
mitk::BaseData *data = node->GetData();
if ( id == mitk::BaseRenderer::Standard2D )
{
if((dynamic_cast<Image*>(data)!=NULL))
{
newMapper = mitk::ImageVtkMapper2D::New();
newMapper->SetDataNode(node);
}
else if((dynamic_cast<Geometry2DData*>(data)!=NULL))
{
newMapper = mitk::Geometry2DDataMapper2D::New();
newMapper->SetDataNode(node);
}
else if((dynamic_cast<Surface*>(data)!=NULL))
{
newMapper = mitk::SurfaceGLMapper2D::New();
// cast because SetDataNode is not virtual
mitk::SurfaceGLMapper2D *castedMapper = dynamic_cast<mitk::SurfaceGLMapper2D*>(newMapper.GetPointer());
castedMapper->SetDataNode(node);
}
else if((dynamic_cast<PointSet*>(data)!=NULL))
{
newMapper = mitk::PointSetGLMapper2D::New();
newMapper->SetDataNode(node);
}
}
else if ( id == mitk::BaseRenderer::Standard3D )
{
if((dynamic_cast<Image*>(data) != NULL))
{
newMapper = mitk::VolumeDataVtkMapper3D::New();
newMapper->SetDataNode(node);
}
else if((dynamic_cast<Geometry2DData*>(data)!=NULL))
{
newMapper = mitk::Geometry2DDataVtkMapper3D::New();
newMapper->SetDataNode(node);
}
else if((dynamic_cast<Surface*>(data)!=NULL))
{
newMapper = mitk::SurfaceVtkMapper3D::New();
newMapper->SetDataNode(node);
}
else if((dynamic_cast<PointSet*>(data)!=NULL))
{
newMapper = mitk::PointSetVtkMapper3D::New();
newMapper->SetDataNode(node);
}
}
}
return newMapper;
}
/*
// @deprecated
//
#define EXTERNAL_FILE_EXTENSIONS \
"All known formats(*.dcm *.DCM *.dc3 *.DC3 *.gdcm *.ima *.mhd *.mps *.nii *.pic *.pic.gz *.bmp *.png *.jpg *.tiff *.pvtk *.stl *.vtk *.vtp *.vtu *.obj *.vti *.hdr *.nrrd *.nhdr );;" \
"DICOM files(*.dcm *.DCM *.dc3 *.DC3 *.gdcm);;" \
"DKFZ Pic (*.seq *.pic *.pic.gz *.seq.gz);;" \
"NRRD Vector Images (*.nrrd *.nhdr);;" \
"Point sets (*.mps);;" \
"Sets of 2D slices (*.pic *.pic.gz *.bmp *.png *.dcm *.gdcm *.ima *.tiff);;" \
"Surface files (*.stl *.vtk *.vtp *.obj);;" \
"NIfTI format (*.nii)"
#define SAVE_FILE_EXTENSIONS "all (*.pic *.mhd *.vtk *.vti *.hdr *.png *.tiff *.jpg *.hdr *.bmp *.dcm *.gipl *.nii *.nrrd *.nhdr *.spr *.lsm *.dwi *.hdwi *.qbi *.hqbi)"
*/
/**
* @brief This method gets the supported (open) file extensions as string. This string is can then used by the QT QFileDialog widget.
* @return The c-string that contains the file extensions
*
*/
const char* mitk::CoreObjectFactory::GetFileExtensions()
{
MultimapType aMap;
for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ )
{
aMap = (*it)->GetFileExtensionsMap();
this->MergeFileExtensions(m_FileExtensionsMap, aMap);
}
this->CreateFileExtensions(m_FileExtensionsMap, m_FileExtensions);
return m_FileExtensions.c_str();
}
/**
* @brief Merge the input map into the fileExtensionsMap. Duplicate entries are removed
* @param fileExtensionsMap the existing map, it contains value pairs like ("*.dcm", "DICOM files"),("*.dc3", "DICOM files").
* This map is extented/merged with the values from the input map.
* @param inputMap the input map, it contains value pairs like ("*.dcm", "DICOM files"),("*.dc3", "DICOM files") returned by
* the extra factories.
*
*/
void mitk::CoreObjectFactory::MergeFileExtensions(MultimapType& fileExtensionsMap, MultimapType inputMap)
{
bool duplicateFound = false;
std::pair<MultimapType::iterator, MultimapType::iterator> pairOfIter;
for (MultimapType::iterator it = inputMap.begin(); it != inputMap.end(); ++it)
{
duplicateFound = false;
pairOfIter = fileExtensionsMap.equal_range((*it).first);
for (MultimapType::iterator it2 = pairOfIter.first; it2 != pairOfIter.second; ++it2)
{
//cout << " [" << (*it).first << ", " << (*it).second << "]" << endl;
std::string aString = (*it2).second;
if (aString.compare((*it).second) == 0)
{
//cout << " DUP!! [" << (*it).first << ", " << (*it).second << "]" << endl;
duplicateFound = true;
break;
}
}
if (!duplicateFound)
{
fileExtensionsMap.insert(std::pair<std::string, std::string>((*it).first, (*it).second));
}
}
}
/**
* @brief get the defined (open) file extension map
* @return the defined (open) file extension map
*/
mitk::CoreObjectFactoryBase::MultimapType mitk::CoreObjectFactory::GetFileExtensionsMap()
{
return m_FileExtensionsMap;
}
/**
* @brief initialize the file extension entries for open and save
*/
void mitk::CoreObjectFactory::CreateFileExtensionsMap()
{
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.dcm", "DICOM files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.DCM", "DICOM files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.dc3", "DICOM files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.DC3", "DICOM files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.gdcm", "DICOM files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.seq", "DKFZ Pic"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.pic", "DKFZ Pic"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.pic.gz", "DKFZ Pic"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.mhd", "MetaImage"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.seq.gz", "DKFZ Pic"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.hdr", "High Dynamic Range File"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.img", "High Dynamic Range File"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.img.gz", "High Dynamic Range File"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.nrrd", "Nearly Raw Raster Data"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.nhdr", "NRRD with detached header"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.mps", "Point sets"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.pic", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.pic.gz", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.bmp", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.png", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.jpg", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.jpeg", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.dcm", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.gdcm", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.ima", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.tiff", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.tif", "Sets of 2D slices"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.stl", "Surface files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.vtk", "Surface files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.vtp", "Surface files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.obj", "Surface files"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.nii", "NIfTI format"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.nii.gz", "NIfTI format"));
//m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.pic", "DKFZ Pic"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.mhd", "MetaImage"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.vtk", "Surface Files"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.vti", "VTK Image Data Files"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.hdr", "High Dynamic Range File"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.png", "Sets of 2D slices"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.tiff", "Sets of 2D slices"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.tif", "Sets of 2D slices"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.jpg", "Sets of 2D slices"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.jpeg", "Sets of 2D slices"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.bmp", "Sets of 2D slices"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.dcm", "Sets of 2D slices"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.gipl", "UMDS GIPL Format Files"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.nii", "NIfTI format"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.nrrd", "Nearly Raw Raster Data"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.nhdr", "NRRD with detached header"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.lsm", "Microscope Images"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.dwi", "Diffusion Weighted Images"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.hdwi", "Diffusion Weighted Images"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.qbi", "Q-Ball Images"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.hqbi", "Q-Ball Images"));
}
/**
* @brief This method gets the supported (save) file extensions as string. This string is can then used by the QT QFileDialog widget.
* @return The c-string that contains the (save) file extensions
*
*/
const char* mitk::CoreObjectFactory::GetSaveFileExtensions() {
MultimapType aMap;
for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ )
{
aMap = (*it)->GetSaveFileExtensionsMap();
this->MergeFileExtensions(m_SaveFileExtensionsMap, aMap);
}
this->CreateFileExtensions(m_SaveFileExtensionsMap, m_SaveFileExtensions);
return m_SaveFileExtensions.c_str();
};
/**
* @brief get the defined (save) file extension map
* @return the defined (save) file extension map
*/
mitk::CoreObjectFactoryBase::MultimapType mitk::CoreObjectFactory::GetSaveFileExtensionsMap()
{
return m_SaveFileExtensionsMap;
}
mitk::CoreObjectFactory::FileWriterList mitk::CoreObjectFactory::GetFileWriters() {
FileWriterList allWriters = m_FileWriters;
for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) {
FileWriterList list2 = (*it)->GetFileWriters();
allWriters.merge(list2);
}
return allWriters;
}
void mitk::CoreObjectFactory::MapEvent(const mitk::Event*, const int) {
}
diff --git a/Core/Code/Algorithms/mitkCoreObjectFactory.h b/Core/Code/Algorithms/mitkCoreObjectFactory.h
index 4d3634e3e5..60b38e73db 100755
--- a/Core/Code/Algorithms/mitkCoreObjectFactory.h
+++ b/Core/Code/Algorithms/mitkCoreObjectFactory.h
@@ -1,63 +1,62 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 COREOBJECTFACTORY_H_INCLUDED
#define COREOBJECTFACTORY_H_INCLUDED
#include <set>
#include <MitkExports.h>
#include "mitkCoreObjectFactoryBase.h"
#include "mitkFileWriterWithInformation.h"
namespace mitk {
class Event;
class MITK_CORE_EXPORT CoreObjectFactory : public CoreObjectFactoryBase
{
public:
mitkClassMacro(CoreObjectFactory,CoreObjectFactoryBase);
itkFactorylessNewMacro(CoreObjectFactory);
virtual Mapper::Pointer CreateMapper(mitk::DataNode* node, MapperSlotId slotId);
virtual void SetDefaultProperties(mitk::DataNode* node);
virtual const char* GetFileExtensions();
virtual MultimapType GetFileExtensionsMap();
virtual const char* GetSaveFileExtensions();
virtual MultimapType GetSaveFileExtensionsMap();
virtual FileWriterList GetFileWriters();
virtual void MapEvent(const mitk::Event* event, const int eventID);
virtual void RegisterExtraFactory(CoreObjectFactoryBase* factory);
virtual void UnRegisterExtraFactory(CoreObjectFactoryBase* factory);
static Pointer GetInstance();
protected:
CoreObjectFactory();
void MergeFileExtensions(MultimapType& fileExtensionsMap, MultimapType inputMap);
void CreateFileExtensionsMap();
void CreateSaveFileExtensions();
typedef std::set<mitk::CoreObjectFactoryBase::Pointer> ExtraFactoriesContainer;
ExtraFactoriesContainer m_ExtraFactories;
static FileWriterList m_FileWriters;
std::string m_FileExtensions;
MultimapType m_FileExtensionsMap;
std::string m_SaveFileExtensions;
MultimapType m_SaveFileExtensionsMap;
};
} // namespace mitk
#endif
diff --git a/Core/Code/Algorithms/mitkCoreObjectFactoryBase.cpp b/Core/Code/Algorithms/mitkCoreObjectFactoryBase.cpp
index 7b5b2d3ee9..5dd6b8972f 100644
--- a/Core/Code/Algorithms/mitkCoreObjectFactoryBase.cpp
+++ b/Core/Code/Algorithms/mitkCoreObjectFactoryBase.cpp
@@ -1,73 +1,72 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-04-21 15:31:43 +0200 (Mi, 21 Apr 2010) $
-Version: $Revision: 22357 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkCoreObjectFactoryBase.h"
void mitk::CoreObjectFactoryBase::CreateFileExtensions(MultimapType fileExtensionsMap, std::string& fileExtensions)
{
std::map<std::string, std::string> aMap;
// group the extensions by extension-group
// e.g. aMap["DICOM files"] = "*.dcm *.DCM *.dc3 *.DC3 *.gdcm"
for (MultimapType::iterator it = fileExtensionsMap.begin(); it != fileExtensionsMap.end(); ++it)
{
std::string aValue = aMap[(*it).second];
if (aValue.compare("") != 0)
{
aValue.append(" ");
}
aValue.append((*it).first);
aMap[(*it).second] = aValue;
}
// build the "all" entry (it contains all the extensions)
// and add it to the string in the first position
// e.g. "all (*.dcm *.DCM *.dc3 *.DC3 *.gdcm *.ima *.mhd ... *.vti *.hdr *.nrrd *.nhdr );;"
fileExtensions = "known extensions (";
std::string lastKey = "";
for (MultimapType::iterator it = fileExtensionsMap.begin(); it != fileExtensionsMap.end(); ++it)
{
std::string aKey = (*it).first;
if (aKey.compare(lastKey) != 0)
{
if (lastKey.compare("") != 0)
{
fileExtensions.append(" ");
}
fileExtensions.append(aKey);
}
lastKey = aKey;
}
fileExtensions.append(");;all (*);;");
// build the entry for each extension-group
// e.g. "Sets of 2D slices (*.pic *.pic.gz *.bmp *.png *.dcm *.gdcm *.ima *.tiff);;"
for (std::map<std::string, std::string>::iterator it = aMap.begin(); it != aMap.end(); ++it)
{
//cout << " [" << (*it).first << ", " << (*it).second << "]" << endl;
std::string aKey = (*it).first;
if (aKey.compare("") != 0)
{
fileExtensions.append((*it).first);
fileExtensions.append(" (");
fileExtensions.append((*it).second);
fileExtensions.append(");;");
}
}
}
diff --git a/Core/Code/Algorithms/mitkCoreObjectFactoryBase.h b/Core/Code/Algorithms/mitkCoreObjectFactoryBase.h
index 7a2f41b2ce..33404c0d6d 100644
--- a/Core/Code/Algorithms/mitkCoreObjectFactoryBase.h
+++ b/Core/Code/Algorithms/mitkCoreObjectFactoryBase.h
@@ -1,79 +1,78 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 COREOBJECTFACTORYBASE_H_INCLUDED
#define COREOBJECTFACTORYBASE_H_INCLUDED
// the mbilog header is necessary for CMake test drivers.
// Since the EXTRA_INCLUDE parameter of CREATE_TEST_SOURCELIST only
// allows one extra include file, we specify mitkLog.h here so it will
// be available to all classes implementing this interface.
#include "mitkLog.h"
#include <MitkExports.h>
#include "mitkMapper.h"
#include <itkObjectFactoryBase.h>
#include <itkVersion.h>
#include "mitkFileWriterWithInformation.h"
namespace mitk {
class DataNode;
//## @brief base-class for factories of certain mitk objects.
//## @ingroup Algorithms
//## This interface can be implemented by factories which add new mapper classes or extend the
//## data tree deserialization mechanism.
class MITK_CORE_EXPORT CoreObjectFactoryBase : public itk::Object
{
public:
typedef std::list<mitk::FileWriterWithInformation::Pointer> FileWriterList;
typedef std::multimap<std::string, std::string> MultimapType;
mitkClassMacro(CoreObjectFactoryBase,itk::Object);
virtual Mapper::Pointer CreateMapper(mitk::DataNode* node, MapperSlotId slotId) = 0;
virtual void SetDefaultProperties(mitk::DataNode* node) = 0;
virtual const char* GetFileExtensions() = 0;
virtual MultimapType GetFileExtensionsMap() = 0;
virtual const char* GetSaveFileExtensions() = 0;
virtual MultimapType GetSaveFileExtensionsMap() = 0;
virtual const char* GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
virtual const char* GetDescription() const
{
return "Core Object Factory";
}
FileWriterList GetFileWriters() {
return m_FileWriters;
}
protected:
/**
* @brief create a string from a map that contains the file extensions
* @param fileExtensionsMap input map with the file extensions, e.g. ("*.dcm", "DICOM files")("*.dc3", "DICOM files")
* @param fileExtensions the converted output string, suitable for the QT QFileDialog widget
* e.g. "all (*.dcm *.DCM *.dc3 ... *.vti *.hdr *.nrrd *.nhdr );;Q-Ball Images (*.hqbi *qbi)"
*/
static void CreateFileExtensions(MultimapType fileExtensionsMap, std::string& fileExtensions);
FileWriterList m_FileWriters;
};
}
#endif
diff --git a/Core/Code/Algorithms/mitkDataNodeFactory.cpp b/Core/Code/Algorithms/mitkDataNodeFactory.cpp
index 68d7fbd84b..86df353629 100644
--- a/Core/Code/Algorithms/mitkDataNodeFactory.cpp
+++ b/Core/Code/Algorithms/mitkDataNodeFactory.cpp
@@ -1,483 +1,482 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkConfig.h>
#include <mitkDataNodeFactory.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkCoreObjectFactory.h>
#include <mitkITKImageImport.h>
// C-Standard library includes
#include <stdlib.h>
#include <locale.h>
// STL-related includes
#include <vector>
#include <map>
#include <istream>
#include <cstdlib>
#include <locale>
// VTK-related includes
#include <vtkSTLReader.h>
#include <vtkOBJReader.h>
#include <vtkPolyData.h>
#include <vtkPolyDataNormals.h>
#include <vtkDataReader.h>
#include <vtkPolyDataReader.h>
#include <vtkStructuredPointsReader.h>
#include <vtkStructuredPoints.h>
#include <vtkLookupTable.h>
#include <vtkPointData.h>
#include <vtkXMLImageDataReader.h>
// ITK-related includes
#include <itksys/SystemTools.hxx>
#include <itksys/Directory.hxx>
#include <itkImage.h>
#include <itkImageSeriesReader.h>
#include <itkImageFileReader.h>
#include <itkImageIOFactory.h>
#include <itkImageIORegion.h>
#include <itkImageSeriesReader.h>
#include <itkDICOMImageIO2.h>
#include <itkDICOMSeriesFileNames.h>
#include <itkGDCMImageIO.h>
#ifdef NOMINMAX
# define DEF_NOMINMAX
# undef NOMINMAX
#endif
#include <itkGDCMSeriesFileNames.h>
#ifdef DEF_NOMINMAX
# ifndef NOMINMAX
# define NOMINMAX
# endif
# undef DEF_NOMINMAX
#endif
#include <itkNumericSeriesFileNames.h>
#include <itkCommand.h>
// MITK-related includes
#include "mitkSurface.h"
#include "mitkPointSet.h"
#include "mitkStringProperty.h"
#include "mitkProperties.h"
//#include "mitkMaterialProperty.h"
#include "mitkLevelWindowProperty.h"
#include "mitkVtkRepresentationProperty.h"
#include "mitkVtkInterpolationProperty.h"
#include "mitkVtkScalarModeProperty.h"
#include "mitkImage.h"
#include "mitkLookupTableProperty.h"
#include "mitkLookupTable.h"
#include "mitkImageChannelSelector.h"
#include "mitkImageSliceSelector.h"
#include "mitkCoreObjectFactory.h"
#include "mitkTransferFunctionProperty.h"
#include "mitkVtkResliceInterpolationProperty.h"
#include "mitkProgressBar.h"
#include <mitkDicomSeriesReader.h>
bool mitk::DataNodeFactory::m_TextureInterpolationActive = false; // default value for texture interpolation if nothing is defined in global options (see QmitkMainTemplate.ui.h)
mitk::DataNodeFactory::DataNodeFactory()
{
m_Serie = false;
m_OldProgress = 0;
this->Modified();
//ensure that a CoreObjectFactory has been instantiated
mitk::CoreObjectFactory::GetInstance();
}
mitk::DataNodeFactory::~DataNodeFactory()
{}
void mitk::DataNodeFactory::SetImageSerie(bool serie)
{
m_Serie = serie;
}
void mitk::DataNodeFactory::GenerateData()
{
// IF filename is something.pic, and something.pic does not exist, try to read something.pic.gz
// if there are both, something.pic and something.pic.gz, only the requested file is read
// not only for images, but for all formats
std::ifstream exists(m_FileName.c_str());
if (!exists)
{
std::string testfilename = m_FileName + ".gz";
std::ifstream exists(testfilename.c_str());
if (exists.good())
{
m_FileName += ".gz";
}
else
{
testfilename = m_FileName + ".GZ";
std::ifstream exists(testfilename.c_str());
if (exists.good())
{
m_FileName += ".GZ";
}
else
{
std::string message("File does not exist, or cannot be read. Filename = ");
message += m_FileName;
MITK_ERROR << message;
itkExceptionMacro( << message );
}
}
}
// part for DICOM
// const char *numbers = "0123456789.";
// std::string::size_type first_non_number;
// first_non_number = itksys::SystemTools::GetFilenameName(m_FileName).find_first_not_of ( numbers );
if (DicomSeriesReader::IsDicom(this->m_FileName) /*|| first_non_number == std::string::npos*/)
{
this->ReadFileSeriesTypeDCM();
}
else
{
bool usedNewDTNF = false;
// the mitkBaseDataIO class returns a pointer of a vector of BaseData objects
std::vector<mitk::BaseData::Pointer> baseDataVector = mitk::BaseDataIO::LoadBaseDataFromFile( m_FileName, m_FilePrefix, m_FilePattern, m_Serie );
if( !baseDataVector.empty() )
this->ResizeOutputs((unsigned int)baseDataVector.size());
for(int i=0; i<(int)baseDataVector.size(); i++)
{
mitk::BaseData::Pointer baseData = baseDataVector.at(i);
if( baseData.IsNotNull() )
{
usedNewDTNF = true;
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(baseData);
this->SetDefaultCommonProperties( node );
this->SetOutput(i, node);
}
}
if(!usedNewDTNF && ( m_FileName != "" ) && !(m_Serie == false))
ReadFileSeriesTypeITKImageSeriesReader();
}
}
void mitk::DataNodeFactory::ResizeOutputs( const unsigned int& num )
{
unsigned int prevNum = this->GetNumberOfOutputs();
this->SetNumberOfOutputs( num );
for ( unsigned int i = prevNum; i < num; ++i )
{
this->SetNthOutput( i, this->MakeOutput( i ).GetPointer() );
}
}
bool mitk::DataNodeFactory::FileNameEndsWith( const std::string& name )
{
if (m_FileName.size() < name.size()) return false;
return m_FileName.substr(m_FileName.size() - name.size()) == name;
}
bool mitk::DataNodeFactory::FilePatternEndsWith( const std::string& name )
{
return m_FilePattern.find( name ) != std::string::npos;
}
std::string mitk::DataNodeFactory::GetBaseFileName()
{
return itksys::SystemTools::GetFilenameName( m_FileName );
}
std::string mitk::DataNodeFactory::GetBaseFilePrefix()
{
return itksys::SystemTools::GetFilenameName( m_FilePrefix );
}
std::string mitk::DataNodeFactory::GetDirectory()
{
if ( !m_FileName.empty() ) return itksys::SystemTools::GetFilenamePath( m_FileName );
if ( !m_FilePrefix.empty() ) return itksys::SystemTools::GetFilenamePath( m_FilePrefix );
return std::string();
}
void mitk::DataNodeFactory::ReadFileSeriesTypeDCM()
{
const char* previousCLocale = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
std::locale previousCppLocale( std::cin.getloc() );
std::locale l( "C" );
std::cin.imbue(l);
if ( DicomSeriesReader::IsPhilips3DDicom(this->GetFileName()) )
{
MITK_INFO << "it is a Philips3D US Dicom file" << std::endl;
this->ResizeOutputs(1);
DataNode::Pointer node = this->GetOutput(0);
mitk::DicomSeriesReader::StringContainer stringvec;
stringvec.push_back(this->GetFileName());
if (DicomSeriesReader::LoadDicomSeries(stringvec, *node))
{
node->SetName(this->GetBaseFileName());
}
setlocale(LC_NUMERIC, previousCLocale);
std::cin.imbue(previousCppLocale);
return;
}
DicomSeriesReader::UidFileNamesMap names_map = DicomSeriesReader::GetSeries(this->GetDirectory(), this->m_SeriesRestrictions);
const unsigned int size = names_map.size();
this->ResizeOutputs(size);
ProgressBar::GetInstance()->AddStepsToDo(size);
ProgressBar::GetInstance()->Progress();
unsigned int outputIndex = 0u;
const DicomSeriesReader::UidFileNamesMap::const_iterator n_end = names_map.end();
for (DicomSeriesReader::UidFileNamesMap::const_iterator n_it = names_map.begin(); n_it != n_end; ++n_it)
{
const std::string &uid = n_it->first;
DataNode::Pointer node = this->GetOutput(outputIndex);
MITK_INFO << "Reading series " << outputIndex << ": " << uid << std::endl;
if (DicomSeriesReader::LoadDicomSeries(n_it->second, *node))
{
std::string nodeName(uid);
std::string studyDescription;
if ( node->GetStringProperty( "dicom.study.StudyDescription", studyDescription ) )
{
nodeName = studyDescription;
std::string seriesDescription;
if ( node->GetStringProperty( "dicom.series.SeriesDescription", seriesDescription ) )
{
nodeName += "/" + seriesDescription;
}
}
node->SetName(nodeName);
++outputIndex;
}
else
{
MITK_ERROR << "Skipping series " << outputIndex << " due to exception" << std::endl;
}
ProgressBar::GetInstance()->Progress();
}
setlocale(LC_NUMERIC, previousCLocale);
std::cin.imbue(previousCppLocale);
}
void mitk::DataNodeFactory::ReadFileSeriesTypeITKImageSeriesReader()
{
typedef itk::Image<int, 3> ImageType;
typedef itk::ImageSeriesReader< ImageType > ReaderType;
typedef itk::NumericSeriesFileNames NameGenerator;
if ( ! this->GenerateFileList() )
{
itkWarningMacro( "Sorry, file list could not be generated!" );
return ;
}
if ( m_MatchedFileNames.size() == 0 )
{
itkWarningMacro( "Sorry, no files matched the given filename ("<< m_FileName <<")!" );
return ;
}
//
// Finally, initialize the ITK-reader and load the files!
//
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileNames( m_MatchedFileNames );
try
{
reader->Update();
ResizeOutputs( reader->GetNumberOfOutputs() );
for ( unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i )
{
//Initialize mitk image from itk
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk( reader->GetOutput( i ) );
image->SetVolume( reader->GetOutput( i )->GetBufferPointer() );
//add the mitk image to the node
mitk::DataNode::Pointer node = this->GetOutput( i );
node->SetData( image );
mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New( m_FileName );
node->SetProperty( "name", nameProp );
}
}
catch ( const std::exception & e )
{
itkWarningMacro( << e.what() );
return ;
}
}
mitk::ColorProperty::Pointer mitk::DataNodeFactory::DefaultColorForOrgan( const std::string& organ )
{
static bool initialized = false;
static std::map< std::string, std::string > s_ColorMap;
if (!initialized)
{
// all lowercase here, please!
s_ColorMap.insert( std::make_pair( "ankle", "0xe38686") );
s_ColorMap.insert( std::make_pair( "appendix", "0xe38686") );
s_ColorMap.insert( std::make_pair( "blood vessels", "0xff3131") );
s_ColorMap.insert( std::make_pair( "bronchial tree", "0x3168ff") );
s_ColorMap.insert( std::make_pair( "bone", "0xd5d5d5") );
s_ColorMap.insert( std::make_pair( "brain", "0xff9cca") );
s_ColorMap.insert( std::make_pair( "coccyx", "0xe38686") );
s_ColorMap.insert( std::make_pair( "colon", "0xe38686") );
s_ColorMap.insert( std::make_pair( "cyst", "0xe38686") );
s_ColorMap.insert( std::make_pair( "elbow", "0xe38686") );
s_ColorMap.insert( std::make_pair( "eye", "0xe38686") );
s_ColorMap.insert( std::make_pair( "fallopian tube", "0xe38686") );
s_ColorMap.insert( std::make_pair( "fat", "0xff2bee") );
s_ColorMap.insert( std::make_pair( "hand", "0xe38686") );
s_ColorMap.insert( std::make_pair( "gall bladder", "0x567f18") );
s_ColorMap.insert( std::make_pair( "heart", "0xeb1d32") );
s_ColorMap.insert( std::make_pair( "hip", "0xe38686") );
s_ColorMap.insert( std::make_pair( "kidney", "0xd33f00") );
s_ColorMap.insert( std::make_pair( "knee", "0xe38686") );
s_ColorMap.insert( std::make_pair( "larynx", "0xe38686") );
s_ColorMap.insert( std::make_pair( "liver", "0xffcc3d") );
s_ColorMap.insert( std::make_pair( "lung", "0x6bdcff") );
s_ColorMap.insert( std::make_pair( "lymph node", "0xff0000") );
s_ColorMap.insert( std::make_pair( "muscle", "0xff456a") );
s_ColorMap.insert( std::make_pair( "nerve", "0xffea4f") );
s_ColorMap.insert( std::make_pair( "nose", "0xe38686") );
s_ColorMap.insert( std::make_pair( "oesophagus", "0xe38686") );
s_ColorMap.insert( std::make_pair( "ovaries", "0xe38686") );
s_ColorMap.insert( std::make_pair( "pancreas", "0xf9ab3d") );
s_ColorMap.insert( std::make_pair( "pelvis", "0xe38686") );
s_ColorMap.insert( std::make_pair( "penis", "0xe38686") );
s_ColorMap.insert( std::make_pair( "pharynx", "0xe38686") );
s_ColorMap.insert( std::make_pair( "prostate", "0xe38686") );
s_ColorMap.insert( std::make_pair( "rectum", "0xe38686") );
s_ColorMap.insert( std::make_pair( "sacrum", "0xe38686") );
s_ColorMap.insert( std::make_pair( "seminal vesicle", "0xe38686") );
s_ColorMap.insert( std::make_pair( "shoulder", "0xe38686") );
s_ColorMap.insert( std::make_pair( "spinal cord", "0xf5f93d") );
s_ColorMap.insert( std::make_pair( "spleen", "0xf96c3d") );
s_ColorMap.insert( std::make_pair( "stomach", "0xf96c3d") );
s_ColorMap.insert( std::make_pair( "teeth", "0xfffcd8") );
s_ColorMap.insert( std::make_pair( "testicles", "0xe38686") );
s_ColorMap.insert( std::make_pair( "thyroid", "0xfff694") );
s_ColorMap.insert( std::make_pair( "tongue", "0xe38686") );
s_ColorMap.insert( std::make_pair( "tumor", "0x937011") );
s_ColorMap.insert( std::make_pair( "urethra", "0xf8ff32") );
s_ColorMap.insert( std::make_pair( "urinary bladder", "0xf8ff32") );
s_ColorMap.insert( std::make_pair( "uterus", "0xe38686") );
s_ColorMap.insert( std::make_pair( "vagina", "0xe38686") );
s_ColorMap.insert( std::make_pair( "vertebra", "0xe38686") );
s_ColorMap.insert( std::make_pair( "wrist", "0xe38686") );
initialized = true;
}
std::string lowercaseOrgan(organ);
for(unsigned int i = 0; i < organ.length(); i++)
{
lowercaseOrgan[i] = tolower(lowercaseOrgan[i]);
}
std::map< std::string, std::string >::iterator iter = s_ColorMap.find( lowercaseOrgan );
if ( iter != s_ColorMap.end() )
{
std::string hexColor = iter->second;
std::string hexRed = std::string("0x") + hexColor.substr( 2, 2 );
std::string hexGreen = std::string("0x") + hexColor.substr( 4, 2 );
std::string hexBlue = std::string("0x") + hexColor.substr( 6, 2 );
long int red = strtol( hexRed.c_str(), NULL, 16 );
long int green = strtol( hexGreen.c_str(), NULL, 16 );
long int blue = strtol( hexBlue.c_str(), NULL, 16 );
return ColorProperty::New( (float)red/ 255.0, (float)green/ 255.0, (float)blue/ 255.0 );
}
else
{
// a default color (green)
return ColorProperty::New( 0.0, 1.0, 0.0 );
}
}
void mitk::DataNodeFactory::SetDefaultCommonProperties(mitk::DataNode::Pointer &node)
{
// path
mitk::StringProperty::Pointer pathProp = mitk::StringProperty::New( itksys::SystemTools::GetFilenamePath( m_FileName ) );
node->SetProperty( StringProperty::PATH, pathProp );
// name already defined?
mitk::StringProperty::Pointer nameProp = dynamic_cast<mitk::StringProperty*>(node->GetProperty("name"));
if(nameProp.IsNull() || (strcmp(nameProp->GetValue(),"No Name!")==0))
{
// name already defined in BaseData
mitk::StringProperty::Pointer baseDataNameProp = dynamic_cast<mitk::StringProperty*>(node->GetData()->GetProperty("name").GetPointer() );
if(baseDataNameProp.IsNull() || (strcmp(baseDataNameProp->GetValue(),"No Name!")==0))
{
// name neither defined in node, nor in BaseData -> name = filename
if (FileNameEndsWith( ".gz" ))
m_FileName = m_FileName.substr( 0, m_FileName.length()-3 );
nameProp = mitk::StringProperty::New( itksys::SystemTools::GetFilenameWithoutLastExtension( m_FileName ) );
node->SetProperty( "name", nameProp );
}
else
{
// name defined in BaseData!
nameProp = mitk::StringProperty::New( baseDataNameProp->GetValue() );
node->SetProperty( "name", nameProp );
}
}
// visibility
if(!node->GetProperty("visible"))
node->SetVisibility(true);
}
diff --git a/Core/Code/Algorithms/mitkDataNodeFactory.h b/Core/Code/Algorithms/mitkDataNodeFactory.h
index 63bc5228f7..f66a5a5d70 100644
--- a/Core/Code/Algorithms/mitkDataNodeFactory.h
+++ b/Core/Code/Algorithms/mitkDataNodeFactory.h
@@ -1,183 +1,182 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _DATA_TREE_NODE_FACTORY_H_
#define _DATA_TREE_NODE_FACTORY_H_
#include "mitkDataNodeSource.h"
#include "mitkFileSeriesReader.h"
#include "mitkColorProperty.h"
#include <vtkConfigure.h>
#include <string>
namespace mitk
{
/**
* @brief Factory, which creates instances of mitk::DataNodes filled with
* data read from a given file
*
* This class reads files, creates an appropriate mitk::BaseData and adds the
* BaseData to a mitk::DataNode. This filter may produce one or more outputs
* (i.e. mitk::DataNodes). The number of generated nodes can be retrieved by a
* call of GetNumberOfOutputs().
*
* If you want to add a new file type, you have to register the factory
* of the file reader in the class mitk::BaseDataIOFactory.
* @ingroup IO
*/
class MITK_CORE_EXPORT DataNodeFactory : public DataNodeSource, public FileSeriesReader
{
public:
mitkClassMacro( DataNodeFactory, DataNodeSource );
itkNewMacro( Self );
/**
* Sets the filename of the file to read.
* @param FileName the name of the file to read.
*/
itkSetStringMacro( FileName );
/**
* @returns the name of the file to be read from disk.
*/
itkGetStringMacro( FileName );
/**
* \brief Set prefix for multiple load
*/
itkSetStringMacro( FilePrefix );
/**
* \brief Get prefix for multiple load
*/
itkGetStringMacro( FilePrefix );
/**
* \brief Set pattern for multiple load
*/
itkSetStringMacro( FilePattern );
/**
* \brief Get pattern for multiple load
*/
itkGetStringMacro( FilePattern );
/**
* Nice default colors for segmentations of some "normal" organs.
*/
static ColorProperty::Pointer DefaultColorForOrgan( const std::string& );
void SetDefaultCommonProperties(mitk::DataNode::Pointer &node);
/**
* if true -> loaded image is part of a serie
*/
void SetImageSerie(bool serie);
void AddSeriesRestriction(const std::string &tag)
{m_SeriesRestrictions.push_back(tag);}
static bool m_TextureInterpolationActive;
protected:
/**
* Constructor.
*/
DataNodeFactory();
/**
* Virtual destructor.
*/
virtual ~DataNodeFactory();
bool m_Serie;
/**
* Determines of which file type a given file is and calls the
* appropriate reader function.
*/
virtual void GenerateData();
/**
* Resizes the number of outputs of the factory.
* The outputs are initialized by empty DataNodes
* @param num the new number of outputs
*/
virtual void ResizeOutputs( const unsigned int& num );
/**
* Checks if the file name m_FileName ends with the given name.
* Currently, this check is done by a dumb search for name in
* the filename.
* @param name the extension of the file
* @returns true, if the filename contains name.
*/
virtual bool FileNameEndsWith(const std::string& name);
/**
* Checks if the file pattern m_FilePattern ends with the given name.
* Currently, this check is done by a dumb search for name in
* the filename.
* @param name the extension of the file
* @returns true, if the filepattern contains name.
*/
virtual bool FilePatternEndsWith(const std::string& name);
/**
* @returns the plain filename, that is, without any directory.
*/
virtual std::string GetBaseFileName();
/**
* @returns the plain file prefix, that is, without any directory.
*/
virtual std::string GetBaseFilePrefix();
/**
* @returns the directory of the file name m_FileName.
*/
virtual std::string GetDirectory();
#ifdef MBI_INTERNAL
virtual void ReadFileTypeHPSONOS();
#ifdef HAVE_IPDICOM
virtual void ReadFileTypeIPDCM();
#endif /* HAVE_IPDICOM */
#ifdef USE_TUS_READER
virtual void ReadFileTypeTUS();
#endif
#endif /* MBI_INTERNAL */
virtual void ReadFileSeriesTypeDCM();
virtual void ReadFileSeriesTypeITKImageSeriesReader();
std::vector<std::string> m_SeriesRestrictions;
int m_OldProgress;
};
}
#endif //#ifndef __DATA_TREE_NODE_FACTORY_H
diff --git a/Core/Code/Algorithms/mitkDataNodeSource.cpp b/Core/Code/Algorithms/mitkDataNodeSource.cpp
index 28f6c729e8..4a6a880ed2 100644
--- a/Core/Code/Algorithms/mitkDataNodeSource.cpp
+++ b/Core/Code/Algorithms/mitkDataNodeSource.cpp
@@ -1,85 +1,84 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDataNodeSource.h"
mitk::DataNodeSource::DataNodeSource()
{
// Create the output.
OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
assert (output.IsNotNull());
this->SetNumberOfOutputs( 1 );
this->SetOutput(0, output.GetPointer());
}
mitk::DataNodeSource::~DataNodeSource()
{
}
itk::DataObject::Pointer mitk::DataNodeSource::MakeOutput ( unsigned int /*idx*/ )
{
return OutputType::New().GetPointer();
}
void mitk::DataNodeSource::SetOutput( OutputType* output )
{
this->itk::ProcessObject::SetNthOutput( 0, output );
}
void mitk::DataNodeSource::SetOutput( unsigned int idx, OutputType* output )
{
this->itk::ProcessObject::SetNthOutput(idx, output);
}
mitk::DataNodeSource::OutputType* mitk::DataNodeSource::GetOutput()
{
if ( this->GetNumberOfOutputs() < 1 )
{
return 0;
}
else
{
return dynamic_cast<OutputType*> ( this->GetOutput( 0 ) );
}
}
mitk::DataNodeSource::OutputType* mitk::DataNodeSource::GetOutput ( unsigned int idx )
{
return dynamic_cast<OutputType*> ( this->itk::ProcessObject::GetOutput( idx ) );
}
diff --git a/Core/Code/Algorithms/mitkDataNodeSource.h b/Core/Code/Algorithms/mitkDataNodeSource.h
index 0fd9267c99..b52fa02dcb 100644
--- a/Core/Code/Algorithms/mitkDataNodeSource.h
+++ b/Core/Code/Algorithms/mitkDataNodeSource.h
@@ -1,91 +1,90 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_DATA_TREE_NODE_SOURCE_H
#define _MITK_DATA_TREE_NODE_SOURCE_H
#include "itkProcessObject.h"
#include "mitkDataNode.h"
namespace mitk
{
/**
* @brief Superclass of all classes generating data tree nodes (instances of class
* mitk::DataNode) as output.
*
* In itk and vtk the generated result of a ProcessObject is only guaranteed
* to be up-to-date, when Update() of the ProcessObject or the generated
* DataObject is called immediately before access of the data stored in the
* DataObject. This is also true for subclasses of mitk::BaseProcess and thus
* for mitk::DataNodeSource.
* @ingroup Process
*/
class MITK_CORE_EXPORT DataNodeSource : public itk::ProcessObject
{
public:
mitkClassMacro( DataNodeSource, itk::ProcessObject );
itkNewMacro( Self );
typedef mitk::DataNode OutputType;
typedef OutputType::Pointer OutputTypePointer;
/**
* Allocates a new output object and returns it. Currently the
* index idx is not evaluated.
* @param idx the index of the output for which an object should be created
* @returns the new object
*/
virtual itk::DataObject::Pointer MakeOutput ( unsigned int idx );
/**
* Allows to set the output of the base data source.
* @param output the intended output of the base data source
*/
virtual void SetOutput( OutputType* output );
/**
* Allows to set the n-th output of the base data source.
* @param output the intended output of the base data source
*/
virtual void SetOutput( unsigned int idx, OutputType* output );
/**
* Returns the output with index 0 of the base data source
* @returns the output
*/
virtual OutputType* GetOutput();
/**
* Returns the n'th output of the base data source
* @param idx the index of the wanted output
* @returns the output with index idx.
*/
virtual OutputType* GetOutput ( unsigned int idx );
protected:
DataNodeSource();
virtual ~DataNodeSource();
};
}
#endif // #define _MITK_BASE_DATA_SOURCE_H
diff --git a/Core/Code/Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp b/Core/Code/Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp
index 0a8293c671..ead5ea0395 100644
--- a/Core/Code/Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp
+++ b/Core/Code/Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp
@@ -1,450 +1,449 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGeometry2DDataToSurfaceFilter.h"
#include "mitkSurface.h"
#include "mitkGeometry3D.h"
#include "mitkGeometry2DData.h"
#include "mitkPlaneGeometry.h"
#include "mitkAbstractTransformGeometry.h"
#include <vtkPolyData.h>
#include <vtkPlaneSource.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkCubeSource.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkTransform.h>
#include <vtkGeneralTransform.h>
#include <vtkPlane.h>
#include <vtkPPolyDataNormals.h>
#include <vtkCutter.h>
#include <vtkStripper.h>
#include <vtkTriangleFilter.h>
#include <vtkBox.h>
#include <vtkClipPolyData.h>
#include <vtkTextureMapToPlane.h>
mitk::Geometry2DDataToSurfaceFilter::Geometry2DDataToSurfaceFilter()
: m_UseGeometryParametricBounds( true ), m_XResolution( 10 ),
m_YResolution( 10 ), m_PlaceByGeometry( false ), m_UseBoundingBox( false )
{
m_PlaneSource = vtkPlaneSource::New();
m_Transform = vtkTransform::New();
m_CubeSource = vtkCubeSource::New();
m_PolyDataTransformer = vtkTransformPolyDataFilter::New();
m_Plane = vtkPlane::New();
m_PlaneCutter = vtkCutter::New();
m_PlaneStripper = vtkStripper::New();
m_PlanePolyData = vtkPolyData::New();
m_NormalsUpdater = vtkPPolyDataNormals::New();
m_PlaneTriangler = vtkTriangleFilter::New();
m_TextureMapToPlane = vtkTextureMapToPlane::New();
m_Box = vtkBox::New();
m_PlaneClipper = vtkClipPolyData::New();
m_VtkTransformPlaneFilter = vtkTransformPolyDataFilter::New();
m_VtkTransformPlaneFilter->SetInput( m_PlaneSource->GetOutput() );
}
mitk::Geometry2DDataToSurfaceFilter::~Geometry2DDataToSurfaceFilter()
{
m_PlaneSource->Delete();
m_Transform->Delete();
m_CubeSource->Delete();
m_PolyDataTransformer->Delete();
m_Plane->Delete();
m_PlaneCutter->Delete();
m_PlaneStripper->Delete();
m_PlanePolyData->Delete();
m_NormalsUpdater->Delete();
m_PlaneTriangler->Delete();
m_TextureMapToPlane->Delete();
m_Box->Delete();
m_PlaneClipper->Delete();
m_VtkTransformPlaneFilter->Delete();
}
void mitk::Geometry2DDataToSurfaceFilter::GenerateOutputInformation()
{
mitk::Geometry2DData::ConstPointer input = this->GetInput();
mitk::Surface::Pointer output = this->GetOutput();
if ( input.IsNull() || (input->GetGeometry2D() == NULL)
|| (input->GetGeometry2D()->IsValid() == false)
|| (m_UseBoundingBox && (m_BoundingBox.IsNull() || (m_BoundingBox->GetDiagonalLength2() < mitk::eps))) )
{
return;
}
Point3D origin;
Point3D right, bottom;
vtkPolyData *planeSurface = NULL;
// Does the Geometry2DData contain a PlaneGeometry?
if ( dynamic_cast< PlaneGeometry * >( input->GetGeometry2D() ) != NULL )
{
mitk::PlaneGeometry *planeGeometry =
dynamic_cast< PlaneGeometry * >( input->GetGeometry2D() );
if ( m_PlaceByGeometry )
{
// Let the output use the input geometry to appropriately transform the
// coordinate system.
mitk::AffineGeometryFrame3D::TransformType *affineTransform =
planeGeometry->GetIndexToWorldTransform();
mitk::TimeSlicedGeometry *timeGeometry = output->GetTimeSlicedGeometry();
timeGeometry->SetIndexToWorldTransform( affineTransform );
mitk::Geometry3D *g3d = timeGeometry->GetGeometry3D( 0 );
g3d->SetIndexToWorldTransform( affineTransform );
}
if ( !m_UseBoundingBox)
{
// We do not have a bounding box, so no clipping is required.
if ( m_PlaceByGeometry )
{
// Derive coordinate axes and origin from input geometry extent
origin.Fill( 0.0 );
FillVector3D( right, planeGeometry->GetExtent(0), 0.0, 0.0 );
FillVector3D( bottom, 0.0, planeGeometry->GetExtent(1), 0.0 );
}
else
{
// Take the coordinate axes and origin directly from the input geometry.
origin = planeGeometry->GetOrigin();
right = planeGeometry->GetCornerPoint( false, true );
bottom = planeGeometry->GetCornerPoint( true, false );
}
// Since the plane is planar, there is no need to subdivide the grid
// (cf. AbstractTransformGeometry case)
m_PlaneSource->SetXResolution( 1 );
m_PlaneSource->SetYResolution( 1 );
m_PlaneSource->SetOrigin( origin[0], origin[1], origin[2] );
m_PlaneSource->SetPoint1( right[0], right[1], right[2] );
m_PlaneSource->SetPoint2( bottom[0], bottom[1], bottom[2] );
planeSurface = m_PlaneSource->GetOutput();
planeSurface->Update();
}
else
{
// Set up a cube with the extent and origin of the bounding box. This
// cube will be clipped by a plane later on. The intersection of the
// cube and the plane will be the surface we are interested in. Note
// that the bounding box needs to be explicitly specified by the user
// of this class, since it is not necessarily clear from the data
// available herein which bounding box to use. In most cases, this
// would be the bounding box of the input geometry's reference
// geometry, but this is not an inevitable requirement.
mitk::BoundingBox::PointType boundingBoxMin = m_BoundingBox->GetMinimum();
mitk::BoundingBox::PointType boundingBoxMax = m_BoundingBox->GetMaximum();
mitk::BoundingBox::PointType boundingBoxCenter = m_BoundingBox->GetCenter();
m_CubeSource->SetXLength( boundingBoxMax[0] - boundingBoxMin[0] );
m_CubeSource->SetYLength( boundingBoxMax[1] - boundingBoxMin[1] );
m_CubeSource->SetZLength( boundingBoxMax[2] - boundingBoxMin[2] );
m_CubeSource->SetCenter(
boundingBoxCenter[0],
boundingBoxCenter[1],
boundingBoxCenter[2] );
// Now we have to transform the cube, so that it will cut our plane
// appropriately. (As can be seen below, the plane corresponds to the
// z-plane in the coordinate system and is *not* transformed.) Therefore,
// we get the inverse of the plane geometry's transform and concatenate
// it with the transform of the reference geometry, if available.
m_Transform->Identity();
m_Transform->Concatenate(
planeGeometry->GetVtkTransform()->GetLinearInverse()
);
Geometry3D *referenceGeometry = planeGeometry->GetReferenceGeometry();
if ( referenceGeometry )
{
m_Transform->Concatenate(
referenceGeometry->GetVtkTransform()
);
}
// Transform the cube accordingly (s.a.)
m_PolyDataTransformer->SetInput( m_CubeSource->GetOutput() );
m_PolyDataTransformer->SetTransform( m_Transform );
// Initialize the plane to clip the cube with, as lying on the z-plane
m_Plane->SetOrigin( 0.0, 0.0, 0.0 );
m_Plane->SetNormal( 0.0, 0.0, 1.0 );
// Cut the plane with the cube.
m_PlaneCutter->SetInput( m_PolyDataTransformer->GetOutput() );
m_PlaneCutter->SetCutFunction( m_Plane );
// The output of the cutter must be converted into appropriate poly data.
m_PlaneStripper->SetInput( m_PlaneCutter->GetOutput() );
m_PlaneStripper->Update();
if ( m_PlaneStripper->GetOutput()->GetNumberOfPoints() < 3 )
{
return;
}
m_PlanePolyData->SetPoints( m_PlaneStripper->GetOutput()->GetPoints() );
m_PlanePolyData->SetPolys( m_PlaneStripper->GetOutput()->GetLines() );
m_PlaneTriangler->SetInput( m_PlanePolyData );
// Get bounds of the resulting surface and use it to generate the texture
// mapping information
m_PlaneTriangler->Update();
m_PlaneTriangler->GetOutput()->ComputeBounds();
vtkFloatingPointType *surfaceBounds =
m_PlaneTriangler->GetOutput()->GetBounds();
origin[0] = surfaceBounds[0];
origin[1] = surfaceBounds[2];
origin[2] = surfaceBounds[4];
right[0] = surfaceBounds[1];
right[1] = surfaceBounds[2];
right[2] = surfaceBounds[4];
bottom[0] = surfaceBounds[0];
bottom[1] = surfaceBounds[3];
bottom[2] = surfaceBounds[4];
// Now we tell the data how it shall be textured afterwards;
// description see above.
m_TextureMapToPlane->SetInput( m_PlaneTriangler->GetOutput() );
m_TextureMapToPlane->AutomaticPlaneGenerationOn();
m_TextureMapToPlane->SetOrigin( origin[0], origin[1], origin[2] );
m_TextureMapToPlane->SetPoint1( right[0], right[1], right[2] );
m_TextureMapToPlane->SetPoint2( bottom[0], bottom[1], bottom[2] );
// Need to call update so that output data and bounds are immediately
// available
m_TextureMapToPlane->Update();
// Return the output of this generation process
planeSurface = dynamic_cast< vtkPolyData * >(
m_TextureMapToPlane->GetOutput()
);
}
}
// Does the Geometry2DData contain an AbstractTransformGeometry?
else if ( mitk::AbstractTransformGeometry *abstractGeometry =
dynamic_cast< AbstractTransformGeometry * >( input->GetGeometry2D() ) )
{
// In the case of an AbstractTransformGeometry (which holds a possibly
// non-rigid transform), we proceed slightly differently: since the
// plane can be arbitrarily deformed, we need to transform it by the
// abstract transform before clipping it. The setup for this is partially
// done in the constructor.
origin = abstractGeometry->GetPlane()->GetOrigin();
right = origin + abstractGeometry->GetPlane()->GetAxisVector( 0 );
bottom = origin + abstractGeometry->GetPlane()->GetAxisVector( 1 );
// Define the plane
m_PlaneSource->SetOrigin( origin[0], origin[1], origin[2] );
m_PlaneSource->SetPoint1( right[0], right[1], right[2] );
m_PlaneSource->SetPoint2( bottom[0], bottom[1], bottom[2] );
// Set the plane's resolution (unlike for non-deformable planes, the plane
// grid needs to have a certain resolution so that the deformation has the
// desired effect).
if ( m_UseGeometryParametricBounds )
{
m_PlaneSource->SetXResolution(
(int)abstractGeometry->GetParametricExtent(0)
);
m_PlaneSource->SetYResolution(
(int)abstractGeometry->GetParametricExtent(1)
);
}
else
{
m_PlaneSource->SetXResolution( m_XResolution );
m_PlaneSource->SetYResolution( m_YResolution );
}
if ( m_PlaceByGeometry )
{
// Let the output use the input geometry to appropriately transform the
// coordinate system.
mitk::AffineGeometryFrame3D::TransformType *affineTransform =
abstractGeometry->GetIndexToWorldTransform();
mitk::TimeSlicedGeometry *timeGeometry = output->GetTimeSlicedGeometry();
timeGeometry->SetIndexToWorldTransform( affineTransform );
mitk::Geometry3D *g3d = timeGeometry->GetGeometry3D( 0 );
g3d->SetIndexToWorldTransform( affineTransform );
vtkGeneralTransform *composedResliceTransform = vtkGeneralTransform::New();
composedResliceTransform->Identity();
composedResliceTransform->Concatenate(
abstractGeometry->GetVtkTransform()->GetLinearInverse() );
composedResliceTransform->Concatenate(
abstractGeometry->GetVtkAbstractTransform()
);
// Use the non-rigid transform for transforming the plane.
m_VtkTransformPlaneFilter->SetTransform(
composedResliceTransform
);
}
else
{
// Use the non-rigid transform for transforming the plane.
m_VtkTransformPlaneFilter->SetTransform(
abstractGeometry->GetVtkAbstractTransform()
);
}
if ( m_UseBoundingBox )
{
mitk::BoundingBox::PointType boundingBoxMin = m_BoundingBox->GetMinimum();
mitk::BoundingBox::PointType boundingBoxMax = m_BoundingBox->GetMaximum();
//mitk::BoundingBox::PointType boundingBoxCenter = m_BoundingBox->GetCenter();
m_Box->SetXMin( boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2] );
m_Box->SetXMax( boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2] );
}
else
{
// Plane will not be clipped
m_Box->SetXMin( -10000.0, -10000.0, -10000.0 );
m_Box->SetXMax( 10000.0, 10000.0, 10000.0 );
}
m_Transform->Identity();
m_Transform->Concatenate( input->GetGeometry2D()->GetVtkTransform() );
m_Transform->PreMultiply();
m_Box->SetTransform( m_Transform );
m_PlaneClipper->SetInput( m_VtkTransformPlaneFilter->GetOutput() );
m_PlaneClipper->SetClipFunction( m_Box );
m_PlaneClipper->GenerateClippedOutputOff(); // important to NOT generate normals data for clipped part
m_PlaneClipper->InsideOutOn();
m_PlaneClipper->SetValue( 0.0 );
planeSurface = m_PlaneClipper->GetOutput();
}
m_NormalsUpdater->SetInput( planeSurface );
m_NormalsUpdater->AutoOrientNormalsOn(); // that's the trick! Brings consistency between
// normals direction and front/back faces direction (see bug 1440)
m_NormalsUpdater->ComputePointNormalsOn();
m_NormalsUpdater->Update();
output->SetVtkPolyData( m_NormalsUpdater->GetOutput() );
output->CalculateBoundingBox();
}
void mitk::Geometry2DDataToSurfaceFilter::GenerateData()
{
mitk::Surface::Pointer output = this->GetOutput();
if (output.IsNull()) return;
if (output->GetVtkPolyData()==NULL) return;
output->GetVtkPolyData()->Update();
}
const mitk::Geometry2DData *mitk::Geometry2DDataToSurfaceFilter::GetInput()
{
if (this->GetNumberOfInputs() < 1)
{
return 0;
}
return static_cast<const mitk::Geometry2DData * >
( this->ProcessObject::GetInput(0) );
}
const mitk::Geometry2DData *
mitk::Geometry2DDataToSurfaceFilter
::GetInput(unsigned int idx)
{
return static_cast< const mitk::Geometry2DData * >
( this->ProcessObject::GetInput(idx) );
}
void
mitk::Geometry2DDataToSurfaceFilter
::SetInput(const mitk::Geometry2DData *input)
{
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput( 0,
const_cast< mitk::Geometry2DData * >( input )
);
}
void
mitk::Geometry2DDataToSurfaceFilter
::SetInput(unsigned int index, const mitk::Geometry2DData *input)
{
if( index+1 > this->GetNumberOfInputs() )
{
this->SetNumberOfRequiredInputs( index + 1 );
}
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput(index,
const_cast< mitk::Geometry2DData *>( input )
);
}
void
mitk::Geometry2DDataToSurfaceFilter
::SetBoundingBox( const mitk::BoundingBox *boundingBox )
{
m_BoundingBox = boundingBox;
this->UseBoundingBoxOn();
}
const mitk::BoundingBox *
mitk::Geometry2DDataToSurfaceFilter
::GetBoundingBox() const
{
return m_BoundingBox.GetPointer();
}
diff --git a/Core/Code/Algorithms/mitkGeometry2DDataToSurfaceFilter.h b/Core/Code/Algorithms/mitkGeometry2DDataToSurfaceFilter.h
index 30d171c0b4..9186c1a506 100644
--- a/Core/Code/Algorithms/mitkGeometry2DDataToSurfaceFilter.h
+++ b/Core/Code/Algorithms/mitkGeometry2DDataToSurfaceFilter.h
@@ -1,227 +1,226 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGEOMETRY2DDATATOSURFACEDATAFILTER_H_HEADER_INCLUDED_C10B22CD
#define MITKGEOMETRY2DDATATOSURFACEDATAFILTER_H_HEADER_INCLUDED_C10B22CD
#include "mitkSurfaceSource.h"
#include "mitkGeometry3D.h"
#include "vtkSystemIncludes.h"
class vtkPlaneSource;
class vtkTransformPolyDataFilter;
class vtkCubeSource;
class vtkTransform;
class vtkPlane;
class vtkCutter;
class vtkStripper;
class vtkPolyData;
class vtkPPolyDataNormals;
class vtkTriangleFilter;
class vtkTextureMapToPlane;
class vtkBox;
class vtkClipPolyData;
namespace mitk {
class Geometry2DData;
/** \brief Superclass of all classes having a Geometry2DData as input and
* generating Images as output
*
* Currently implemented for PlaneGeometry and AbstractTransformGeometry.
* Currently, this class does not really have subclasses, but does the job
* for itself. It checks which kind of Geometry2D is stored in the
* Geometry2DData and - if it knows how - it generates the respective
* Surface. Of course, this has the disadvantage that for any new type of
* Geometry2D this class (Geometry2DDataToSurfaceFilter) has to be
* changed/extended. The idea is to move the type specific generation code in
* subclasses, and internally (within this class) use a factory to create an
* instance of the required subclass and delegate the surface generation to
* it.
*
* \sa mitk::DeformablePlane
* \todo make extension easier
* \ingroup Process
*/
class MITK_CORE_EXPORT Geometry2DDataToSurfaceFilter : public SurfaceSource
{
public:
mitkClassMacro(Geometry2DDataToSurfaceFilter, SurfaceSource);
itkNewMacro(Self);
virtual void GenerateOutputInformation();
virtual void GenerateData();
const Geometry2DData *GetInput(void);
const Geometry2DData *GetInput(unsigned int idx);
virtual void SetInput(const Geometry2DData *image);
virtual void SetInput(unsigned int index, const Geometry2DData *image);
/** \brief If \a true (default), use Geometry3D::GetParametricBounds() to define the resolution in parameter space,
* otherwise use m_XResolution and m_YResolution
*/
itkGetMacro(UseGeometryParametricBounds, bool);
/** \brief If \a true (default), use Geometry3D::GetParametricBounds() to define the resolution in parameter space,
* otherwise use m_XResolution and m_YResolution
*/
itkSetMacro(UseGeometryParametricBounds, bool);
/** \brief Get x-resolution in parameter space
*
* The m_PlaneSource will create this many sub-rectangles
* in x-direction (see vtkPlaneSource::SetXResolution)
* \note Only used, when GetUseGeometryParametricBounds() is \a false, otherwise the
* the x-bounds of Geometry3D::GetParametricBounds() are used.
* \sa m_XResolution
*/
itkGetMacro(XResolution, int);
/** \brief Set x-resolution in parameter space
*
* The m_PlaneSource will create this many sub-rectangles
* in x-direction (see vtkPlaneSource::SetXResolution)
* \note Only used, when GetUseGeometryParametricBounds() is \a false, otherwise the
* the x-bounds of Geometry3D::GetParametricBounds() are used.
* \sa m_XResolution
*/
itkSetMacro(XResolution, int);
/** \brief Get y-resolution in parameter space
*
* The m_PlaneSource will create this many sub-rectangles
* in y-direction (see vtkPlaneSource::SetYResolution)
* \note Only used, when GetUseGeometryParametricBounds() is \a false, otherwise the
* the y-bounds of Geometry3D::GetParametricBounds() are used.
* \sa m_YResolution
*/
itkGetMacro(YResolution, int);
/** \brief Set y-resolution in parameter space
*
* The m_PlaneSource will create this many sub-rectangles
* in y-direction (see vtkPlaneSource::SetYResolution)
* \note Only used, when GetUseGeometryParametricBounds() is \a false, otherwise the
* the y-bounds of Geometry3D::GetParametricBounds() are used.
* \sa m_YResolution
*/
itkSetMacro(YResolution, int);
/** \brief Get whether the Surface is at the origin and placed using the Geometry
*
* Default is \a false, i.e., the transform of the Geometry is the identity, thus
* the points within the Surface are at their final position. Otherwise
* (m_PlaceByGeometry==\a true), the first cornerpoint of the created Surface is
* at the origin and the actual position is determined by the transform of the
* Geometry.
* \sa m_PlaceByGeometry
*/
itkGetConstMacro(PlaceByGeometry, bool);
/** \brief Set whether the Surface is at the origin and placed using the Geometry
*
* Default is \a false, i.e., the transform of the Geometry is the identity, thus
* the points within the Surface are at their final position. Otherwise
* (m_PlaceByGeometry==\a true), the first cornerpoint of the created Surface is
* at the origin and the actual position is determined by the transform of the
* Geometry.
* \sa m_PlaceByGeometry
*/
itkSetMacro(PlaceByGeometry, bool);
itkBooleanMacro(PlaceByGeometry);
itkGetConstMacro( UseBoundingBox, bool );
itkSetMacro( UseBoundingBox, bool );
itkBooleanMacro( UseBoundingBox );
void SetBoundingBox( const BoundingBox *boundingBox );
const BoundingBox *GetBoundingBox() const;
protected:
Geometry2DDataToSurfaceFilter();
virtual ~Geometry2DDataToSurfaceFilter();
/** \brief Source to create the vtk-representation of the parameter space rectangle of the Geometry2D
*/
vtkPlaneSource* m_PlaneSource;
/** \brief Filter to create the vtk-representation of the Geometry2D, which is a
* transformation of the m_PlaneSource
*/
vtkTransformPolyDataFilter* m_VtkTransformPlaneFilter;
/** \brief If \a true, use Geometry3D::GetParametricBounds() to define the resolution in parameter space,
* otherwise use m_XResolution and m_YResolution
*/
bool m_UseGeometryParametricBounds;
/** \brief X-resolution in parameter space
*
* The m_PlaneSource will create this many sub-rectangles
* in x-direction (see vtkPlaneSource::SetXResolution)
* \note Only used, when GetUseGeometryParametricBounds() is \a false, otherwise the
* the x-bounds of Geometry3D::GetParametricBounds() are used.
* \sa m_XResolution
*/
int m_XResolution;
/** \brief Y-resolution in parameter space
*
* The m_PlaneSource will create this many sub-rectangles
* in y-direction (see vtkPlaneSource::SetYResolution)
* \note Only used, when GetUseGeometryParametricBounds() is \a false, otherwise the
* the y-bounds of Geometry3D::GetParametricBounds() are used.
*/
int m_YResolution;
/** \brief Define whether the Surface is at the origin and placed using the Geometry
*
* Default is \a false, i.e., the transform of the Geometry is the identity, thus
* the points within the Surface are at their final position. Otherwise
* (m_PlaceByGeometry==\a true), the first cornerpoint of the created Surface is
* at the origin and the actual position is determined by the transform of the
* Geometry.
*/
bool m_PlaceByGeometry;
bool m_UseBoundingBox;
BoundingBox::ConstPointer m_BoundingBox;
vtkCubeSource *m_CubeSource;
vtkTransform *m_Transform;
vtkTransformPolyDataFilter *m_PolyDataTransformer;
vtkPlane *m_Plane;
vtkCutter *m_PlaneCutter;
vtkStripper *m_PlaneStripper;
vtkPolyData *m_PlanePolyData;
vtkPPolyDataNormals * m_NormalsUpdater;
vtkTriangleFilter *m_PlaneTriangler;
vtkTextureMapToPlane *m_TextureMapToPlane;
vtkBox *m_Box;
vtkClipPolyData *m_PlaneClipper;
};
} // namespace mitk
#endif /* MITKGEOMETRY2DDATATOSURFACEDATAFILTER_H_HEADER_INCLUDED_C10B22CD */
diff --git a/Core/Code/Algorithms/mitkHistogramGenerator.cpp b/Core/Code/Algorithms/mitkHistogramGenerator.cpp
index 5fb63242ae..c5666e5848 100644
--- a/Core/Code/Algorithms/mitkHistogramGenerator.cpp
+++ b/Core/Code/Algorithms/mitkHistogramGenerator.cpp
@@ -1,127 +1,126 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#if(_MSC_VER==1200)
#include <itkFixedCenterOfRotationAffineTransform.h>
#endif
#include "mitkHistogramGenerator.h"
#include "mitkImageTimeSelector.h"
#include "mitkImageAccessByItk.h"
//
// The new ITK Statistics framework has
// a class with the same functionality as
// MITKScalarImageToHistogramGenerator.h, but
// no longer has the classis the MITK class depends on.
#if !defined(ITK_USE_REVIEW_STATISTICS)
#include "itkMITKScalarImageToHistogramGenerator.h"
#else
#include "itkScalarImageToHistogramGenerator.h"
#endif
mitk::HistogramGenerator::HistogramGenerator() : m_Image(NULL), m_Size(256), m_Histogram(NULL)
{
}
mitk::HistogramGenerator::~HistogramGenerator()
{
}
template < typename TPixel, unsigned int VImageDimension >
void InternalCompute(itk::Image< TPixel, VImageDimension >* itkImage, const mitk::HistogramGenerator* mitkHistoGenerator, mitk::HistogramGenerator::HistogramType::ConstPointer& histogram)
{
#if !defined(ITK_USE_REVIEW_STATISTICS)
typedef itk::Statistics::MITKScalarImageToHistogramGenerator<
itk::Image< TPixel, VImageDimension >,
double > HistogramGeneratorType;
#else
typedef itk::Statistics::ScalarImageToHistogramGenerator< itk::Image< TPixel, VImageDimension > >
HistogramGeneratorType;
#endif
typename HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New();
histogramGenerator->SetInput( itkImage );
histogramGenerator->SetNumberOfBins( mitkHistoGenerator->GetSize() );
// histogramGenerator->SetMarginalScale( 10.0 );
histogramGenerator->Compute();
histogram = histogramGenerator->GetOutput();
}
void mitk::HistogramGenerator::ComputeHistogram()
{
if((m_Histogram.IsNull()) || (m_Histogram->GetMTime() < m_Image->GetMTime()))
{
const_cast<mitk::Image*>(m_Image.GetPointer())->SetRequestedRegionToLargestPossibleRegion(); //@todo without this, Image::GetScalarMin does not work for dim==3 (including sliceselector!)
const_cast<mitk::Image*>(m_Image.GetPointer())->Update();
mitk::ImageTimeSelector::Pointer timeSelector=mitk::ImageTimeSelector::New();
timeSelector->SetInput(m_Image);
timeSelector->SetTimeNr( 0 );
timeSelector->UpdateLargestPossibleRegion();
AccessByItk_n( timeSelector->GetOutput() , InternalCompute, (this, m_Histogram));
}
// debug code
/*
MITK_INFO << "Histogram modfied 1" << m_Histogram->GetMTime() << std::endl;
m_Histogram->Modified();
MITK_INFO << "Histogram modfied 2" << m_Histogram->GetMTime() << std::endl;
MITK_INFO << "Image modfied" << m_Image->GetMTime() << std::endl;
const unsigned int histogramSize = m_Histogram->Size();
MITK_INFO << "Histogram size " << histogramSize << std::endl;
HistogramType::ConstIterator itr = GetHistogram()->Begin();
HistogramType::ConstIterator end = GetHistogram()->End();
int bin = 0;
while( itr != end )
{
MITK_INFO << "bin = " << GetHistogram()->GetBinMin(0,bin) << "--" << GetHistogram()->GetBinMax(0,bin) << " frequency = ";
MITK_INFO << itr.GetFrequency() << std::endl;
++itr;
++bin;
}
*/
}
float mitk::HistogramGenerator::GetMaximumFrequency() const {
return CalculateMaximumFrequency(this->m_Histogram);
};
float mitk::HistogramGenerator::CalculateMaximumFrequency(const HistogramType* histogram)
{
HistogramType::ConstIterator itr = histogram->Begin();
HistogramType::ConstIterator end = histogram->End();
float maxFreq = 0;
while( itr != end )
{
maxFreq = vnl_math_max(maxFreq,
// get rid of ambiguity with type signature
// for vnl_math_max
static_cast<float>(itr.GetFrequency()));
++itr;
}
return maxFreq;
};
diff --git a/Core/Code/Algorithms/mitkHistogramGenerator.h b/Core/Code/Algorithms/mitkHistogramGenerator.h
index 1faad9c04d..191e59e576 100644
--- a/Core/Code/Algorithms/mitkHistogramGenerator.h
+++ b/Core/Code/Algorithms/mitkHistogramGenerator.h
@@ -1,60 +1,59 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 HISTOGRAM_GENERATOR_H_HEADER_INCLUDED
#define HISTOGRAM_GENERATOR_H_HEADER_INCLUDED
#include <itkObject.h>
#include <itkHistogram.h>
#include <itkImage.h>
#include "mitkImage.h"
namespace mitk {
//##Documentation
//## @brief Provides an easy way to calculate an itk::Histogram for a mitk::Image
//##
class MITK_CORE_EXPORT HistogramGenerator : public itk::Object
{
public:
mitkClassMacro(HistogramGenerator,itk::Object);
itkNewMacro(Self);
typedef itk::Statistics::Histogram<double> HistogramType;
itkSetMacro(Image,mitk::Image::ConstPointer);
itkSetMacro(Size,int);
itkGetConstMacro(Size,int);
itkGetConstObjectMacro(Histogram,HistogramType);
// TODO: calculate if needed in GetHistogram()
void ComputeHistogram();
float GetMaximumFrequency() const;
static float CalculateMaximumFrequency(const HistogramType* histogram);
protected:
HistogramGenerator();
virtual ~HistogramGenerator();
mitk::Image::ConstPointer m_Image;
int m_Size;
HistogramType::ConstPointer m_Histogram;
};
} // namespace mitk
#endif /* HISTOGRAM_GENERATOR_H_HEADER_INCLUDED */
diff --git a/Core/Code/Algorithms/mitkITKImageImport.h b/Core/Code/Algorithms/mitkITKImageImport.h
index 99c43f9d10..823ad89a45 100644
--- a/Core/Code/Algorithms/mitkITKImageImport.h
+++ b/Core/Code/Algorithms/mitkITKImageImport.h
@@ -1,178 +1,177 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKITKIMAGEIMPORT_H_HEADER_INCLUDED_C1E4861D
#define MITKITKIMAGEIMPORT_H_HEADER_INCLUDED_C1E4861D
#include <MitkExports.h>
#include "mitkImageSource.h"
#include "itkImageToImageFilterDetail.h"
namespace mitk {
//##Documentation
//## @brief Pipelined import of itk::Image
//##
//## The image data contained in the itk::Image is referenced,
//## not copied.
//## The easiest way of use is by the function
//## mitk::ImportItkImage
//## \code
//## mitkImage = mitk::ImportItkImage(itkImage);
//## \endcode
//## \sa ImportItkImage
//## @ingroup Adaptor
template <class TInputImage>
class MITK_EXPORT ITKImageImport : public ImageSource
{
public:
mitkClassMacro(ITKImageImport,ImageSource);
itkNewMacro(Self);
//##Documentation
//## \brief The type of the input image.
typedef TInputImage InputImageType;
typedef typename InputImageType::Pointer InputImagePointer;
typedef typename InputImageType::ConstPointer InputImageConstPointer;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename InputImageType::PixelType InputImagePixelType;
/** ImageDimension constants */
itkStaticConstMacro(InputImageDimension, unsigned int,
TInputImage::ImageDimension);
itkStaticConstMacro(RegionDimension, unsigned int,
mitk::SlicedData::RegionDimension);
//##Documentation
//## \brief Set the input itk::Image of this image importer.
InputImageType * GetInput(void);
//##Documentation
//## \brief Set the input itk::Image of this image importer.
void SetInput(const InputImageType*);
//##Documentation
//## \brief Set the Geometry of the result image (optional)
//##
//## The Geometry has to fit the dimension and size of
//## the input image. The Geometry will be cloned, not
//## referenced!
//##
//## Providing the Geometry is optional.
//## The default behavior is to set the geometry by
//## the itk::Image::GetDirection() information.
void SetGeometry(const Geometry3D* geometry);
protected:
ITKImageImport();
virtual ~ITKImageImport();
virtual void GenerateOutputInformation();
virtual void GenerateInputRequestedRegion();
virtual void GenerateData();
virtual void SetNthOutput(unsigned int num, itk::DataObject *output);
/** Typedef for the region copier function object that converts an
* output region to an input region. */
typedef itk::ImageToImageFilterDetail::ImageRegionCopier<itkGetStaticConstMacro(InputImageDimension),
itkGetStaticConstMacro(RegionDimension)> OutputToInputRegionCopierType;
Geometry3D::Pointer m_Geometry;
};
//##Documentation
//## @brief Imports an itk::Image (with a specific type) as an mitk::Image.
//## @ingroup Adaptor
//##
//## Instantiates instance of ITKImageImport.
//## mitk::ITKImageImport does not cast pixel types etc., it just imports
//## image data. If you get a compile error, try image.GetPointer().
//##
//## \param update: if \a true, fill mitk::Image, which will execute the
//## up-stream pipeline connected to the input itk::Image. Otherwise you
//## need to make sure that Update() is called on the mitk::Image before
//## its data is being used, e.g., by connecting it to an mitk-pipeline
//## and call Update of a downstream filter at some time.
//## \sa itk::Image::CastToMitkImage
template <typename ItkOutputImageType>
Image::Pointer ImportItkImage(const itk::SmartPointer<ItkOutputImageType>& itkimage, const Geometry3D* geometry = NULL, bool update = true);
//##Documentation
//## @brief Imports an itk::Image (with a specific type) as an mitk::Image.
//## @ingroup Adaptor
//##
//## Instantiates instance of ITKImageImport
//## mitk::ITKImageImport does not cast pixel types etc., it just imports
//## image data. If you get a compile error, try image.GetPointer().
//##
//## \param update: if \a true, fill mitk::Image, which will execute the
//## up-stream pipeline connected to the input itk::Image. Otherwise you
//## need to make sure that Update() is called on the mitk::Image before
//## its data is being used, e.g., by connecting it to an mitk-pipeline
//## and call Update of a downstream filter at some time.
//## \sa itk::Image::CastToMitkImage
//## \sa GrabItkImageMemory
template <typename ItkOutputImageType>
Image::Pointer ImportItkImage(const ItkOutputImageType* itkimage, const Geometry3D* geometry = NULL, bool update = true);
//##Documentation
//## @brief Grabs the memory of an itk::Image (with a specific type)
//## and puts it into an mitk::Image.
//## @ingroup Adaptor
//##
//## The memory is managed by the mitk::Image after calling this
//## function. The itk::Image remains valid until the mitk::Image
//## decides to free the memory.
//## \param update: if \a true, fill mitk::Image, which will execute the
//## up-stream pipeline connected to the input itk::Image. Otherwise you
//## need to make sure that Update() is called on the mitk::Image before
//## its data is being used, e.g., by connecting it to an mitk-pipeline
//## and call Update of a downstream filter at some time.
//## \sa ImportItkImage
template <typename ItkOutputImageType>
Image::Pointer GrabItkImageMemory(itk::SmartPointer<ItkOutputImageType>& itkimage, mitk::Image* mitkImage = NULL, const Geometry3D* geometry = NULL, bool update = true);
//##Documentation
//## @brief Grabs the memory of an itk::Image (with a specific type)
//## and puts it into an mitk::Image.
//## @ingroup Adaptor
//##
//## The memory is managed by the mitk::Image after calling this
//## function. The itk::Image remains valid until the mitk::Image
//## decides to free the memory.
//## \param update: if \a true, fill mitk::Image, which will execute the
//## up-stream pipeline connected to the input itk::Image. Otherwise you
//## need to make sure that Update() is called on the mitk::Image before
//## its data is being used, e.g., by connecting it to an mitk-pipeline
//## and call Update of a downstream filter at some time.
//## \sa ImportItkImage
template <typename ItkOutputImageType>
Image::Pointer GrabItkImageMemory(ItkOutputImageType* itkimage, mitk::Image* mitkImage = NULL, const Geometry3D* geometry = NULL, bool update = true);
} // namespace mitk
#ifndef MITK_MANUAL_INSTANTIATION
#include "mitkITKImageImport.txx"
#endif
#endif /* MITKITKIMAGEIMPORT_H_HEADER_INCLUDED_C1E4861D */
diff --git a/Core/Code/Algorithms/mitkITKImageImport.txx b/Core/Code/Algorithms/mitkITKImageImport.txx
index aa7ea6b565..bbc66d911f 100644
--- a/Core/Code/Algorithms/mitkITKImageImport.txx
+++ b/Core/Code/Algorithms/mitkITKImageImport.txx
@@ -1,178 +1,177 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkITKImageImport_txx
#define __mitkITKImageImport_txx
#include "mitkITKImageImport.h"
template <class TInputImage>
mitk::ITKImageImport<TInputImage>::ITKImageImport()
{
}
template <class TInputImage>
mitk::ITKImageImport<TInputImage>::~ITKImageImport()
{
}
template <class TInputImage>
typename mitk::ITKImageImport<TInputImage>::InputImageType *
mitk::ITKImageImport<TInputImage>::GetInput(void)
{
return static_cast<TInputImage*>(
this->ProcessObject::GetInput(0));
}
template <class TInputImage>
void mitk::ITKImageImport<TInputImage>::SetInput(const InputImageType* input)
{
this->ProcessObject::SetNthInput(0, const_cast<TInputImage*>(input) );
}
template <class TInputImage>
void mitk::ITKImageImport<TInputImage>::SetGeometry(const Geometry3D* geometry)
{
if(geometry != NULL)
{
m_Geometry = static_cast<mitk::Geometry3D*>(geometry->Clone().GetPointer());
}
else
{
m_Geometry = NULL;
}
Modified();
}
template <class TInputImage>
void mitk::ITKImageImport<TInputImage>::GenerateOutputInformation()
{
InputImageConstPointer input = this->GetInput();
mitk::Image::Pointer output = this->GetOutput();
itkDebugMacro(<<"GenerateOutputInformation()");
output->InitializeByItk(input.GetPointer());
if(m_Geometry.IsNotNull())
{
output->SetGeometry(m_Geometry);
}
}
template <class TInputImage>
void mitk::ITKImageImport<TInputImage>::GenerateData()
{
InputImageConstPointer input = this->GetInput();
mitk::Image::Pointer output = this->GetOutput();
output->SetImportChannel((void*)input->GetBufferPointer(), 0, mitk::Image::ReferenceMemory);
}
template <class TInputImage>
void mitk::ITKImageImport<TInputImage>::GenerateInputRequestedRegion()
{
Superclass::GenerateInputRequestedRegion();
// Input is an image, cast away the constness so we can set
// the requested region.
InputImagePointer input =
const_cast< TInputImage * > ( this->GetInput() );
// Use the function object RegionCopier to copy the output region
// to the input. The default region copier has default implementations
// to handle the cases where the input and output are the same
// dimension, the input a higher dimension than the output, and the
// input a lower dimension than the output.
InputImageRegionType inputRegion;
OutputToInputRegionCopierType regionCopier;
regionCopier(inputRegion, this->GetOutput()->GetRequestedRegion());
input->SetRequestedRegion( inputRegion );
}
template <class TInputImage>
void mitk::ITKImageImport<TInputImage>::SetNthOutput(unsigned int idx, itk::DataObject *output)
{
if((output == NULL) && (idx == 0))
{
// we are disconnected from our output:
// copy buffer of input to output, because we
// cannot guarantee that the input (to which our
// output is refering) will stay alive.
InputImageConstPointer input = this->GetInput();
mitk::Image::Pointer currentOutput = this->GetOutput();
if(input.IsNotNull() && currentOutput.IsNotNull())
currentOutput->SetChannel(input->GetBufferPointer());
}
Superclass::SetNthOutput(idx, output);
}
template <typename ItkOutputImageType>
mitk::Image::Pointer mitk::ImportItkImage(const itk::SmartPointer<ItkOutputImageType>& itkimage, const Geometry3D* geometry, bool update)
{
typename mitk::ITKImageImport<ItkOutputImageType>::Pointer importer = mitk::ITKImageImport<ItkOutputImageType>::New();
importer->SetInput(itkimage);
importer->SetGeometry(geometry);
if(update)
importer->Update();
return importer->GetOutput();
}
template <typename ItkOutputImageType>
mitk::Image::Pointer mitk::ImportItkImage(const ItkOutputImageType* itkimage, const Geometry3D* geometry, bool update)
{
typename mitk::ITKImageImport<ItkOutputImageType>::Pointer importer = mitk::ITKImageImport<ItkOutputImageType>::New();
importer->SetInput(itkimage);
importer->SetGeometry(geometry);
if(update)
importer->Update();
return importer->GetOutput();
}
template <typename ItkOutputImageType>
mitk::Image::Pointer mitk::GrabItkImageMemory(itk::SmartPointer<ItkOutputImageType>& itkimage, mitk::Image* mitkImage, const Geometry3D* geometry, bool update)
{
return GrabItkImageMemory( itkimage.GetPointer(), mitkImage, geometry, update );
}
template <typename ItkOutputImageType>
mitk::Image::Pointer mitk::GrabItkImageMemory(ItkOutputImageType* itkimage, mitk::Image* mitkImage, const Geometry3D* geometry, bool update)
{
if(update)
itkimage->Update();
mitk::Image::Pointer resultImage;
if(mitkImage != NULL)
{
resultImage = mitkImage;
}
else
{
resultImage = mitk::Image::New();
}
resultImage->InitializeByItk( itkimage );
resultImage->SetImportVolume( itkimage->GetBufferPointer(), 0, 0,
Image::ManageMemory );
itkimage->GetPixelContainer()->ContainerManageMemoryOff();
if(geometry != NULL)
resultImage->SetGeometry(static_cast<mitk::Geometry3D*>(geometry->Clone().GetPointer()));
return resultImage;
}
#endif //__mitkITKImageImport_txx
diff --git a/Core/Code/Algorithms/mitkImageAccessByItk.h b/Core/Code/Algorithms/mitkImageAccessByItk.h
index f55ed96b4d..8fc5ae80ca 100644
--- a/Core/Code/Algorithms/mitkImageAccessByItk.h
+++ b/Core/Code/Algorithms/mitkImageAccessByItk.h
@@ -1,620 +1,619 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 <itkCastImageFilter.h>
#include <mitkImageToItk.h>
#include <mitkPPArgCount.h>
#include <mitkPPSeqForEach.h>
#include <mitkPPSeqForEachProduct.h>
#include <mitkPPSeqToTuple.h>
#include <mitkPPCat.h>
#include <mitkPPExpand.h>
#include <mitkPPTupleRem.h>
#include <mitkPPStringize.h>
#include <sstream>
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<pixeltype, dimension> ImageType; \
typedef mitk::ImageToItk<ImageType> ImageToItkType; \
itk::SmartPointer<ImageToItkType> 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<pixeltype, dimension> ImageType; \
typedef mitk::ImageToItk<ImageType> ImageToItkType; \
itk::SmartPointer<ImageToItkType> 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<TPixel, VImageDimension>* 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<mitk::Image*>(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<TPixel, VImageDimension>* 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<mitk::Image*>(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) && \
constImage1->GetDimension() == dim1 && constImage2->GetDimension() == dim2) \
{ \
typedef itk::Image<pixeltype1,dim1> ImageType1; \
typedef itk::Image<pixeltype2,dim2> ImageType2; \
typedef mitk::ImageToItk<ImageType1> ImageToItkType1; \
typedef mitk::ImageToItk<ImageType2> ImageToItkType2; \
itk::SmartPointer<ImageToItkType1> imagetoitk1 = ImageToItkType1::New(); \
imagetoitk1->SetInput(constImage1); \
imagetoitk1->Update(); \
itk::SmartPointer<ImageToItkType2> 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 <typename TPixel1, unsigned int VImageDimension1, typename TPixel2, unsigned int VImageDimension2>
* void ExampleFunctionTwoImages(itk::Image<TPixel1, VImageDimension1>* itkImage1, itk::Image<TPixel2, VImageDimension2>* itkImage2);
* \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* inputMitkImage1 = ...
* mitk::Image* inputMitkImage2 = ...
* try
* {
* AccessTwoImagesFixedDimensionByItk(inputMitkImage1, inputMitkImage2, ExampleFunctionTwoImages, 3);
* }
* catch (const mitk::AccessByItkException& e)
* {
* // mitk::Image arguments are of wrong pixel type or dimension,
* // insert error handling here
* }
* \endcode
*
* \note If your inputMitkImage1 or inputMitkImage2 is a mitk::Image::Pointer, use
* inputMitkImage1.GetPointer().
*
* \param mitkImage1 The first MITK input image.
* \param mitkImage1 The second MITK input image.
* \param itkImageTypeFunction The name of the template access-function to be called.
* \param dimension Dimension of the two mitk-images.
*
* \throws mitk::AccessByItkException If mitkImage1 and mitkImage2 have different dimensions or
* one of the images is of unsupported pixel type or dimension.
*
* \sa #AccessByItk
*
* \ingroup Adaptor
*/
#define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension) \
{ \
const mitk::PixelType& pixelType1 = mitkImage1->GetPixelType(); \
const mitk::PixelType& pixelType2 = mitkImage2->GetPixelType(); \
const mitk::Image* constImage1 = mitkImage1; \
const mitk::Image* constImage2 = mitkImage2; \
const_cast<mitk::Image*>(constImage1)->Update(); \
const_cast<mitk::Image*>(constImage2)->Update(); \
_checkSpecificDimension(mitkImage1, (dimension)); \
_checkSpecificDimension(mitkImage2, (dimension)); \
_accessTwoImagesByItkForEach(itkImageTypeFunction, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension), MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension)) \
{ \
std::string msg("Pixel type "); \
msg.append(pixelType1.GetComponentTypeAsString() ); \
msg.append(" or pixel type "); \
msg.append(pixelType2.GetComponentTypeAsString() ); \
msg.append(" is not in " MITK_PP_STRINGIZE(MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension))); \
throw mitk::AccessByItkException(msg); \
} \
}
#endif // of MITKIMAGEACCESSBYITK_H_HEADER_INCLUDED
diff --git a/Core/Code/Algorithms/mitkImageCast.h b/Core/Code/Algorithms/mitkImageCast.h
index 9ebcc15377..ce996c193e 100644
--- a/Core/Code/Algorithms/mitkImageCast.h
+++ b/Core/Code/Algorithms/mitkImageCast.h
@@ -1,41 +1,40 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKIMAGECAST_H_HEADER_INCLUDED
#define MITKIMAGECAST_H_HEADER_INCLUDED
#include <MitkExports.h>
#include <mitkImage.h>
#include <itkImage.h>
namespace mitk
{
#ifndef DOXYGEN_SKIP
template < typename TPixel, unsigned int VImageDimension, class ItkOutputImageType >
void _CastToItkImage2Access( itk::Image<TPixel, VImageDimension>* itkInputImage, itk::SmartPointer<ItkOutputImageType>& itkOutputImage);
#endif //DOXYGEN_SKIP
//##Documentation
//## @brief Cast an mitk::Image to an itk::Image with a specific type. You don't have to initialize the itk::Image<..>::Pointer.
//## @ingroup Adaptor
template <typename ItkOutputImageType> extern void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer<ItkOutputImageType>& itkOutputImage);
}
#endif // of MITKIMAGECAST_H_HEADER_INCLUDED
diff --git a/Core/Code/Algorithms/mitkImageCastPart1.cpp b/Core/Code/Algorithms/mitkImageCastPart1.cpp
index 6fe18466b8..043009fb98 100644
--- a/Core/Code/Algorithms/mitkImageCastPart1.cpp
+++ b/Core/Code/Algorithms/mitkImageCastPart1.cpp
@@ -1,54 +1,53 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkConfig.h>
#include <mitkImageCast.h>
#include <mitkInstantiateAccessFunctions.h>
#include <itkImage.h>
#include <itkCastImageFilter.h>
namespace mitk
{
#ifndef DOXYGEN_SKIP
template < typename TPixel, unsigned int VImageDimension, class ItkOutputImageType >
void _CastToItkImage2Access( itk::Image<TPixel, VImageDimension>* itkInputImage, itk::SmartPointer<ItkOutputImageType>& itkOutputImage)
{
typedef itk::Image<TPixel, VImageDimension> ItkInputImageType;
if(typeid(ItkInputImageType) == typeid(ItkOutputImageType))
{
itkOutputImage = reinterpret_cast<ItkOutputImageType*>(itkInputImage);
return;
}
typedef itk::CastImageFilter< ItkInputImageType, ItkOutputImageType > CastImageFilterType;
typename CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New();
castImageFilter->SetInput( itkInputImage );
castImageFilter->Update();
itkOutputImage = castImageFilter->GetOutput();
}
#endif //DOXYGEN_SKIP
#define InstantiateAccessFunction__CastToItkImage2Access(type1, type2) \
template MITK_CORE_EXPORT void _CastToItkImage2Access(itk::Image<MITK_PP_TUPLE_REM(2)type1>*, itk::SmartPointer<itk::Image<MITK_PP_TUPLE_REM(2)type2> >&);
#define InstantiateCastToItkImage2Access(r, data, dim) \
MITK_PP_SEQ_FOR_EACH_PRODUCT(InstantiateAccessFunctionProductImpl, ((_CastToItkImage2Access))(MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dim))(MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dim)))
MITK_PP_SEQ_FOR_EACH(InstantiateCastToItkImage2Access, _, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
}
diff --git a/Core/Code/Algorithms/mitkImageCastPart2.cpp b/Core/Code/Algorithms/mitkImageCastPart2.cpp
index 0eafbbe30d..48af1dc0f7 100644
--- a/Core/Code/Algorithms/mitkImageCastPart2.cpp
+++ b/Core/Code/Algorithms/mitkImageCastPart2.cpp
@@ -1,41 +1,40 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkImageCast.h>
#include <mitkImageAccessByItk.h>
#include <mitkInstantiateAccessFunctions.h>
#include <itkImage.h>
#include <itkCastImageFilter.h>
namespace mitk
{
#ifndef DOXYGEN_SKIP
template <typename ItkOutputImageType> void CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer<ItkOutputImageType>& itkOutputImage)
{
AccessFixedDimensionByItk_1(mitkImage, _CastToItkImage2Access, ::itk::GetImageDimension<ItkOutputImageType>::ImageDimension, itkOutputImage);
}
#endif //DOXYGEN_SKIP
#define InstantiateAccessFunction_CastToItkImage(pixelType, dim) \
template MITK_CORE_EXPORT void CastToItkImage(const mitk::Image *, itk::SmartPointer<itk::Image<pixelType,dim> >&);
InstantiateAccessFunction(CastToItkImage)
}
diff --git a/Core/Code/Algorithms/mitkImageCastPart3.cpp b/Core/Code/Algorithms/mitkImageCastPart3.cpp
index 3af3681eed..05ce0048de 100644
--- a/Core/Code/Algorithms/mitkImageCastPart3.cpp
+++ b/Core/Code/Algorithms/mitkImageCastPart3.cpp
@@ -1,122 +1,121 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-12-05 10:31:44 +0100 (Fr, 05 Dez 2008) $
-Version: $Revision: 15893 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkImageCast.h>
#include <itkImage.h>
#include <itkCastImageFilter.h>
#include <itkRGBPixel.h>
#include <itkVector.h>
#include <itkDiffusionTensor3D.h>
namespace mitk
{
#ifndef DOXYGEN_SKIP
template < typename TPixel, unsigned int VImageDimension, class ItkOutputImageType >
void _CastToItkImage2Access( itk::Image<TPixel, VImageDimension>* itkInputImage, itk::SmartPointer<ItkOutputImageType>& itkOutputImage)
{
typedef itk::Image<TPixel, VImageDimension> ItkInputImageType;
if(typeid(ItkInputImageType) == typeid(ItkOutputImageType))
{
itkOutputImage = reinterpret_cast<ItkOutputImageType*>(itkInputImage);
return;
}
typedef itk::CastImageFilter< ItkInputImageType, ItkOutputImageType > CastImageFilterType;
typename CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New();
castImageFilter->SetInput( itkInputImage );
castImageFilter->Update();
itkOutputImage = castImageFilter->GetOutput();
}
#endif //DOXYGEN_SKIP
typedef itk::Image<itk::RGBPixel<unsigned char>, 2> itkImageRGBUC2;
typedef itk::Image<itk::DiffusionTensor3D<float>, 2> itkImageDTIF2;
typedef itk::Image<itk::DiffusionTensor3D<double>, 2> itkImageDTID2;
template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBUC2*, itk::SmartPointer<itkImageRGBUC2>&);
template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageDTIF2*, itk::SmartPointer<itkImageDTIF2>&);
template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageDTID2*, itk::SmartPointer<itkImageDTID2>&);
typedef itk::Image<itk::RGBPixel<unsigned char>, 3> itkImageRGBUC3;
typedef itk::Image<itk::DiffusionTensor3D<float>, 3> itkImageDTIF3;
typedef itk::Image<itk::DiffusionTensor3D<double>, 3> itkImageDTID3;
template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBUC3*, itk::SmartPointer<itkImageRGBUC3>&);
template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageDTIF3*, itk::SmartPointer<itkImageDTIF3>&);
template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageDTID3*, itk::SmartPointer<itkImageDTID3>&);
#define CAST_HUNDRED_VECS(HUN) \
CAST_TEN_VECS(HUN) \
CAST_TEN_VECS(HUN+10) \
CAST_TEN_VECS(HUN+20) \
CAST_TEN_VECS(HUN+30) \
CAST_TEN_VECS(HUN+40) \
CAST_TEN_VECS(HUN+50) \
CAST_TEN_VECS(HUN+60) \
CAST_TEN_VECS(HUN+70) \
CAST_TEN_VECS(HUN+80) \
CAST_TEN_VECS(HUN+90) \
#define CAST_TEN_VECS(TEN) \
CAST_N_VEC(TEN+ 1) \
CAST_N_VEC(TEN+ 2) \
CAST_N_VEC(TEN+ 3) \
CAST_N_VEC(TEN+ 4) \
CAST_N_VEC(TEN+ 5) \
CAST_N_VEC(TEN+ 6) \
CAST_N_VEC(TEN+ 7) \
CAST_N_VEC(TEN+ 8) \
CAST_N_VEC(TEN+ 9) \
CAST_N_VEC(TEN+10) \
#define CAST_N_VEC(N_DIRS) \
_CAST_N_VEC(N_DIRS,double) \
_CAST_N_VEC(N_DIRS,float) \
_CAST_N_VEC(N_DIRS,short) \
#define _CAST_N_VEC(N_DIRS,PIXTYPE) \
template void MITK_CORE_EXPORT _CastToItkImage2Access(itk::Image<itk::Vector<PIXTYPE,N_DIRS>, 2> *, itk::SmartPointer<itk::Image<itk::Vector<PIXTYPE,N_DIRS>, 2> >&); \
template void MITK_CORE_EXPORT _CastToItkImage2Access(itk::Image<itk::Vector<PIXTYPE,N_DIRS>, 3> *, itk::SmartPointer<itk::Image<itk::Vector<PIXTYPE,N_DIRS>, 3> >&); \
// the following lines allow for fixed-size vector images up to a certain size limit
// (commented out for shorter compile times)
//CAST_HUNDRED_VECS(0)
//CAST_HUNDRED_VECS(100)
//CAST_HUNDRED_VECS(200)
//CAST_HUNDRED_VECS(300)
// allow for fixed-size vectors of specific length
// (inspired by itkPointshell.cpp, precompiled q-ball configs)
//CAST_TEN_VECS(0)
//CAST_N_VEC(11)
//CAST_N_VEC(12)
CAST_N_VEC(2)
CAST_N_VEC(3)
CAST_N_VEC(6)
CAST_N_VEC(42)
CAST_N_VEC(92)
CAST_N_VEC(162)
CAST_N_VEC(252)
CAST_N_VEC(362)
CAST_N_VEC(492)
CAST_N_VEC(642)
CAST_N_VEC(812)
CAST_N_VEC(1002)
}
diff --git a/Core/Code/Algorithms/mitkImageCastPart4.cpp b/Core/Code/Algorithms/mitkImageCastPart4.cpp
index 0f890f6deb..c07d3c9e7e 100644
--- a/Core/Code/Algorithms/mitkImageCastPart4.cpp
+++ b/Core/Code/Algorithms/mitkImageCastPart4.cpp
@@ -1,155 +1,154 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-12-05 10:31:44 +0100 (Fr, 05 Dez 2008) $
-Version: $Revision: 15893 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkImageCast.h>
#include <mitkImageAccessByItk.h>
#include <itkRGBPixel.h>
#include <itkImage.h>
#include <itkCastImageFilter.h>
#include <itkDiffusionTensor3D.h>
namespace mitk
{
#ifndef DOXYGEN_SKIP
template <typename ItkOutputImageType> void CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer<ItkOutputImageType>& itkOutputImage)
{
AccessFixedDimensionByItk_1(mitkImage, _CastToItkImage2Access, ::itk::GetImageDimension<ItkOutputImageType>::ImageDimension, itkOutputImage);
}
#endif //DOXYGEN_SKIP
typedef itk::Image<itk::RGBPixel<unsigned char>, 2> itkImageRGBUC2;
typedef itk::Image<itk::DiffusionTensor3D<float>, 2> itkImageDTIF2;
typedef itk::Image<itk::DiffusionTensor3D<double>, 2> itkImageDTID2;
template <> void MITK_CORE_EXPORT CastToItkImage<itkImageRGBUC2>(const mitk::Image * mitkImage, itk::SmartPointer<itkImageRGBUC2>& itkOutputImage)
{
typedef itkImageRGBUC2 ItkOutputImageType;
AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::RGBPixel<unsigned char>), (::itk::GetImageDimension<ItkOutputImageType>::ImageDimension), itkOutputImage);
}
template <> void MITK_CORE_EXPORT CastToItkImage<itkImageDTIF2>(const mitk::Image * mitkImage, itk::SmartPointer<itkImageDTIF2>& itkOutputImage)
{
typedef itkImageDTIF2 ItkOutputImageType;
AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::DiffusionTensor3D<float>), (::itk::GetImageDimension<ItkOutputImageType>::ImageDimension), itkOutputImage);
}
template <> void MITK_CORE_EXPORT CastToItkImage<itkImageDTID2>(const mitk::Image * mitkImage, itk::SmartPointer<itkImageDTID2>& itkOutputImage)
{
typedef itkImageDTID2 ItkOutputImageType;
AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::DiffusionTensor3D<double>), (::itk::GetImageDimension<ItkOutputImageType>::ImageDimension), itkOutputImage);
}
typedef itk::Image<itk::RGBPixel<unsigned char>, 3> itkImageRGBUC3;
typedef itk::Image<itk::DiffusionTensor3D<float>, 3> itkImageDTIF3;
typedef itk::Image<itk::DiffusionTensor3D<double>, 3> itkImageDTID3;
template <> void MITK_CORE_EXPORT CastToItkImage<itkImageRGBUC3>(const mitk::Image * mitkImage, itk::SmartPointer<itkImageRGBUC3>& itkOutputImage)
{
typedef itkImageRGBUC3 ItkOutputImageType;
AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::RGBPixel<unsigned char>), (::itk::GetImageDimension<ItkOutputImageType>::ImageDimension), itkOutputImage);
}
template <> void MITK_CORE_EXPORT CastToItkImage<itkImageDTIF3>(const mitk::Image * mitkImage, itk::SmartPointer<itkImageDTIF3>& itkOutputImage)
{
typedef itkImageDTIF3 ItkOutputImageType;
AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::DiffusionTensor3D<float>), (::itk::GetImageDimension<ItkOutputImageType>::ImageDimension), itkOutputImage);
}
template <> void MITK_CORE_EXPORT CastToItkImage<itkImageDTID3>(const mitk::Image * mitkImage, itk::SmartPointer<itkImageDTID3>& itkOutputImage)
{
typedef itkImageDTID3 ItkOutputImageType;
AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::DiffusionTensor3D<double>), (::itk::GetImageDimension<ItkOutputImageType>::ImageDimension), itkOutputImage);
}
#define TYPE_VECS(HUN) \
TYPE_TEN_VECS(HUN) \
TYPE_TEN_VECS(HUN + 10) \
TYPE_TEN_VECS(HUN + 20) \
TYPE_TEN_VECS(HUN + 30) \
TYPE_TEN_VECS(HUN + 40) \
TYPE_TEN_VECS(HUN + 50) \
TYPE_TEN_VECS(HUN + 60) \
TYPE_TEN_VECS(HUN + 70) \
TYPE_TEN_VECS(HUN + 80) \
TYPE_TEN_VECS(HUN + 90) \
#define TYPE_TEN_VECS(HUN) \
TYPE_N_VEC(HUN + 1) \
TYPE_N_VEC(HUN + 2) \
TYPE_N_VEC(HUN + 3) \
TYPE_N_VEC(HUN + 4) \
TYPE_N_VEC(HUN + 5) \
TYPE_N_VEC(HUN + 6) \
TYPE_N_VEC(HUN + 7) \
TYPE_N_VEC(HUN + 8) \
TYPE_N_VEC(HUN + 9) \
TYPE_N_VEC(HUN + 10) \
#define TYPE_N_VEC(N_DIRS) \
_TYPE_N_VEC(N_DIRS,double) \
_TYPE_N_VEC(N_DIRS,float) \
_TYPE_N_VEC(N_DIRS,short) \
#define _TYPE_N_VEC(N_DIRS,PIXTYPE) \
template <> void MITK_CORE_EXPORT CastToItkImage<itk::Image<itk::Vector<PIXTYPE,N_DIRS>, 2> >(const mitk::Image * mitkImage, itk::SmartPointer<itk::Image<itk::Vector<PIXTYPE,N_DIRS>, 2> >& itkOutputImage) \
{ \
typedef itk::Vector<PIXTYPE,N_DIRS> VECTORTYPE; \
typedef itk::Image<VECTORTYPE, 2> ItkOutputImageType2; \
AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (VECTORTYPE), (::itk::GetImageDimension<ItkOutputImageType2>::ImageDimension), itkOutputImage); \
} \
template <> void MITK_CORE_EXPORT CastToItkImage<itk::Image<itk::Vector<PIXTYPE,N_DIRS>, 3> >(const mitk::Image * mitkImage, itk::SmartPointer<itk::Image<itk::Vector<PIXTYPE,N_DIRS>, 3> >& itkOutputImage) \
{ \
typedef itk::Vector<PIXTYPE,N_DIRS> VECTORTYPE; \
typedef itk::Image<VECTORTYPE, 3> ItkOutputImageType3; \
AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (VECTORTYPE), (::itk::GetImageDimension<ItkOutputImageType3>::ImageDimension), itkOutputImage); \
} \
// the following lines allow for fixed-size vector images up to a certain size limit
// (commented out for shorter compile times)
//TYPE_VECS(000)
//TYPE_VECS(100)
//TYPE_VECS(200)
//TYPE_VECS(300)
//TYPE_VECS(400)
//TYPE_VECS(500)
//TYPE_VECS(600)
//TYPE_VECS(700)
// allow for fixed-size vectors of specific length
// (inspired by itkPointshell.cpp, precompiled q-ball configs)
//TYPE_TEN_VECS(0)
//TYPE_N_VEC(11)
//TYPE_N_VEC(12)
TYPE_N_VEC(2)
TYPE_N_VEC(3)
TYPE_N_VEC(6)
TYPE_N_VEC(42)
TYPE_N_VEC(92)
TYPE_N_VEC(162)
TYPE_N_VEC(252)
TYPE_N_VEC(362)
TYPE_N_VEC(492)
TYPE_N_VEC(642)
TYPE_N_VEC(812)
TYPE_N_VEC(1002)
#ifndef DOXYGEN_SKIP
#endif //DOXYGEN_SKIP
}
diff --git a/Core/Code/Algorithms/mitkImageCaster.cpp b/Core/Code/Algorithms/mitkImageCaster.cpp
index 611e5e22e4..4cec26f482 100644
--- a/Core/Code/Algorithms/mitkImageCaster.cpp
+++ b/Core/Code/Algorithms/mitkImageCaster.cpp
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-06-18 20:12:43 +0200 (Fr, 18 Jun 2010) $
-Version: $Revision: 23881 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageCaster.h"
#include "mitkImageAccessByItk.h"
vtkRenderer* mitk::RendererAccess::m_3DRenderer = 0;
void mitk::RendererAccess::Set3DRenderer(vtkRenderer* renwin4)
{
m_3DRenderer = renwin4;
}
vtkRenderer* mitk::RendererAccess::Get3DRenderer()
{
return m_3DRenderer;
}
void mitk::Caster::Cast(mitk::BaseData*, mitk::Surface*)
{
}
void mitk::ImageCaster::CastBaseData(mitk::BaseData* const mitkBaseData, itk::SmartPointer<mitk::Image>& mitkoutputimage){
try
{
mitkoutputimage = dynamic_cast<mitk::Image*>(mitkBaseData);
}
catch(...)
{
return;
}
}
#define DefineMitkImageCasterMethods(r, data, type) \
void mitk::ImageCaster::CastToItkImage(const mitk::Image* mitkImage, itk::SmartPointer<itk::Image<MITK_PP_TUPLE_REM(2)type> >& itkOutputImage) { \
mitk::CastToItkImage<itk::Image<MITK_PP_TUPLE_REM(2)type> >(mitkImage, itkOutputImage); \
} \
void mitk::ImageCaster::CastToMitkImage(const itk::Image<MITK_PP_TUPLE_REM(2)type>* itkImage, itk::SmartPointer<mitk::Image>& mitkOutputImage) { \
mitk::CastToMitkImage<itk::Image<MITK_PP_TUPLE_REM(2)type> >(itkImage, mitkOutputImage); \
}
MITK_PP_SEQ_FOR_EACH(DefineMitkImageCasterMethods, _, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(2))
MITK_PP_SEQ_FOR_EACH(DefineMitkImageCasterMethods, _, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(3))
diff --git a/Core/Code/Algorithms/mitkImageCaster.h b/Core/Code/Algorithms/mitkImageCaster.h
index dd0c5ed8c8..03f54ccd22 100644
--- a/Core/Code/Algorithms/mitkImageCaster.h
+++ b/Core/Code/Algorithms/mitkImageCaster.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
-Version: $Revision: 17179 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKIMAGECASTER_H
#define MITKIMAGECASTER_H
#include <mitkImageCast.h>
#include <itkImage.h>
#include <itkCastImageFilter.h>
#include <vtkRenderWindow.h>
#include <mitkSurface.h>
#include <mitkPPSeqForEach.h>
#define DeclareMitkImageCasterMethods(r, data, type) \
static void CastToItkImage(const mitk::Image*, itk::SmartPointer<itk::Image<MITK_PP_TUPLE_REM(2)type> >&); \
static void CastToMitkImage(const itk::Image<MITK_PP_TUPLE_REM(2)type>*, itk::SmartPointer<mitk::Image>&);
namespace mitk
{
///
/// \brief This class is just a proxy for global functions which are needed by the
/// python wrapping process since global functions cannnot be wrapped. Static method
/// can be wrapped though.
///
class MITK_CORE_EXPORT ImageCaster
{
public:
MITK_PP_SEQ_FOR_EACH(DeclareMitkImageCasterMethods, _, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(2))
MITK_PP_SEQ_FOR_EACH(DeclareMitkImageCasterMethods, _, MITK_ACCESSBYITK_TYPES_DIMN_SEQ(3))
static void CastBaseData(mitk::BaseData* const, itk::SmartPointer<mitk::Image>&);
};
class MITK_CORE_EXPORT Caster
{
public:
static void Cast(BaseData* dat, Surface* surface);
};
class MITK_CORE_EXPORT RendererAccess
{
public:
static void Set3DRenderer(vtkRenderer* renderer);
static vtkRenderer* Get3DRenderer();
protected:
static vtkRenderer* m_3DRenderer;
};
}
#endif // MITKIMAGECASTER_H
diff --git a/Core/Code/Algorithms/mitkImageChannelSelector.cpp b/Core/Code/Algorithms/mitkImageChannelSelector.cpp
index 2ee3714d72..b12063e33c 100644
--- a/Core/Code/Algorithms/mitkImageChannelSelector.cpp
+++ b/Core/Code/Algorithms/mitkImageChannelSelector.cpp
@@ -1,76 +1,75 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageChannelSelector.h"
mitk::ImageChannelSelector::ImageChannelSelector() : m_ChannelNr(0)
{
}
mitk::ImageChannelSelector::~ImageChannelSelector()
{
}
void mitk::ImageChannelSelector::GenerateOutputInformation()
{
mitk::Image::ConstPointer input = this->GetInput();
mitk::Image::Pointer output = this->GetOutput();
itkDebugMacro(<<"GenerateOutputInformation()");
output->Initialize(input->GetPixelType(), input->GetDimension(), input->GetDimensions());
// initialize geometry
output->SetPropertyList(input->GetPropertyList()->Clone());
output->SetGeometry(dynamic_cast<Geometry3D*>(input->GetTimeSlicedGeometry()->Clone().GetPointer()));
}
void mitk::ImageChannelSelector::GenerateData()
{
const Image::RegionType& requestedRegion = GetOutput()->GetRequestedRegion();
//do we really need the complete channel?
if(requestedRegion.GetSize(3)>1)
SetChannelItem(GetChannelData(m_ChannelNr), 0);
else
//or only a complete volume at a time?
if(requestedRegion.GetSize(2)>1)
SetVolumeItem(GetVolumeData(requestedRegion.GetIndex(3), m_ChannelNr), requestedRegion.GetIndex(3), 0);
else
//not even a complete volume, so now take just a slice!
SetSliceItem(GetSliceData(requestedRegion.GetIndex(2), requestedRegion.GetIndex(3), m_ChannelNr), requestedRegion.GetIndex(2), requestedRegion.GetIndex(3), 0);
}
void mitk::ImageChannelSelector::GenerateInputRequestedRegion()
{
Superclass::GenerateInputRequestedRegion();
mitk::ImageToImageFilter::InputImagePointer input =
const_cast< mitk::ImageToImageFilter::InputImageType * > ( this->GetInput() );
mitk::Image::Pointer output = this->GetOutput();
Image::RegionType requestedRegion;
requestedRegion = output->GetRequestedRegion();
requestedRegion.SetIndex(4, m_ChannelNr);
requestedRegion.SetSize(4, 1);
input->SetRequestedRegion( & requestedRegion );
}
diff --git a/Core/Code/Algorithms/mitkImageChannelSelector.h b/Core/Code/Algorithms/mitkImageChannelSelector.h
index 1d71ba2a92..6a0c0df3ce 100644
--- a/Core/Code/Algorithms/mitkImageChannelSelector.h
+++ b/Core/Code/Algorithms/mitkImageChannelSelector.h
@@ -1,61 +1,60 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 IMAGECHANNELSELECTOR_H_HEADER_INCLUDED_C1E4F4E7
#define IMAGECHANNELSELECTOR_H_HEADER_INCLUDED_C1E4F4E7
#include <MitkExports.h>
#include "mitkSubImageSelector.h"
namespace mitk {
//##Documentation
//## @brief Provides access to a channel of the input image
//##
//## If the input is generated by a ProcessObject, only the required data is
//## requested.
//## @ingroup Process
class MITK_CORE_EXPORT ImageChannelSelector : public SubImageSelector
{
public:
mitkClassMacro(ImageChannelSelector,SubImageSelector);
itkNewMacro(Self);
itkGetConstMacro(ChannelNr,int);
itkSetMacro(ChannelNr,int);
protected:
ImageChannelSelector();
virtual ~ImageChannelSelector();
virtual void GenerateOutputInformation();
virtual void GenerateInputRequestedRegion();
virtual void GenerateData();
int m_ChannelNr;
};
} // namespace mitk
#endif /* IMAGECHANNELSELECTOR_H_HEADER_INCLUDED_C1E4F4E7 */
diff --git a/Core/Code/Algorithms/mitkImageSliceSelector.cpp b/Core/Code/Algorithms/mitkImageSliceSelector.cpp
index 7fa0d99542..c913289b02 100644
--- a/Core/Code/Algorithms/mitkImageSliceSelector.cpp
+++ b/Core/Code/Algorithms/mitkImageSliceSelector.cpp
@@ -1,78 +1,77 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageSliceSelector.h"
void mitk::ImageSliceSelector::GenerateOutputInformation()
{
mitk::Image::ConstPointer input = this->GetInput();
mitk::Image::Pointer output = this->GetOutput();
itkDebugMacro(<<"GenerateOutputInformation()");
output->Initialize(input->GetPixelType(), 2, input->GetDimensions());
if( (unsigned int)m_SliceNr >= input->GetDimension(2) )
{
m_SliceNr = input->GetDimension(2)-1;
}
if( (unsigned int)m_TimeNr >= input->GetDimension(3) )
{
m_TimeNr = input->GetDimension(3)-1;
}
// initialize geometry
output->SetGeometry(dynamic_cast<Geometry3D*>(input->GetSlicedGeometry(m_TimeNr)->GetGeometry2D(m_SliceNr)->Clone().GetPointer()));
output->SetPropertyList(input->GetPropertyList()->Clone());
}
void mitk::ImageSliceSelector::GenerateData()
{
SetSliceItem(GetSliceData(m_SliceNr, m_TimeNr, m_ChannelNr), 0);
}
mitk::ImageSliceSelector::ImageSliceSelector() : m_SliceNr(0), m_TimeNr(0), m_ChannelNr(0)
{
}
mitk::ImageSliceSelector::~ImageSliceSelector()
{
}
void mitk::ImageSliceSelector::GenerateInputRequestedRegion()
{
Superclass::GenerateInputRequestedRegion();
mitk::ImageToImageFilter::InputImagePointer input =
const_cast< mitk::ImageToImageFilter::InputImageType * > ( this->GetInput() );
mitk::Image::Pointer output = this->GetOutput();
Image::RegionType requestedRegion;
requestedRegion = output->GetRequestedRegion();
requestedRegion.SetIndex(2, m_SliceNr);
requestedRegion.SetIndex(3, m_TimeNr);
requestedRegion.SetIndex(4, m_ChannelNr);
requestedRegion.SetSize(2, 1);
requestedRegion.SetSize(3, 1);
requestedRegion.SetSize(4, 1);
input->SetRequestedRegion( & requestedRegion );
}
diff --git a/Core/Code/Algorithms/mitkImageSliceSelector.h b/Core/Code/Algorithms/mitkImageSliceSelector.h
index 1bc170211a..e5a95c08dc 100644
--- a/Core/Code/Algorithms/mitkImageSliceSelector.h
+++ b/Core/Code/Algorithms/mitkImageSliceSelector.h
@@ -1,73 +1,72 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 IMAGESLICESELECTOR_H_HEADER_INCLUDED_C1E4BE7B
#define IMAGESLICESELECTOR_H_HEADER_INCLUDED_C1E4BE7B
#include <MitkExports.h>
#include "mitkSubImageSelector.h"
namespace mitk {
//##Documentation
//## @brief Provides access to a slice of the input image
//##
//## If the input is generated by a ProcessObject, only the required data is
//## requested.
//## @ingroup Process
class MITK_CORE_EXPORT ImageSliceSelector : public SubImageSelector
{
public:
mitkClassMacro(ImageSliceSelector,SubImageSelector);
itkNewMacro(Self);
itkGetConstMacro(SliceNr,int);
itkSetMacro(SliceNr,int);
itkGetConstMacro(TimeNr,int);
itkSetMacro(TimeNr,int);
itkGetConstMacro(ChannelNr,int);
itkSetMacro(ChannelNr,int);
protected:
virtual void GenerateOutputInformation();
virtual void GenerateInputRequestedRegion();
virtual void GenerateData();
ImageSliceSelector();
virtual ~ImageSliceSelector();
int m_SliceNr;
int m_TimeNr;
int m_ChannelNr;
};
} // namespace mitk
#endif /* IMAGESLICESELECTOR_H_HEADER_INCLUDED_C1E4BE7B */
diff --git a/Core/Code/Algorithms/mitkImageSource.cpp b/Core/Code/Algorithms/mitkImageSource.cpp
index 36bd8ef157..ac43dbf330 100644
--- a/Core/Code/Algorithms/mitkImageSource.cpp
+++ b/Core/Code/Algorithms/mitkImageSource.cpp
@@ -1,267 +1,266 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageSource.h"
mitk::ImageSource::ImageSource()
{
// Create the output. We use static_cast<> here because we know the default
// output must be of type TOutputImage
OutputImageType::Pointer output
= static_cast<OutputImageType*>(this->MakeOutput(0).GetPointer());
Superclass::SetNumberOfRequiredOutputs(1);
Superclass::SetNthOutput(0, output.GetPointer());
}
/**
*
*/
mitk::ImageSource::DataObjectPointer mitk::ImageSource::MakeOutput(unsigned int)
{
return static_cast<itk::DataObject*>(OutputImageType::New().GetPointer());
}
/**
*
*/
mitk::ImageSource::OutputImageType* mitk::ImageSource::GetOutput()
{
if (this->GetNumberOfOutputs() < 1)
{
return 0;
}
return static_cast<OutputImageType*>
(this->BaseProcess::GetOutput(0));
}
/**
*
*/
mitk::ImageSource::OutputImageType* mitk::ImageSource::GetOutput(unsigned int idx)
{
return static_cast<OutputImageType*>
(this->ProcessObject::GetOutput(idx));
}
/**
*
*/
void mitk::ImageSource::SetOutput(OutputImageType *output)
{
itkWarningMacro(<< "SetOutput(): This method is slated to be removed from ITK. Please use GraftOutput() in possible combination with DisconnectPipeline() instead." );
BaseProcess::SetNthOutput(0, output);
}
/**
*
*/
void mitk::ImageSource::GraftOutput(OutputImageType *graft)
{
this->GraftNthOutput(0, graft);
}
/**
*
*/
void mitk::ImageSource::GraftNthOutput(unsigned int idx, OutputImageType* graft)
{
itkWarningMacro(<< "GraftNthOutput(): This method is not yet implemented for mitk. Implement it before using!!" );
assert(false);
if (idx < this->GetNumberOfOutputs())
{
OutputImageType * output = this->GetOutput(idx);
if (output && graft)
{
// grab a handle to the bulk data of the specified data object
// output->SetPixelContainer( graft->GetPixelContainer() ); @FIXME!!!!
// copy the region ivars of the specified data object
output->SetRequestedRegion( graft );//graft->GetRequestedRegion() );
// output->SetLargestPossibleRegion( graft->GetLargestPossibleRegion() ); @FIXME!!!!
// output->SetBufferedRegion( graft->GetBufferedRegion() ); @FIXME!!!!
// copy the meta-information
output->CopyInformation( graft );
}
}
}
//----------------------------------------------------------------------------
int mitk::ImageSource::SplitRequestedRegion(int i, int num, OutputImageRegionType& splitRegion)
{
// Get the output pointer
OutputImageType * outputPtr = this->GetOutput();
const SlicedData::SizeType& requestedRegionSize
= outputPtr->GetRequestedRegion().GetSize();
int splitAxis;
SlicedData::IndexType splitIndex;
SlicedData::SizeType splitSize;
// Initialize the splitRegion to the output requested region
splitRegion = outputPtr->GetRequestedRegion();
splitIndex = splitRegion.GetIndex();
splitSize = splitRegion.GetSize();
// split on the outermost dimension available
splitAxis = outputPtr->GetDimension() - 1;
while (requestedRegionSize[splitAxis] == 1)
{
--splitAxis;
if (splitAxis < 0)
{ // cannot split
itkDebugMacro(" Cannot Split");
return 1;
}
}
// determine the actual number of pieces that will be generated
SlicedData::SizeType::SizeValueType range = requestedRegionSize[splitAxis];
int valuesPerThread = (int)ceil(range/(double)num);
int maxThreadIdUsed = (int)ceil(range/(double)valuesPerThread) - 1;
// Split the region
if (i < maxThreadIdUsed)
{
splitIndex[splitAxis] += i*valuesPerThread;
splitSize[splitAxis] = valuesPerThread;
}
if (i == maxThreadIdUsed)
{
splitIndex[splitAxis] += i*valuesPerThread;
// last thread needs to process the "rest" dimension being split
splitSize[splitAxis] = splitSize[splitAxis] - i*valuesPerThread;
}
// set the split region ivars
splitRegion.SetIndex( splitIndex );
splitRegion.SetSize( splitSize );
itkDebugMacro(" Split Piece: " << splitRegion );
return maxThreadIdUsed + 1;
}
//----------------------------------------------------------------------------
void mitk::ImageSource::AllocateOutputs()
{
OutputImagePointer outputPtr;
// Allocate the output memory
for (unsigned int i=0; i < this->GetNumberOfOutputs(); i++)
{
outputPtr = this->GetOutput(i);
// outputPtr->SetBufferedRegion(outputPtr->GetRequestedRegion()); @FIXME???
// outputPtr->Allocate(); @FIXME???
}
}
//----------------------------------------------------------------------------
void mitk::ImageSource::GenerateData()
{
// Call a method that can be overriden by a subclass to allocate
// memory for the filter's outputs
this->AllocateOutputs();
// Call a method that can be overridden by a subclass to perform
// some calculations prior to splitting the main computations into
// separate threads
this->BeforeThreadedGenerateData();
// Set up the multithreaded processing
ThreadStruct str;
str.Filter = this;
this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str);
// multithread the execution
this->GetMultiThreader()->SingleMethodExecute();
// Call a method that can be overridden by a subclass to perform
// some calculations after all the threads have completed
this->AfterThreadedGenerateData();
}
//----------------------------------------------------------------------------
// The execute method created by the subclass.
void mitk::ImageSource::ThreadedGenerateData(const OutputImageRegionType&, int)
{
itkExceptionMacro("subclass should override this method!!!");
}
// Callback routine used by the threading library. This routine just calls
// the ThreadedGenerateData method after setting the correct region for this
// thread.
ITK_THREAD_RETURN_TYPE mitk::ImageSource::ThreaderCallback( void *arg )
{
ThreadStruct *str;
int total, threadId, threadCount;
threadId = ((itk::MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
threadCount = ((itk::MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
str = (ThreadStruct *)(((itk::MultiThreader::ThreadInfoStruct *)(arg))->UserData);
// execute the actual method with appropriate output region
// first find out how many pieces extent can be split into.
SlicedData::RegionType splitRegion;
total = str->Filter->SplitRequestedRegion(threadId, threadCount,
splitRegion);
if (threadId < total)
{
str->Filter->ThreadedGenerateData(splitRegion, threadId);
}
// else
// {
// otherwise don't use this thread. Sometimes the threads dont
// break up very well and it is just as efficient to leave a
// few threads idle.
// }
return ITK_THREAD_RETURN_VALUE;
}
void mitk::ImageSource::PrepareOutputs()
{
Superclass::PrepareOutputs();
}
void* mitk::ImageSource::GetData()
{
Update();
return GetOutput()->GetData();
}
vtkImageData* mitk::ImageSource::GetVtkImageData()
{
Update();
return GetOutput()->GetVtkImageData();
}
diff --git a/Core/Code/Algorithms/mitkImageSource.h b/Core/Code/Algorithms/mitkImageSource.h
index a4778bec6c..43eb7fa823 100644
--- a/Core/Code/Algorithms/mitkImageSource.h
+++ b/Core/Code/Algorithms/mitkImageSource.h
@@ -1,261 +1,260 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 IMAGESOURCE_H_HEADER_INCLUDED_C1E7D6EC
#define IMAGESOURCE_H_HEADER_INCLUDED_C1E7D6EC
#include <MitkExports.h>
#include "mitkBaseProcess.h"
#include "mitkImage.h"
namespace mitk {
//##Documentation
//## @brief Superclass of all classes generating Images (instances of class
//## Image) as output.
//##
//## In itk and vtk the generated result of a ProcessObject is only guaranteed
//## to be up-to-date, when Update() of the ProcessObject or the generated
//## DataObject is called immediately before access of the data stored in the
//## DataObject. This is also true for subclasses of mitk::BaseProcess and thus
//## for mitk::ImageSource. But there are also three access methods provided
//## that guarantee an up-to-date result (by first calling Update and then
//## returning the result of GetOutput()): GetData(), GetPic() and
//## GetVtkImageData().
//## @ingroup Process
class MITK_CORE_EXPORT ImageSource : public BaseProcess
{
public:
mitkClassMacro(ImageSource,BaseProcess);
/** @brief Smart Pointer type to a DataObject. */
typedef itk::DataObject::Pointer DataObjectPointer;
/** @brief Method for creation through the object factory. */
itkNewMacro(Self);
/** @brief Some convenient typedefs. */
typedef mitk::Image OutputImageType;
typedef OutputImageType::Pointer OutputImagePointer;
typedef SlicedData::RegionType OutputImageRegionType;
/** @brief Get the image output of this process object. */
OutputImageType * GetOutput(void);
OutputImageType * GetOutput(unsigned int idx);
/** @brief Set the image output of this process object.
*
* This call is slated
* to be removed from ITK. You should GraftOutput() and possible
* DataObject::DisconnectPipeline() to properly change the output. */
void SetOutput(OutputImageType *output);
/** @brief Graft the specified DataObject onto this ProcessObject's output.
*
* This method grabs a handle to the specified DataObject's bulk
* data to used as its output's own bulk data. It also copies the
* region ivars (RequestedRegion, BufferedRegion,
* LargestPossibleRegion) and meta-data (Spacing, Origin) from the
* specified data object into this filter's output data object. Most
* importantly, however, it leaves the Source ivar untouched so the
* original pipeline routing is intact. This method is used when a
* process object is implemented using a mini-pipeline which is
* defined in its GenerateData() method. The usage is:
*
* \code
* // setup the mini-pipeline to process the input to this filter
* firstFilterInMiniPipeline->SetInput( this->GetInput() );
* // setup the mini-pipeline to calculate the correct regions
* // and write to the appropriate bulk data block
* lastFilterInMiniPipeline->GraftOutput( this->GetOutput() );
*
* // execute the mini-pipeline
* lastFilterInMiniPipeline->Update();
*
* // graft the mini-pipeline output back onto this filter's output.
* // this is needed to get the appropriate regions passed back.
* this->GraftOutput( lastFilterInMiniPipeline->GetOutput() );
* \endcode
*
* For proper pipeline execution, a filter using a mini-pipeline
* must implement the GenerateInputRequestedRegion(),
* GenerateOutputRequestedRegion(), GenerateOutputInformation() and
* EnlargeOutputRequestedRegion() methods as necessary to reflect
* how the mini-pipeline will execute (in other words, the outer
* filter's pipeline mechanism must be consistent with what the
* mini-pipeline will do).
* */
virtual void GraftOutput(OutputImageType *output);
/** @brief Graft the specified data object onto this ProcessObject's idx'th
* output.
*
* This is the similar to GraftOutput method except is
* allows you specify which output is affected. The specified index
* must be a valid output number (less than
* ProcessObject::GetNumberOfOutputs()). See the GraftOutput for
* general usage information. */
virtual void GraftNthOutput(unsigned int idx, OutputImageType *output);
/** @brief Make a DataObject of the correct type to used as the specified
* output.
*
* Every ProcessObject subclass must be able to create a
* DataObject that can be used as a specified output. This method
* is automatically called when DataObject::DisconnectPipeline() is
* called. DataObject::DisconnectPipeline, disconnects a data object
* from being an output of its current source. When the data object
* is disconnected, the ProcessObject needs to construct a replacement
* output data object so that the ProcessObject is in a valid state.
* So DataObject::DisconnectPipeline eventually calls
* ProcessObject::MakeOutput. Note that MakeOutput always returns a
* SmartPointer to a DataObject. If a subclass of ImageSource has
* multiple outputs of different types, then that class must provide
* an implementation of MakeOutput(). */
virtual DataObjectPointer MakeOutput(unsigned int idx);
virtual void* GetData();
virtual vtkImageData* GetVtkImageData();
protected:
ImageSource();
virtual ~ImageSource() {}
/** @brief A version of GenerateData() specific for image processing
* filters.
*
* This implementation will split the processing across
* multiple threads. The buffer is allocated by this method. Then
* the BeforeThreadedGenerateData() method is called (if
* provided). Then, a series of threads are spawned each calling
* ThreadedGenerateData(). After all the threads have completed
* processing, the AfterThreadedGenerateData() method is called (if
* provided). If an image processing filter cannot be threaded, the
* filter should provide an implementation of GenerateData(). That
* implementation is responsible for allocating the output buffer.
* If a filter an be threaded, it should NOT provide a
* GenerateData() method but should provide a ThreadedGenerateData()
* instead.
*
* \sa ThreadedGenerateData() */
virtual void GenerateData();
/** @brief If an imaging filter can be implemented as a multithreaded
* algorithm, the filter will provide an implementation of
* ThreadedGenerateData().
*
* This superclass will automatically split
* the output image into a number of pieces, spawn multiple threads,
* and call ThreadedGenerateData() in each thread. Prior to spawning
* threads, the BeforeThreadedGenerateData() method is called. After
* all the threads have completed, the AfterThreadedGenerateData()
* method is called. If an image processing filter cannot support
* threading, that filter should provide an implementation of the
* GenerateData() method instead of providing an implementation of
* ThreadedGenerateData(). If a filter provides a GenerateData()
* method as its implementation, then the filter is responsible for
* allocating the output data. If a filter provides a
* ThreadedGenerateData() method as its implementation, then the
* output memory will allocated automatically by this superclass.
* The ThreadedGenerateData() method should only produce the output
* specified by "outputThreadRegion"
* parameter. ThreadedGenerateData() cannot write to any other
* portion of the output image (as this is responsibility of a
* different thread).
*
* \sa GenerateData(), SplitRequestedRegion() */
virtual
void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
int threadId );
/** @brief This method is intentionally left blank.
*
* ImageSource's need not
* Initialize their containers. The Image::Allocate() method (called
* from GenerateData()) will resize the container if more memory is
* needed. Otherwise, the memory can be reused.
*/
virtual void PrepareOutputs();
/** @brief The GenerateData method normally allocates the buffers for all of the
* outputs of a filter.
*
* Some filters may want to override this default
* behavior. For example, a filter may have multiple outputs with
* varying resolution. Or a filter may want to process data in place by
* grafting its input to its output.*/
virtual void AllocateOutputs();
/** @brief If an imaging filter needs to perform processing after the buffer
* has been allocated but before threads are spawned, the filter can
* can provide an implementation for BeforeThreadedGenerateData().
*
* The execution flow in the default GenerateData() method will be:
* 1) Allocate the output buffer
* 2) Call BeforeThreadedGenerateData()
* 3) Spawn threads, calling ThreadedGenerateData() in each thread.
* 4) Call AfterThreadedGenerateData()
* Note that this flow of control is only available if a filter provides
* a ThreadedGenerateData() method and NOT a GenerateData() method. */
virtual void BeforeThreadedGenerateData() {};
/** @brief If an imaging filter needs to perform processing after all
* processing threads have completed, the filter can can provide an
* implementation for AfterThreadedGenerateData().
*
* The execution
* flow in the default GenerateData() method will be:
* 1) Allocate the output buffer
* 2) Call BeforeThreadedGenerateData()
* 3) Spawn threads, calling ThreadedGenerateData() in each thread.
* 4) Call AfterThreadedGenerateData()
* Note that this flow of control is only available if a filter provides
* a ThreadedGenerateData() method and NOT a GenerateData() method. */
virtual void AfterThreadedGenerateData() {};
/** @brief Split the output's RequestedRegion into "num" pieces, returning
* region "i" as "splitRegion".
*
* This method is called "num" times. The
* regions must not overlap. The method returns the number of pieces that
* the routine is capable of splitting the output RequestedRegion,
* i.e. return value is less than or equal to "num". */
virtual
int SplitRequestedRegion(int i, int num, OutputImageRegionType& splitRegion);
/** @brief Static function used as a "callback" by the MultiThreader.
*
* The threading library will call this routine for each thread, which will delegate the
* control to ThreadedGenerateData(). */
static ITK_THREAD_RETURN_TYPE ThreaderCallback( void *arg );
/** @brief Internal structure used for passing image data into the threading library */
struct ThreadStruct
{
Pointer Filter;
};
private:
void operator=(const Self&); //purposely not implemented
};
} // namespace mitk
#endif /* IMAGESOURCE_H_HEADER_INCLUDED_C1E7D6EC */
diff --git a/Core/Code/Algorithms/mitkImageTimeSelector.cpp b/Core/Code/Algorithms/mitkImageTimeSelector.cpp
index 3dd8ab69af..f4498cf2a7 100644
--- a/Core/Code/Algorithms/mitkImageTimeSelector.cpp
+++ b/Core/Code/Algorithms/mitkImageTimeSelector.cpp
@@ -1,79 +1,78 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageTimeSelector.h"
mitk::ImageTimeSelector::ImageTimeSelector() : m_TimeNr(0), m_ChannelNr(0)
{
}
mitk::ImageTimeSelector::~ImageTimeSelector()
{
}
void mitk::ImageTimeSelector::GenerateOutputInformation()
{
Image::ConstPointer input = this->GetInput();
Image::Pointer output = this->GetOutput();
itkDebugMacro(<<"GenerateOutputInformation()");
int dim=(input->GetDimension()<3?input->GetDimension():3);
output->Initialize(input->GetPixelType(), dim, input->GetDimensions());
if( (unsigned int) m_TimeNr >= input->GetDimension(3) )
{
m_TimeNr = input->GetDimension(3)-1;
}
// initialize geometry
output->SetGeometry(dynamic_cast<Geometry3D*>(input->GetSlicedGeometry(m_TimeNr)->Clone().GetPointer()));
output->SetPropertyList(input->GetPropertyList()->Clone());
}
void mitk::ImageTimeSelector::GenerateData()
{
const Image::RegionType& requestedRegion = this->GetOutput()->GetRequestedRegion();
//do we really need a complete volume at a time?
if(requestedRegion.GetSize(2)>1)
this->SetVolumeItem( this->GetVolumeData(m_TimeNr, m_ChannelNr), 0 );
else
//no, so take just a slice!
this->SetSliceItem( this->GetSliceData(requestedRegion.GetIndex(2), m_TimeNr, m_ChannelNr), requestedRegion.GetIndex(2), 0 );
}
void mitk::ImageTimeSelector::GenerateInputRequestedRegion()
{
Superclass::GenerateInputRequestedRegion();
ImageToImageFilter::InputImagePointer input =
const_cast< mitk::ImageToImageFilter::InputImageType * > ( this->GetInput() );
Image::Pointer output = this->GetOutput();
Image::RegionType requestedRegion;
requestedRegion = output->GetRequestedRegion();
requestedRegion.SetIndex(3, m_TimeNr);
requestedRegion.SetIndex(4, m_ChannelNr);
requestedRegion.SetSize(3, 1);
requestedRegion.SetSize(4, 1);
input->SetRequestedRegion( & requestedRegion );
}
diff --git a/Core/Code/Algorithms/mitkImageTimeSelector.h b/Core/Code/Algorithms/mitkImageTimeSelector.h
index 5f3e5ff489..e26f7596b3 100644
--- a/Core/Code/Algorithms/mitkImageTimeSelector.h
+++ b/Core/Code/Algorithms/mitkImageTimeSelector.h
@@ -1,66 +1,65 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 IMAGETIMESELECTOR_H_HEADER_INCLUDED_C1E4861D
#define IMAGETIMESELECTOR_H_HEADER_INCLUDED_C1E4861D
#include <MitkExports.h>
#include "mitkSubImageSelector.h"
namespace mitk {
//##Documentation
//## @brief Provides access to a volume at a specific time of the input image
//##
//## If the input is generated by a ProcessObject, only the required data is
//## requested.
//## @ingroup Process
class MITK_CORE_EXPORT ImageTimeSelector : public SubImageSelector
{
public:
mitkClassMacro(ImageTimeSelector,SubImageSelector);
itkNewMacro(Self);
itkGetConstMacro(TimeNr,int);
itkSetMacro(TimeNr,int);
itkGetConstMacro(ChannelNr,int);
itkSetMacro(ChannelNr,int);
protected:
ImageTimeSelector();
virtual ~ImageTimeSelector();
virtual void GenerateOutputInformation();
virtual void GenerateInputRequestedRegion();
virtual void GenerateData();
int m_TimeNr;
int m_ChannelNr;
};
} // namespace mitk
#endif /* IMAGETIMESELECTOR_H_HEADER_INCLUDED_C1E4861D */
diff --git a/Core/Code/Algorithms/mitkImageToImageFilter.cpp b/Core/Code/Algorithms/mitkImageToImageFilter.cpp
index 98b3b53412..3a2a911c3a 100644
--- a/Core/Code/Algorithms/mitkImageToImageFilter.cpp
+++ b/Core/Code/Algorithms/mitkImageToImageFilter.cpp
@@ -1,112 +1,111 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageToImageFilter.h"
mitk::ImageToImageFilter::ImageToImageFilter()
{
// Modify superclass default values, can be overridden by subclasses
this->SetNumberOfRequiredInputs(1);
}
mitk::ImageToImageFilter::~ImageToImageFilter()
{
}
/**
*
*/
void mitk::ImageToImageFilter::SetInput(const mitk::ImageToImageFilter::InputImageType *input)
{
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput(0,
const_cast< mitk::ImageToImageFilter::InputImageType * >( input ) );
}
/**
* Connect one of the operands for pixel-wise addition
*/
void mitk::ImageToImageFilter::SetInput( unsigned int index, const mitk::ImageToImageFilter::InputImageType * image )
{
if( index+1 > this->GetNumberOfInputs() )
{
this->SetNumberOfRequiredInputs( index + 1 );
}
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput(index,
const_cast< mitk::ImageToImageFilter::InputImageType *>( image ) );
}
/**
*
*/
const mitk::ImageToImageFilter::InputImageType *mitk::ImageToImageFilter::GetInput(void)
{
if (this->GetNumberOfInputs() < 1)
{
return 0;
}
return static_cast<const mitk::ImageToImageFilter::InputImageType * >
(this->ProcessObject::GetInput(0) );
}
/**
*
*/
const mitk::ImageToImageFilter::InputImageType *mitk::ImageToImageFilter::GetInput(unsigned int idx)
{
return static_cast< const mitk::ImageToImageFilter::InputImageType * >
(this->ProcessObject::GetInput(idx));
}
//-----------------------------------------------------------------------
//
void mitk::ImageToImageFilter::GenerateInputRequestedRegion()
{
Superclass::GenerateInputRequestedRegion();
for (unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx)
{
if (this->GetInput(idx))
{
mitk::ImageToImageFilter::InputImagePointer input =
const_cast< mitk::ImageToImageFilter::InputImageType * > ( this->GetInput(idx) );
// Use the function object RegionCopier to copy the output region
// to the input. The default region copier has default implementations
// to handle the cases where the input and output are the same
// dimension, the input a higher dimension than the output, and the
// input a lower dimension than the output.
InputImageRegionType inputRegion;
// this->CallCopyRegion(inputRegion, this->GetOutput()->GetRequestedRegion()); @FIXME ??
// input->SetRequestedRegion( inputRegion ); @FIXME ??
input->SetRequestedRegion( this->GetOutput() ); // ersatz. @FIXME ??
}
}
}
void mitk::ImageToImageFilter::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
diff --git a/Core/Code/Algorithms/mitkImageToImageFilter.h b/Core/Code/Algorithms/mitkImageToImageFilter.h
index cc233a466b..3e86a0201e 100644
--- a/Core/Code/Algorithms/mitkImageToImageFilter.h
+++ b/Core/Code/Algorithms/mitkImageToImageFilter.h
@@ -1,85 +1,84 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 IMAGETOIMAGEFILTER_H_HEADER_INCLUDED_C1E5E869
#define IMAGETOIMAGEFILTER_H_HEADER_INCLUDED_C1E5E869
#include <MitkExports.h>
#include "mitkImageSource.h"
namespace mitk {
//##Documentation
//## @brief Superclass of all classes having one or more Images as input and
//## generating Images as output
//## @ingroup Process
class MITK_CORE_EXPORT ImageToImageFilter : public ImageSource
{
public:
mitkClassMacro(ImageToImageFilter,ImageSource);
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Superclass typedefs. */
typedef Superclass::OutputImageRegionType OutputImageRegionType;
/** Some convenient typedefs. */
typedef mitk::Image InputImageType;
typedef InputImageType::Pointer InputImagePointer;
typedef InputImageType::ConstPointer InputImageConstPointer;
typedef SlicedData::RegionType InputImageRegionType;
/** Set/Get the image input of this process object. */
virtual void SetInput( const InputImageType *image);
virtual void SetInput( unsigned int, const InputImageType * image);
const InputImageType * GetInput(void);
const InputImageType * GetInput(unsigned int idx);
protected:
ImageToImageFilter();
virtual ~ImageToImageFilter();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
/** What is the input requested region that is required to produce the
* output requested region? The base assumption for image processing
* filters is that the input requested region can be set to match the
* output requested region. If a filter requires more input (for instance
* a filter that uses neighborhoods needs more input than output to avoid
* introducing artificial boundary conditions) or less input (for instance
* a magnify filter) will have to override this method. In doing so, it
* should call its superclass' implementation as its first step. Note that
* this imaging filters operate differently than the classes to this
* point in the class hierachy. Up till now, the base assumption has been
* that the largest possible region will be requested of the input.
*
* \sa ProcessObject::GenerateInputRequestedRegion(),
* ImageSource::GenerateInputRequestedRegion() */
virtual void GenerateInputRequestedRegion();
private:
void operator=(const Self&); //purposely not implemented
};
} // namespace mitk
#endif /* IMAGETOIMAGEFILTER_H_HEADER_INCLUDED_C1E5E869 */
diff --git a/Core/Code/Algorithms/mitkImageToItk.h b/Core/Code/Algorithms/mitkImageToItk.h
index 66a8e876c8..6fb4649ec6 100644
--- a/Core/Code/Algorithms/mitkImageToItk.h
+++ b/Core/Code/Algorithms/mitkImageToItk.h
@@ -1,119 +1,118 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 IMAGETOITK_H_HEADER_INCLUDED_C1C2FCD2
#define IMAGETOITK_H_HEADER_INCLUDED_C1C2FCD2
#if(_MSC_VER==1200)
#include <itkFixedCenterOfRotationAffineTransform.h>
#endif
#include <itkImage.h>
#include <itkImageSource.h>
#include "mitkImage.h"
#include "mitkImageDataItem.h"
namespace mitk
{
/**
* Create itk::ImageSource for mitk::Image
* \ingroup Adaptor
*
* \warning 2D MITK images will get a 2D identity matrix in ITK
* \todo Get clear about how to handle directed ITK 2D images in ITK
*/
template <class TOutputImage>
class ImageToItk : public itk::ImageSource< TOutputImage >
{
protected:
mitk::Image::Pointer m_MitkImage;
mitk::ImageDataItem::Pointer m_ImageDataItem;
public:
typedef ImageToItk Self;
typedef itk::ImageSource<TOutputImage> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Superclass typedefs. */
typedef typename Superclass::OutputImageRegionType OutputImageRegionType;
/** Some convenient typedefs. */
typedef mitk::Image InputImageType;
typedef InputImageType::Pointer InputImagePointer;
typedef InputImageType::ConstPointer InputImageConstPointer;
typedef SlicedData::RegionType InputImageRegionType;
typedef typename TOutputImage::SizeType SizeType;
typedef typename TOutputImage::IndexType IndexType;
typedef typename TOutputImage::RegionType RegionType;
typedef typename TOutputImage::PixelType PixelType;
const mitk::Image * GetInput(void);
const mitk::Image * GetInput(unsigned int idx);
virtual void SetInput(const mitk::Image *input);
virtual void SetInput(unsigned int index, const mitk::Image * image);
virtual void UpdateOutputInformation();
itkGetMacro( Channel, int );
itkSetMacro( Channel, int );
itkSetMacro( CopyMemFlag, bool );
itkGetMacro( CopyMemFlag, bool );
itkBooleanMacro( CopyMemFlag );
protected:
ImageToItk(): m_CopyMemFlag(false), m_Channel(0)
{
}
virtual ~ImageToItk()
{
}
void PrintSelf(std::ostream& os, itk::Indent indent) const;
virtual void GenerateData();
virtual void GenerateOutputInformation();
private:
bool m_CopyMemFlag;
int m_Channel;
//ImageToItk(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#ifndef ITK_MANUAL_INSTANTIATION
#include "mitkImageToItk.txx"
#endif
#endif // IMAGETOITK_H_HEADER_INCLUDED_C1C2FCD2
diff --git a/Core/Code/Algorithms/mitkImageToItk.txx b/Core/Code/Algorithms/mitkImageToItk.txx
index 0aba549913..03b0978bc7 100644
--- a/Core/Code/Algorithms/mitkImageToItk.txx
+++ b/Core/Code/Algorithms/mitkImageToItk.txx
@@ -1,259 +1,257 @@
-/*=========================================================================
+/*===================================================================
- Program: Medical Imaging & Interaction Toolkit
- Module: $RCSfile$
- Language: C++
- Date: $Date$
- Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/ for details.
+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 the above copyright notices for more information.
+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 IMAGETOITK_TXX_INCLUDED_C1C2FCD2
#define IMAGETOITK_TXX_INCLUDED_C1C2FCD2
#include "mitkImageToItk.h"
#include "mitkBaseProcess.h"
#include "itkImportMitkImageContainer.h"
template <class TOutputImage>
void mitk::ImageToItk<TOutputImage>::SetInput(const mitk::Image *input)
{
if(input == NULL)
itkExceptionMacro( << "image is null" );
if(input->GetDimension()!=TOutputImage::GetImageDimension())
itkExceptionMacro( << "image has dimension " << input->GetDimension() << " instead of " << TOutputImage::GetImageDimension() );
if(!(input->GetPixelType() == typeid(PixelType)))
itkExceptionMacro( << "image has wrong pixel type " );
// Process object is not const-correct so the const_cast is required here
itk::ProcessObject::SetNthInput(0,
const_cast< mitk::Image * >( input ) );
}
template<class TOutputImage>
void mitk::ImageToItk<TOutputImage>::SetInput( unsigned int index, const mitk::Image * input )
{
if( index+1 > this->GetNumberOfInputs() )
{
this->SetNumberOfRequiredInputs( index + 1 );
}
if(input == NULL)
itkExceptionMacro( << "image is null" );
if(input->GetDimension()!=TOutputImage::GetImageDimension())
itkExceptionMacro( << "image has dimension " << input->GetDimension() << " instead of " << TOutputImage::GetImageDimension() );
if(!(input->GetPixelType() == typeid(PixelType)))
itkExceptionMacro( << "image has wrong pixel type " );
// Process object is not const-correct so the const_cast is required here
itk::ProcessObject::SetNthInput(index,
const_cast< mitk::Image *>( input ) );
}
template<class TOutputImage>
const mitk::Image *mitk::ImageToItk<TOutputImage>::GetInput(void)
{
if (this->GetNumberOfInputs() < 1)
{
return 0;
}
return static_cast< const mitk::Image * >
(itk::ProcessObject::GetInput(0) );
}
template<class TOutputImage>
const mitk::Image *mitk::ImageToItk<TOutputImage>::GetInput(unsigned int idx)
{
return static_cast< mitk::Image * >
(itk::ProcessObject::GetInput(idx));
}
template<class TOutputImage>
void mitk::ImageToItk<TOutputImage>
::GenerateData()
{
// Allocate output
mitk::Image::ConstPointer input = this->GetInput();
typename Superclass::OutputImageType::Pointer output = this->GetOutput();
unsigned long noBytes = input->GetDimension(0);
for (unsigned int i=1; i<TOutputImage::GetImageDimension(); ++i)
{
noBytes = noBytes * input->GetDimension(i);
}
// hier wird momentan wohl nur der erste Channel verwendet??!!
m_ImageDataItem = const_cast<mitk::Image*>(input.GetPointer())->GetChannelData( m_Channel );
if(m_ImageDataItem.GetPointer() == NULL)
{
itkWarningMacro(<< "no image data to import in ITK image");
RegionType bufferedRegion;
output->SetBufferedRegion(bufferedRegion);
return;
}
if (m_CopyMemFlag)
{
itkDebugMacro("copyMem ...");
output->Allocate();
memcpy( (PixelType *) output->GetBufferPointer(), m_ImageDataItem->GetData(), sizeof(PixelType)*noBytes);
}
else
{
itkDebugMacro("do not copyMem ...");
typedef itk::ImportMitkImageContainer< unsigned long, PixelType > ImportContainerType;
typename ImportContainerType::Pointer import;
import = ImportContainerType::New();
import->Initialize();
itkDebugMacro( << "size of container = " << import->Size() );
import->SetImageDataItem(m_ImageDataItem);
output->SetPixelContainer(import);
itkDebugMacro( << "size of container = " << import->Size() );
}
}
template<class TOutputImage>
void mitk::ImageToItk<TOutputImage>
::UpdateOutputInformation()
{
mitk::Image::ConstPointer input = this->GetInput();
if(input.IsNotNull() && (input->GetSource().IsNotNull()) && input->GetSource()->Updating())
{
typename Superclass::OutputImageType::Pointer output = this->GetOutput();
unsigned long t1 = input->GetUpdateMTime()+1;
if (t1 > this->m_OutputInformationMTime.GetMTime())
{
output->SetPipelineMTime(t1);
this->GenerateOutputInformation();
this->m_OutputInformationMTime.Modified();
}
return;
}
Superclass::UpdateOutputInformation();
}
template<class TOutputImage>
void mitk::ImageToItk<TOutputImage>
::GenerateOutputInformation()
{
mitk::Image::ConstPointer input = this->GetInput();
typename Superclass::OutputImageType::Pointer output = this->GetOutput();
// allocate size, origin, spacing, direction in types of output image
SizeType size;
const unsigned int itkDimMin3 = (TOutputImage::ImageDimension > 3 ? TOutputImage::ImageDimension : 3);
const unsigned int itkDimMax3 = (TOutputImage::ImageDimension < 3 ? TOutputImage::ImageDimension : 3);
typename Superclass::OutputImageType::PointType::ValueType origin[ itkDimMin3 ];
typename Superclass::OutputImageType::SpacingType::ComponentType spacing[ itkDimMin3 ];
typename Superclass::OutputImageType::DirectionType direction;
// copy as much information as possible into size and spacing
unsigned int i;
for ( i=0; i < itkDimMax3; ++i)
{
size[i] = input->GetDimension(i);
spacing[i] = input->GetGeometry()->GetSpacing()[i];
}
for ( ; i < TOutputImage::ImageDimension; ++i)
{
origin[i] = 0.0;
size[i] = input->GetDimension(i);
spacing[i] = 1.0;
}
// build region from size
IndexType start;
start.Fill( 0 );
RegionType region;
region.SetIndex( start );
region.SetSize( size );
// copy as much information as possible into origin
const mitk::Point3D& mitkorigin = input->GetGeometry()->GetOrigin();
itk2vtk(mitkorigin, origin);
// copy as much information as possible into direction
direction.SetIdentity();
unsigned int j;
const AffineTransform3D::MatrixType& matrix = input->GetGeometry()->GetIndexToWorldTransform()->GetMatrix();
/// \warning 2D MITK images could have a 3D rotation, since they have a 3x3 geometry matrix.
/// If it is only a rotation around the transversal plane normal, it can be express with a 2x2 matrix.
/// In this case, the ITK image conservs this information and is identical to the MITK image!
/// If the MITK image contains any other rotation, the ITK image will have no rotation at all.
/// Spacing is of course conserved in both cases.
// the following loop devides by spacing now to normalize columns.
// counterpart of InitializeByItk in mitkImage.h line 372 of revision 15092.
// Check if information is lost
if ( TOutputImage::ImageDimension <= 2)
{
if (( TOutputImage::ImageDimension == 2) && (
( matrix[0][2] != 0) ||
( matrix[1][2] != 0) ||
( matrix[2][0] != 0) ||
( matrix[2][1] != 0) ||
(( matrix[2][2] != 1) && ( matrix[2][2] != -1) )))
{
// The 2D MITK image contains 3D rotation information.
// This cannot be expressed in a 2D ITK image, so the ITK image will have no rotation
}
else
{
// The 2D MITK image can be converted to an 2D ITK image without information loss!
for ( i=0; i < itkDimMax3; ++i)
for( j=0; j < itkDimMax3; ++j )
direction[i][j] = matrix[i][j]/spacing[j];
}
}
else
{
// Normal 3D image. Conversion possible without problem!
for ( i=0; i < itkDimMax3; ++i)
for( j=0; j < itkDimMax3; ++j )
direction[i][j] = matrix[i][j]/spacing[j];
}
// set information into output image
output->SetRegions( region );
output->SetOrigin( origin );
output->SetSpacing( spacing );
output->SetDirection( direction );
}
template<class TOutputImage>
void
mitk::ImageToItk<TOutputImage>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os,indent);
}
#endif //IMAGETOITK_TXX_INCLUDED_C1C2FCD2
diff --git a/Core/Code/Algorithms/mitkInstantiateAccessFunctions.h b/Core/Code/Algorithms/mitkInstantiateAccessFunctions.h
index 93b92827b1..a1c4389d3b 100644
--- a/Core/Code/Algorithms/mitkInstantiateAccessFunctions.h
+++ b/Core/Code/Algorithms/mitkInstantiateAccessFunctions.h
@@ -1,158 +1,157 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKINSTANTIATEACCESSFUNCTIONS_H_HEADER_INCLUDED
#define MITKINSTANTIATEACCESSFUNCTIONS_H_HEADER_INCLUDED
#include <itkCastImageFilter.h>
#include <mitkImageToItk.h>
#include <mitkConfig.h>
#include <mitkPPSeqForEach.h>
#include <mitkPPSeqForEachProduct.h>
#include <mitkPPSeqToTuple.h>
#include <mitkPPCat.h>
#include <mitkPPExpand.h>
#include <mitkPPTupleRem.h>
#ifndef DOXYGEN_SKIP
#define InstantiateAccessFunctionImpl(r, itkImgFunc, type) \
MITK_PP_CAT(InstantiateAccessFunction_, itkImgFunc) type
// product is of the form (itkImgFunc)(short)(2)
#ifdef _MSC_VER
#define InstantiateAccessFunctionProductImpl(r, product) \
MITK_PP_CAT(InstantiateAccessFunction_, MITK_PP_SEQ_HEAD(product)) \
MITK_PP_EXPAND(MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)))
#else
#define InstantiateAccessFunctionProductImpl(r, product) \
MITK_PP_EXPAND(MITK_PP_CAT(InstantiateAccessFunction_, MITK_PP_SEQ_HEAD(product)) \
MITK_PP_SEQ_TO_TUPLE(MITK_PP_SEQ_TAIL(product)))
#endif
#endif // DOXYGEN_SKIP
//--------------------------------- instantiation functions ------------------------------
/**
* \brief Instantiate access function for the given pixel types and dimensions.
*
* Iteratively calls a macro named InstantiateAccessFunction_itkImgFunc
* which you must define and which usually explicitly instantiates your access function.
*
* A call to InstantiateAccessFunctionForFixedPixelType(T, (a)(b), (d)(e)) results in calls
*
* InstantiateAccessFunction_T(a, d) <br>
* InstantiateAccessFunction_T(a, e) <br>
* InstantiateAccessFunction_T(b, d) <br>
* InstantiateAccessFunction_T(b, e)
*
* That is, InstantiateAccessFunction_T is called for the cartesian product of the sequences pixelTypeSeq
* and dimSeq.
*
* Example:
* \code
* template<typename TPixel, typename VDimension>
* void MyImageAccessFunction(itk::Image<TPixel, VImageDimension>* itkImage)
* { ... }
*
* #define InstantiateAccessFunction_MyImageAccessFunction(pixelType, dim) \
* template void MyImageAccessFunction(itk::Image<pixelType,dim>*);
*
* InstantiateAccessFunctionForFixedPixelType(MyImageAccessFunction, (int), (3))
* \endcode
*
* Use this macro once after the definition of your access function.
* Some compilers have memory problems without the explicit instantiation.
* You may need to move the access function to a separate file. The CMake macro
* MITK_MULTIPLEX_PICTYPE can help you with that. See \c mitk/CMake/mitkMacroMultiplexPicType.cmake
* for documentation.
*
* \param itkImgFunc The custom part of the name of the macro to be called.
* \param pixelTypeSeq a sequence of types, like (int)(short)(char).
* \param dimSeq a sequence of dimensions, like (2)(3).
*
* \ingroup Adaptor
*/
#define InstantiateAccessFunctionForFixedType(itkImgFunc, pixelTypeSeq, dimSeq) \
MITK_PP_SEQ_FOR_EACH_PRODUCT(InstantiateAccessFunctionProductImpl, ((itkImgFunc))(pixelTypeSeq)(dimSeq))
/**
* \brief Instantiate access function for all datatypes and dimensions.
*
* \sa InstantiateAccessFunctionForFixedType
*
* \ingroup Adaptor
*/
#define InstantiateAccessFunction(itkImgFunc) \
InstantiateAccessFunctionForFixedType(itkImgFunc, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
/**
* \brief Instantiate access function for all datatypes and a specific dimension.
*
* \sa InstantiateAccessFunctionForFixedType
*
* \param itkImgFunc The custom part of the name of the macro to be called.
* \param dimSeq a sequence of dimensions, like (2)(3).
*
* \ingroup Adaptor
*/
#define InstantiateAccessFunctionForFixedDimension(itkImgFunc, dim) \
InstantiateAccessFunctionForFixedType(itkImgFunc, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ, (dim))
/**
* \brief Instantiate access function for all given pixel types and all dimensions.
*
* \sa InstantiateAccessFunctionForFixedType
*
* \param itkImgFunc The custom part of the name of the macro to be called.
* \param pixelTypeSeq a sequence of types, like (int)(short)(char).
*
* \ingroup Adaptor
*/
#define InstantiateAccessFunctionForFixedPixelType(itkImgFunc, pixelTypeSeq) \
InstantiateAccessFunctionForFixedType(itkImgFunc, pixelTypeSeq, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
/**
* \brief Instantiate access function for integral datatypes and all dimensions.
*
* \sa InstantiateAccessFunctionForFixedType
*
* \param itkImgFunc The custom part of the name of the macro to be called.
*
* \ingroup Adaptor
*/
#define InstantiateAccessFunctionForIntegralPixelTypes(itkImgFunc) \
InstantiateAccessFunctionForFixedType(itkImgFunc, MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
/**
* \brief Instantiate access function for floating point datatypes and all dimensions.
*
* \sa InstantiateAccessFunctionForFixedType
*
* \param itkImgFunc The custom part of the name of the macro to be called.
*
* \ingroup Adaptor
*/
#define InstantiateAccessFunctionForFloatingPixelTypes(itkImgFunc) \
InstantiateAccessFunctionForFixedType(itkImgFunc, MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES_SEQ, MITK_ACCESSBYITK_DIMENSIONS_SEQ)
#endif // of MITKINSTANTIATEACCESSFUNCTIONS_H_HEADER_INCLUDED
diff --git a/Core/Code/Algorithms/mitkPPArgCount.h b/Core/Code/Algorithms/mitkPPArgCount.h
index 059338d7cc..73ad03aa83 100644
--- a/Core/Code/Algorithms/mitkPPArgCount.h
+++ b/Core/Code/Algorithms/mitkPPArgCount.h
@@ -1,38 +1,37 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPPARGCOUNT_H
#define MITKPPARGCOUNT_H
#define MITK_PP_ARG_COUNT(...) \
MITK_PP_ARG_COUNT_((__VA_ARGS__, MITK_PP_RSEQ_N()))
#define MITK_PP_ARG_COUNT_(tuple) \
MITK_PP_ARG_N tuple
#define MITK_PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,N,...) N
#define MITK_PP_RSEQ_N() \
25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#endif // MITKPPARGCOUNT_H
diff --git a/Core/Code/Algorithms/mitkPixelTypeList.h b/Core/Code/Algorithms/mitkPixelTypeList.h
index 2c33db0c32..b1dbd3e1b4 100644
--- a/Core/Code/Algorithms/mitkPixelTypeList.h
+++ b/Core/Code/Algorithms/mitkPixelTypeList.h
@@ -1,194 +1,193 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <stdexcept>
namespace mitk {
struct EmptyType {};
template<
typename T0=EmptyType,
typename T1=EmptyType,
typename T2=EmptyType,
typename T3=EmptyType,
typename T4=EmptyType,
typename T5=EmptyType,
typename T6=EmptyType,
typename T7=EmptyType,
typename T8=EmptyType,
typename T9=EmptyType
> struct PixelTypeList;
template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9
> struct PixelTypeList
{
typedef T0 head;
typedef PixelTypeList<T1,T2,T3,T4,T5,T6,T7,T8,T9> tail;
enum
{
length = tail::length+1
};
};
template<>
struct PixelTypeList<EmptyType, EmptyType, EmptyType, EmptyType, EmptyType,
EmptyType, EmptyType, EmptyType, EmptyType, EmptyType>
{
enum
{
length = 0
};
};
template<typename TypeList>
struct PixelTypeLength
{
enum
{
value = TypeList::length
};
};
template<
typename TypeList,
int Index, //requested element index
int Step = 0, //current recusion step
bool Stop=(Index==Step), //stop recusion flag
bool OutOfRange = PixelTypeLength<TypeList>::value==0 //out of range flag
> struct GetPixelType
{
typedef typename GetPixelType<typename TypeList::tail, Index, Step+1>::type type;
};
//"out of range" specialization
template<
typename TypeList,
int Index,
int Step,
bool Stop
>
struct GetPixelType<TypeList, Index, Step, Stop, true>
{
//if OutOfRange is 'true' the 'type' is undefined
//so we'll get a compile-time error
};
//"element found" specialization
template<
typename TypeList,
int Index,
int Step,
bool OutOfRange
>
struct GetPixelType<TypeList, Index, Step, true, OutOfRange>
{
//the index is equal to the recursion step
//so the result type is the head of the Typlist and stop!
typedef typename TypeList::head type;
};
////////////////////////////////////////////////////////////
// run-time type switch
template<
typename TypeList,
int Index = 0,
bool Stop=(Index==PixelTypeLength<TypeList>::value)
> struct PixelTypeSwitch;
template<typename TypeList, int Index, bool Stop>
struct PixelTypeSwitch
{
template<typename F>
bool operator() (int i, F& f)
{
if( i == Index)
{
return f.operator()<typename GetPixelType<TypeList, Index>::type>();
}
else
{
PixelTypeSwitch<TypeList, Index+1> next;
return next(i, f);
}
}
};
template<typename TypeList, int Index>
struct PixelTypeSwitch<TypeList, Index, true>
{
template<typename F>
bool operator() (int, F&)
{
throw std::out_of_range("Index out of range");
}
};
template<typename X, int VDimension, typename T1 = EmptyType, typename T2 = EmptyType, typename T3 = EmptyType>
struct AccessItkImageFunctor
{
typedef void (*CallBack)(T1,T2,T3);
AccessItkImageFunctor(X* cl, CallBack callBack, const mitk::Image* mitkImage, T1 t1 = T1(), T2 t2 = T2(), T3 t3 = T3())
: cl(cl), callBack(callBack), mitkImage(mitkImage), pixelType(mitkImage->GetPixelType()),
t1(t1), t2(t2), t3(t3)
{
}
template<typename PixelType>
bool operator() ()
{
if (pixelType != typeid(PixelType)) return false;
if (mitkImage->GetDimension() != VDimension) return false;
const_cast<mitk::Image*>(mitkImage)->Update();
typedef itk::Image<PixelType, VDimension> ImageType;
typedef mitk::ImageToItk<ImageType> ImageToItkType;
itk::SmartPointer<ImageToItkType> imagetoitk = ImageToItkType::New();
imagetoitk->SetInput(mitkImage);
imagetoitk->Update();
cl->*callBack(imagetoitk->GetOutput(), t1, t2, t3);
return true;
}
private:
X* cl;
CallBack callBack;
const mitk::Image* mitkImage;
const mitk::PixelType& pixelType;
T1 t1;
T2 t2;
T3 t3;
};
} // namespace mitk
diff --git a/Core/Code/Algorithms/mitkPointSetSource.cpp b/Core/Code/Algorithms/mitkPointSetSource.cpp
index b411388d15..680870a143 100644
--- a/Core/Code/Algorithms/mitkPointSetSource.cpp
+++ b/Core/Code/Algorithms/mitkPointSetSource.cpp
@@ -1,92 +1,91 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetSource.h"
mitk::PointSetSource::PointSetSource()
{
// Create the output.
OutputType::Pointer output = dynamic_cast<OutputType*>(this->MakeOutput(0).GetPointer());
Superclass::SetNumberOfRequiredInputs(0);
Superclass::SetNumberOfRequiredOutputs(1);
Superclass::SetNthOutput(0, output.GetPointer());
}
mitk::PointSetSource::~PointSetSource()
{
}
itk::DataObject::Pointer mitk::PointSetSource::MakeOutput ( unsigned int /*idx */)
{
return OutputType::New().GetPointer();
}
void mitk::PointSetSource::SetOutput( OutputType* output )
{
itkWarningMacro(<< "SetOutput(): This method is slated to be removed from ITK. Please use GraftOutput() in possible combination with DisconnectPipeline() instead." );
this->ProcessObject::SetNthOutput( 0, output );
}
void mitk::PointSetSource::GraftOutput(OutputType *graft)
{
this->GraftNthOutput(0, graft);
}
void mitk::PointSetSource::GraftNthOutput(unsigned int /*idx*/, OutputType* /*graft*/)
{
itkWarningMacro(<< "GraftNthOutput(): This method is not yet implemented for mitk. Implement it before using!!" );
assert(false);
}
mitk::PointSetSource::OutputType* mitk::PointSetSource::GetOutput()
{
if ( this->GetNumberOfOutputs() < 1 )
{
return 0;
}
else
{
return dynamic_cast<OutputType*>
(this->BaseProcess::GetOutput(0));
}
}
mitk::PointSetSource::OutputType* mitk::PointSetSource::GetOutput ( unsigned int idx )
{
return dynamic_cast<OutputType*> ( this->ProcessObject::GetOutput( idx ) );
}
diff --git a/Core/Code/Algorithms/mitkPointSetSource.h b/Core/Code/Algorithms/mitkPointSetSource.h
index 434e353fb1..aee8a89547 100644
--- a/Core/Code/Algorithms/mitkPointSetSource.h
+++ b/Core/Code/Algorithms/mitkPointSetSource.h
@@ -1,87 +1,86 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_POINT_SET_SOURCE_H
#define _MITK_POINT_SET_SOURCE_H
#include "mitkBaseProcess.h"
#include "mitkPointSet.h"
namespace mitk
{
/**
* @brief Superclass of all classes generating point sets (instances of class
* mitk::PointSet) as output.
*
* In itk and vtk the generated result of a ProcessObject is only guaranteed
* to be up-to-date, when Update() of the ProcessObject or the generated
* DataObject is called immediately before access of the data stored in the
* DataObject.
* @ingroup Process
*/
class MITK_CORE_EXPORT PointSetSource : public BaseProcess
{
public:
mitkClassMacro( PointSetSource, BaseProcess );
itkNewMacro( Self );
typedef PointSet OutputType;
typedef OutputType::Pointer OutputTypePointer;
/**
* Allocates a new output object and returns it. Currently the
* index idx is not evaluated.
* @param idx the index of the output for which an object should be created
* @returns the new object
*/
virtual itk::DataObject::Pointer MakeOutput ( unsigned int idx );
/**
* Allows to set the output of the point set source.
* @param output the intended output of the point set source
*/
virtual void SetOutput( OutputType* output );
virtual void GraftOutput(OutputType *output);
virtual void GraftNthOutput(unsigned int idx, OutputType *output);
/**
* Returns the output with index 0 of the point set source
* @returns the output
*/
virtual OutputType* GetOutput();
/**
* Returns the n'th output of the point set source
* @param idx the index of the wanted output
* @returns the output with index idx.
*/
virtual OutputType* GetOutput ( unsigned int idx );
protected:
PointSetSource();
virtual ~PointSetSource();
};
}
#endif // #define _MITK_POINT_SET_SOURCE_H
diff --git a/Core/Code/Algorithms/mitkPointSetToPointSetFilter.cpp b/Core/Code/Algorithms/mitkPointSetToPointSetFilter.cpp
index 6e6b9e0a37..c6e29e871c 100644
--- a/Core/Code/Algorithms/mitkPointSetToPointSetFilter.cpp
+++ b/Core/Code/Algorithms/mitkPointSetToPointSetFilter.cpp
@@ -1,73 +1,71 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Module: $RCSfile$
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetToPointSetFilter.h"
mitk::PointSetToPointSetFilter::PointSetToPointSetFilter()
{
// Modify superclass default values, may be overridden by subclasses
this->SetNumberOfRequiredInputs( 1 );
}
mitk::PointSetToPointSetFilter::~PointSetToPointSetFilter()
{}
void mitk::PointSetToPointSetFilter::SetInput( const mitk::PointSetToPointSetFilter::InputType* input )
{
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput( 0, const_cast< mitk::PointSetToPointSetFilter::InputType * >( input ) );
}
void mitk::PointSetToPointSetFilter::SetInput( const unsigned int& idx, const mitk::PointSetToPointSetFilter::InputType* input )
{
if ( idx + 1 > this->GetNumberOfInputs() )
{
this->SetNumberOfRequiredInputs( idx + 1 );
}
// Process object is not const-correct so the const_cast is required here
this->ProcessObject::SetNthInput( idx, const_cast< mitk::PointSetToPointSetFilter::InputType *>( input ) );
}
const mitk::PointSetToPointSetFilter::InputType * mitk::PointSetToPointSetFilter::GetInput( void )
{
if ( this->GetNumberOfInputs() < 1 )
return 0;
// Process object is not const-correct so the const_cast is required here
return static_cast<const mitk::PointSetToPointSetFilter::InputType * >( this->ProcessObject::GetInput( 0 ) );
}
const mitk::PointSetToPointSetFilter::InputType * mitk::PointSetToPointSetFilter::GetInput( const unsigned int& idx )
{
if (idx > this->GetNumberOfInputs() - 1 )
return 0;
// Process object is not const-correct so the const_cast is required here
return static_cast< const mitk::PointSetToPointSetFilter::InputType * >(this->ProcessObject::GetInput(idx));
}
void mitk::PointSetToPointSetFilter::operator=( const mitk::PointSetToPointSetFilter::Self& )
{}
diff --git a/Core/Code/Algorithms/mitkPointSetToPointSetFilter.h b/Core/Code/Algorithms/mitkPointSetToPointSetFilter.h
index 489ef0e879..bbd45cf7d9 100644
--- a/Core/Code/Algorithms/mitkPointSetToPointSetFilter.h
+++ b/Core/Code/Algorithms/mitkPointSetToPointSetFilter.h
@@ -1,93 +1,91 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Module: $RCSfile$
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _mitkpointsettopointsetfilter_h
#define _mitkpointsettopointsetfilter_h
#include <MitkExports.h>
#include "mitkPointSetSource.h"
namespace mitk
{
/**
* @brief Superclass of all classes/algorithms having one or more PointSets
* as input and output
* @ingroup Process
*/
class MITK_CORE_EXPORT PointSetToPointSetFilter : public PointSetSource
{
public:
mitkClassMacro( PointSetToPointSetFilter, PointSetSource );
itkNewMacro( Self );
typedef mitk::PointSet InputType;
typedef mitk::PointSet OutputType;
typedef InputType::Pointer InputTypePointer;
typedef InputType::ConstPointer InputTypeConstPointer;
/**
* Sets the input of this process object
* @param input the input
*/
virtual void SetInput( const InputType* input );
/**
* Sets the input n'th of this process object
* @param idx the number associated with the given input
*/
virtual void SetInput( const unsigned int& idx, const InputType* input );
/**
* @returns the input tree of the process object
*/
const InputType * GetInput( void );
/**
* @param idx the index of the input to return
* @returns the input object with the given index
*/
const InputType * GetInput( const unsigned int& idx );
protected:
/**
* A default constructor
*/
PointSetToPointSetFilter();
/**
* The destructor
*/
virtual ~PointSetToPointSetFilter();
private:
void operator=( const Self& ); //purposely not implemented
}
;
} //end of namespace mitk
#endif
diff --git a/Core/Code/Algorithms/mitkRGBToRGBACastImageFilter.cpp b/Core/Code/Algorithms/mitkRGBToRGBACastImageFilter.cpp
index 53bc825095..dff950eadf 100644
--- a/Core/Code/Algorithms/mitkRGBToRGBACastImageFilter.cpp
+++ b/Core/Code/Algorithms/mitkRGBToRGBACastImageFilter.cpp
@@ -1,230 +1,229 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-04-23 13:50:34 +0200 (Do, 23 Apr 2009) $
-Version: $Revision: 16947 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRGBToRGBACastImageFilter.h"
#include "mitkImageTimeSelector.h"
#include "mitkProperties.h"
#include "mitkImageAccessByItk.h"
#include "mitkImageToItk.h"
#include <itkImageRegionConstIterator.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkImageIOBase.h>
#include <itkRGBAPixel.h>
mitk::RGBToRGBACastImageFilter::RGBToRGBACastImageFilter()
{
this->SetNumberOfInputs(1);
this->SetNumberOfRequiredInputs(1);
m_InputTimeSelector = mitk::ImageTimeSelector::New();
m_OutputTimeSelector = mitk::ImageTimeSelector::New();
}
mitk::RGBToRGBACastImageFilter::~RGBToRGBACastImageFilter()
{
}
bool mitk::RGBToRGBACastImageFilter::IsRGBImage( const mitk::Image *image )
{
const mitk::PixelType &inputPixelType = image->GetPixelType();
if ( (inputPixelType == typeid( UCRGBPixelType) )
|| (inputPixelType == typeid( USRGBPixelType) )
|| (inputPixelType == typeid( FloatRGBPixelType) )
|| (inputPixelType == typeid( DoubleRGBPixelType) ) )
{
return true;
}
return false;
}
void mitk::RGBToRGBACastImageFilter::GenerateInputRequestedRegion()
{
Superclass::GenerateInputRequestedRegion();
mitk::Image* output = this->GetOutput();
mitk::Image* input = const_cast< mitk::Image * > ( this->GetInput() );
if ( !output->IsInitialized() )
{
return;
}
input->SetRequestedRegionToLargestPossibleRegion();
//GenerateTimeInInputRegion(output, input);
}
void mitk::RGBToRGBACastImageFilter::GenerateOutputInformation()
{
mitk::Image::ConstPointer input = this->GetInput();
mitk::Image::Pointer output = this->GetOutput();
if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
return;
itkDebugMacro(<<"GenerateOutputInformation()");
// Initialize RGBA output with same pixel type as input image
const mitk::PixelType &inputPixelType = input->GetPixelType();
typedef itk::Image< UCRGBPixelType > UCRGBItkImageType;
typedef itk::Image< USRGBPixelType > USRGBItkImageType;
typedef itk::Image< FloatRGBPixelType > FloatCRGBItkImageType;
typedef itk::Image< DoubleRGBPixelType > DoubleRGBItkImageType;
if ( inputPixelType == typeid( UCRGBPixelType ) )
{
const mitk::PixelType refPtype = MakePixelType<UCRGBItkImageType>();
output->Initialize( refPtype, *input->GetTimeSlicedGeometry() );
}
else if ( inputPixelType == typeid( USRGBPixelType ) )
{
const mitk::PixelType refPtype = MakePixelType<USRGBItkImageType>();
output->Initialize( refPtype, *input->GetTimeSlicedGeometry() );
}
else if ( inputPixelType == typeid( FloatRGBPixelType ) )
{
const mitk::PixelType refPtype = MakePixelType<FloatCRGBItkImageType>();
output->Initialize( refPtype, *input->GetTimeSlicedGeometry() );
}
else if ( inputPixelType == typeid( DoubleRGBPixelType ) )
{
const mitk::PixelType refPtype = MakePixelType<DoubleRGBItkImageType>();
output->Initialize( refPtype, *input->GetTimeSlicedGeometry() );
}
output->SetPropertyList(input->GetPropertyList()->Clone());
m_TimeOfHeaderInitialization.Modified();
}
void mitk::RGBToRGBACastImageFilter::GenerateData()
{
mitk::Image::ConstPointer input = this->GetInput();
mitk::Image::Pointer output = this->GetOutput();
if( !output->IsInitialized() )
{
return;
}
m_InputTimeSelector->SetInput(input);
m_OutputTimeSelector->SetInput(this->GetOutput());
mitk::Image::RegionType outputRegion = output->GetRequestedRegion();
const mitk::TimeSlicedGeometry *outputTimeGeometry = output->GetTimeSlicedGeometry();
const mitk::TimeSlicedGeometry *inputTimeGeometry = input->GetTimeSlicedGeometry();
ScalarType timeInMS;
int timestep=0;
int tstart=outputRegion.GetIndex(3);
int tmax=tstart+outputRegion.GetSize(3);
int t;
for(t=tstart;t<tmax;++t)
{
timeInMS = outputTimeGeometry->TimeStepToMS( t );
timestep = inputTimeGeometry->MSToTimeStep( timeInMS );
m_InputTimeSelector->SetTimeNr(timestep);
m_InputTimeSelector->UpdateLargestPossibleRegion();
m_OutputTimeSelector->SetTimeNr(t);
m_OutputTimeSelector->UpdateLargestPossibleRegion();
mitk::Image *image = m_InputTimeSelector->GetOutput();
const mitk::PixelType &pixelType = image->GetPixelType();
// Check if the pixel type is supported
if ( pixelType == typeid( UCRGBPixelType ) )
{
AccessFixedPixelTypeByItk_2( image, InternalCast, (UCRGBPixelType), this, 255 );
}
else if ( pixelType == typeid( USRGBPixelType ) )
{
AccessFixedPixelTypeByItk_2( image, InternalCast, (USRGBPixelType), this, 65535 );
}
else if ( pixelType == typeid( FloatRGBPixelType ) )
{
AccessFixedPixelTypeByItk_2( image, InternalCast, (FloatRGBPixelType), this, 1.0 );
}
else if ( pixelType == typeid( DoubleRGBPixelType ) )
{
AccessFixedPixelTypeByItk_2( image, InternalCast, (DoubleRGBPixelType), this, 1.0 );
}
else
{
// Otherwise, write warning and graft input to output
// ...TBD...
}
}
m_TimeOfHeaderInitialization.Modified();
}
template < typename TPixel, unsigned int VImageDimension >
void mitk::RGBToRGBACastImageFilter::InternalCast(
itk::Image< TPixel, VImageDimension > *inputItkImage,
mitk::RGBToRGBACastImageFilter *addComponentFilter,
typename TPixel::ComponentType defaultAlpha )
{
typedef TPixel InputPixelType;
typedef itk::RGBAPixel< typename TPixel::ComponentType > OutputPixelType;
typedef itk::Image< InputPixelType, VImageDimension > InputImageType;
typedef itk::Image< OutputPixelType, VImageDimension > OutputImageType;
typedef itk::ImageRegionConstIterator< InputImageType > InputImageIteratorType;
typedef itk::ImageRegionIteratorWithIndex< OutputImageType > OutputImageIteratorType;
typename mitk::ImageToItk< OutputImageType >::Pointer outputimagetoitk =
mitk::ImageToItk< OutputImageType >::New();
outputimagetoitk->SetInput(addComponentFilter->m_OutputTimeSelector->GetOutput());
outputimagetoitk->Update();
typename OutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput();
// create the iterators
typename InputImageType::RegionType inputRegionOfInterest =
inputItkImage->GetLargestPossibleRegion();
InputImageIteratorType inputIt( inputItkImage, inputRegionOfInterest );
OutputImageIteratorType outputIt( outputItkImage, inputRegionOfInterest );
for ( inputIt.GoToBegin(), outputIt.GoToBegin();
!inputIt.IsAtEnd();
++inputIt, ++outputIt )
{
typename InputPixelType::Iterator pixelInputIt = inputIt.Get().Begin();
typename OutputPixelType::Iterator pixelOutputIt = outputIt.Get().Begin();
*pixelOutputIt++ = *pixelInputIt++;
*pixelOutputIt++ = *pixelInputIt++;
*pixelOutputIt++ = *pixelInputIt++;
*pixelOutputIt = defaultAlpha;
}
}
diff --git a/Core/Code/Algorithms/mitkRGBToRGBACastImageFilter.h b/Core/Code/Algorithms/mitkRGBToRGBACastImageFilter.h
index 3bbeb7edcd..0f5ab0c062 100644
--- a/Core/Code/Algorithms/mitkRGBToRGBACastImageFilter.h
+++ b/Core/Code/Algorithms/mitkRGBToRGBACastImageFilter.h
@@ -1,88 +1,87 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-13 18:06:46 +0200 (Mi, 13 Mai 2009) $
-Version: $Revision: 17258 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKRGBTORGBACASTIMAGEFILTER_H_HEADER_INCLUDED
#define MITKRGBTORGBACASTIMAGEFILTER_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkImageToImageFilter.h"
#include "mitkImageTimeSelector.h"
#include <itkRGBPixel.h>
namespace itk {
template <class TPixel, unsigned int VImageDimension> class ITK_EXPORT Image;
}
namespace mitk {
//##Documentation
//## @brief
//## @ingroup Process
class MITK_CORE_EXPORT RGBToRGBACastImageFilter : public ImageToImageFilter
{
public:
mitkClassMacro(RGBToRGBACastImageFilter, ImageToImageFilter);
itkNewMacro(Self);
/** Static convenience method to check if the passed mitk::Image is
* an RGB image in the sense of this converter filter.
*
* Returns falsefor RGBA and all other images.
*/
static bool IsRGBImage( const mitk::Image *image );
protected:
// Typedefs for supported RGB pixel types
typedef itk::RGBPixel< unsigned char > UCRGBPixelType;
typedef itk::RGBPixel< unsigned short > USRGBPixelType;
typedef itk::RGBPixel< float > FloatRGBPixelType;
typedef itk::RGBPixel< double > DoubleRGBPixelType;
RGBToRGBACastImageFilter();
~RGBToRGBACastImageFilter();
virtual void GenerateInputRequestedRegion();
virtual void GenerateOutputInformation();
virtual void GenerateData();
template < typename TPixel, unsigned int VImageDimension >
void InternalCast( itk::Image< TPixel, VImageDimension > *itkImage,
mitk::RGBToRGBACastImageFilter *addComponentFilter,
typename TPixel::ComponentType defaultAlpha );
mitk::ImageTimeSelector::Pointer m_InputTimeSelector;
mitk::ImageTimeSelector::Pointer m_OutputTimeSelector;
//##Description
//## @brief Time when Header was last initialized
itk::TimeStamp m_TimeOfHeaderInitialization;
};
} // namespace mitk
#endif /* MITKRGBTORGBACASTIMAGEFILTER_H_HEADER_INCLUDED */
diff --git a/Core/Code/Algorithms/mitkSubImageSelector.cpp b/Core/Code/Algorithms/mitkSubImageSelector.cpp
index ec3569980d..0333691df7 100644
--- a/Core/Code/Algorithms/mitkSubImageSelector.cpp
+++ b/Core/Code/Algorithms/mitkSubImageSelector.cpp
@@ -1,76 +1,75 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSubImageSelector.h"
void mitk::SubImageSelector::SetPosNr(int /*p*/)
{
}
mitk::Image::ImageDataItemPointer mitk::SubImageSelector::GetSliceData(int s, int t, int n)
{
mitk::Image::Pointer input = const_cast<mitk::Image*>(this->GetInput());
return input->GetSliceData(s,t,n);
}
mitk::Image::ImageDataItemPointer mitk::SubImageSelector::GetVolumeData(int t, int n)
{
mitk::Image::Pointer input = const_cast<mitk::Image*>(this->GetInput());
return input->GetVolumeData(t,n);
}
mitk::Image::ImageDataItemPointer mitk::SubImageSelector::GetChannelData(int n)
{
mitk::Image::Pointer input = const_cast<mitk::Image*>(this->GetInput());
return input->GetChannelData(n);
}
void mitk::SubImageSelector::SetChannelItem(mitk::Image::ImageDataItemPointer dataItem, int n)
{
mitk::Image::Pointer output = this->GetOutput();
if(output->IsValidChannel(n)==false) return;
output->m_Channels[n]=dataItem;
}
void mitk::SubImageSelector::SetVolumeItem(mitk::Image::ImageDataItemPointer dataItem, int t, int n)
{
mitk::Image::Pointer output = this->GetOutput();
if(output->IsValidVolume(t,n)==false) return;
int pos;
pos=output->GetVolumeIndex(t,n);
output->m_Volumes[pos]=dataItem;
}
void mitk::SubImageSelector::SetSliceItem(mitk::Image::ImageDataItemPointer dataItem, int s, int t, int n)
{
mitk::Image::Pointer output = this->GetOutput();
if(output->IsValidSlice(s,t,n)==false) return;
int pos;
pos=output->GetSliceIndex(s,t,n);
output->m_Slices[pos]=dataItem;
}
mitk::SubImageSelector::SubImageSelector()
{
}
mitk::SubImageSelector::~SubImageSelector()
{
}
diff --git a/Core/Code/Algorithms/mitkSubImageSelector.h b/Core/Code/Algorithms/mitkSubImageSelector.h
index c37deed11b..ef94f946b0 100644
--- a/Core/Code/Algorithms/mitkSubImageSelector.h
+++ b/Core/Code/Algorithms/mitkSubImageSelector.h
@@ -1,63 +1,62 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 SUBIMAGESELECTOR_H_HEADER_INCLUDED_C1E4F463
#define SUBIMAGESELECTOR_H_HEADER_INCLUDED_C1E4F463
#include <MitkExports.h>
#include "mitkImageToImageFilter.h"
#include "mitkImageDataItem.h"
#include "mitkBaseData.h"
namespace mitk {
//##Documentation
//## @brief Base class of all classes providing access to parts of an image
//##
//## Base class of all classes providing access to parts of an image, e.g., to
//## a slice (mitk::ImageSilceSelector) or a volume at a specific time
//## (mitk::ImageTimeSelector). If the input is generated by a ProcessObject,
//## only the required data is requested.
//## @ingroup Process
class MITK_CORE_EXPORT SubImageSelector : public ImageToImageFilter
{
public:
/** Run-time type information (and related methods). */
mitkClassMacro(SubImageSelector,ImageToImageFilter);
itkNewMacro(Self);
virtual void SetPosNr(int p);
SubImageSelector();
virtual ~SubImageSelector();
protected:
mitk::Image::ImageDataItemPointer GetSliceData(int s = 0, int t = 0, int n = 0);
mitk::Image::ImageDataItemPointer GetVolumeData(int t = 0, int n = 0);
mitk::Image::ImageDataItemPointer GetChannelData(int n = 0);
void SetSliceItem(mitk::Image::ImageDataItemPointer dataItem, int s = 0, int t = 0, int n = 0);
void SetVolumeItem(mitk::Image::ImageDataItemPointer dataItem, int t = 0, int n = 0);
void SetChannelItem(mitk::Image::ImageDataItemPointer dataItem, int n = 0);
};
} // namespace mitk
#endif /* SUBIMAGESELECTOR_H_HEADER_INCLUDED_C1E4F463 */
diff --git a/Core/Code/Algorithms/mitkSurfaceSource.cpp b/Core/Code/Algorithms/mitkSurfaceSource.cpp
index 76209ac7d7..13b8a7c649 100644
--- a/Core/Code/Algorithms/mitkSurfaceSource.cpp
+++ b/Core/Code/Algorithms/mitkSurfaceSource.cpp
@@ -1,91 +1,90 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurfaceSource.h"
#include "mitkSurface.h"
mitk::SurfaceSource::SurfaceSource()
{
// Create the output. We use static_cast<> here because we know the default
// output must be of type TOutputImage
mitk::Surface::Pointer output
= static_cast<mitk::Surface*>(this->MakeOutput(0).GetPointer());
Superclass::SetNumberOfRequiredOutputs(1);
Superclass::SetNthOutput(0, output.GetPointer());
}
mitk::SurfaceSource::~SurfaceSource()
{
}
mitk::SurfaceSource::DataObjectPointer mitk::SurfaceSource::MakeOutput(unsigned int /*idx*/)
{
return static_cast<itk::DataObject*>(mitk::Surface::New().GetPointer());
}
mitk::Surface* mitk::SurfaceSource::GetOutput()
{
if (this->GetNumberOfOutputs() < 1)
{
return 0;
}
return static_cast<mitk::Surface*>
(this->BaseProcess::GetOutput(0));
}
mitk::Surface* mitk::SurfaceSource::GetOutput(unsigned int idx)
{
return static_cast<mitk::Surface*>
(this->ProcessObject::GetOutput(idx));
}
void mitk::SurfaceSource::SetOutput(mitk::Surface* output)
{
itkWarningMacro(<< "SetOutput(): This method is slated to be removed from ITK. Please use GraftOutput() in possible combination with DisconnectPipeline() instead." );
BaseProcess::SetNthOutput(0, output);
}
void mitk::SurfaceSource::GraftOutput(mitk::Surface* graft)
{
this->GraftNthOutput(0, graft);
}
void mitk::SurfaceSource::GraftNthOutput(unsigned int idx, mitk::Surface *graft)
{
if (idx < this->GetNumberOfOutputs())
{
mitk::Surface * output = this->GetOutput(idx);
if (output && graft)
{
// grab a handle to the bulk data of the specified data object
// output->SetPixelContainer( graft->GetPixelContainer() ); @FIXME!!!!
// copy the region ivars of the specified data object
output->SetRequestedRegion( graft );//graft->GetRequestedRegion() );
// output->SetLargestPossibleRegion( graft->GetLargestPossibleRegion() ); @FIXME!!!!
// output->SetBufferedRegion( graft->GetBufferedRegion() ); @FIXME!!!!
// copy the meta-information
output->CopyInformation( graft );
}
}
}
diff --git a/Core/Code/Algorithms/mitkSurfaceSource.h b/Core/Code/Algorithms/mitkSurfaceSource.h
index 1baa378dfa..57cf50bcd8 100644
--- a/Core/Code/Algorithms/mitkSurfaceSource.h
+++ b/Core/Code/Algorithms/mitkSurfaceSource.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSURFACEDATASOURCE_H_HEADER_INCLUDED_C10B4740
#define MITKSURFACEDATASOURCE_H_HEADER_INCLUDED_C10B4740
#include "mitkBaseProcess.h"
namespace mitk {
class Surface;
//##Documentation
//## @brief Superclass of all classes generating surfaces (instances of class
//## Surface) as output.
//##
//## In itk and vtk the generated result of a ProcessObject is only guaranteed
//## to be up-to-date, when Update() of the ProcessObject or the generated
//## DataObject is called immediately before access of the data stored in the
//## DataObject. This is also true for subclasses of mitk::BaseProcess and thus
//## for mitk::SurfaceSource.
//## @ingroup Process
class MITK_CORE_EXPORT SurfaceSource : public BaseProcess
{
public:
mitkClassMacro(SurfaceSource, BaseProcess);
itkNewMacro(Self);
typedef itk::DataObject::Pointer DataObjectPointer;
virtual DataObjectPointer MakeOutput(unsigned int idx);
void SetOutput(mitk::Surface* output);
mitk::Surface* GetOutput();
mitk::Surface* GetOutput(unsigned int idx);
virtual void GraftOutput(mitk::Surface* graft);
virtual void GraftNthOutput(unsigned int idx, mitk::Surface *graft);
protected:
SurfaceSource();
virtual ~SurfaceSource();
};
} // namespace mitk
#endif /* MITKSURFACEDATASOURCE_H_HEADER_INCLUDED_C10B4740 */
diff --git a/Core/Code/Algorithms/mitkSurfaceToSurfaceFilter.cpp b/Core/Code/Algorithms/mitkSurfaceToSurfaceFilter.cpp
index 8cfcdac91f..4a08e9e4f9 100644
--- a/Core/Code/Algorithms/mitkSurfaceToSurfaceFilter.cpp
+++ b/Core/Code/Algorithms/mitkSurfaceToSurfaceFilter.cpp
@@ -1,86 +1,85 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
-Version: $Revision: 17179 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurfaceToSurfaceFilter.h"
#include "mitkSurface.h"
mitk::SurfaceToSurfaceFilter::SurfaceToSurfaceFilter()
: SurfaceSource()
{
}
mitk::SurfaceToSurfaceFilter::~SurfaceToSurfaceFilter()
{
}
void mitk::SurfaceToSurfaceFilter::SetInput( const mitk::Surface* surface )
{
this->SetInput( 0, const_cast<mitk::Surface*>( surface ) );
}
void mitk::SurfaceToSurfaceFilter::SetInput( unsigned int idx, const mitk::Surface* surface )
{
if ( this->GetInput(idx) != surface )
{
this->SetNthInput( idx, const_cast<mitk::Surface*>( surface ) );
this->CreateOutputsForAllInputs(idx);
this->Modified();
}
}
const mitk::Surface* mitk::SurfaceToSurfaceFilter::GetInput()
{
if (this->GetNumberOfInputs() < 1)
return NULL;
return static_cast<const mitk::Surface*>(this->ProcessObject::GetInput(0));
}
const mitk::Surface* mitk::SurfaceToSurfaceFilter::GetInput( unsigned int idx)
{
if (this->GetNumberOfInputs() < 1)
return NULL;
return static_cast<const mitk::Surface*>(this->ProcessObject::GetInput(idx));
}
void mitk::SurfaceToSurfaceFilter::CreateOutputsForAllInputs(unsigned int /*idx*/)
{
this->SetNumberOfOutputs( this->GetNumberOfInputs() );
for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx)
{
if (this->GetOutput(idx) == NULL)
{
DataObjectPointer newOutput = this->MakeOutput(idx);
this->SetNthOutput(idx, newOutput);
}
this->GetOutput( idx )->Graft( this->GetInput( idx) );
}
this->Modified();
}
void mitk::SurfaceToSurfaceFilter::RemoveInputs(mitk::Surface* input)
{
this->RemoveInput(input);
}
\ No newline at end of file
diff --git a/Core/Code/Algorithms/mitkSurfaceToSurfaceFilter.h b/Core/Code/Algorithms/mitkSurfaceToSurfaceFilter.h
index c52add0948..fc870f7569 100644
--- a/Core/Code/Algorithms/mitkSurfaceToSurfaceFilter.h
+++ b/Core/Code/Algorithms/mitkSurfaceToSurfaceFilter.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
-Version: $Revision: 17179 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSURFACETOSURFACEFILTER_H_HEADER_INCLUDED_C10B4740
#define MITKSURFACETOSURFACEFILTER_H_HEADER_INCLUDED_C10B4740
#include "mitkSurfaceSource.h"
namespace mitk {
class Surface;
//##Documentation
//## @brief Superclass of all classes getting surfaces (instances of class
//## Surface) as input and generating surfaces as output.
//##
//## In itk and vtk the generated result of a ProcessObject is only guaranteed
//## to be up-to-date, when Update() of the ProcessObject or the generated
//## DataObject is called immediately before access of the data stored in the
//## DataObject. This is also true for subclasses of mitk::BaseProcess and thus
//## for mitk::mitkSurfaceToSurfaceFilter.
//## @ingroup Process
class MITK_CORE_EXPORT SurfaceToSurfaceFilter : public mitk::SurfaceSource
{
public:
mitkClassMacro(SurfaceToSurfaceFilter, mitk::SurfaceSource);
itkNewMacro(Self);
typedef itk::DataObject::Pointer DataObjectPointer;
virtual void SetInput( const mitk::Surface* surface );
virtual void SetInput( unsigned int idx, const mitk::Surface* surface );
virtual const mitk::Surface* GetInput();
virtual const mitk::Surface* GetInput( unsigned int idx );
virtual void CreateOutputsForAllInputs(unsigned int idx);
virtual void RemoveInputs(mitk::Surface* input);
protected:
SurfaceToSurfaceFilter();
virtual ~SurfaceToSurfaceFilter();
};
} // namespace mitk
#endif /* MITKSURFACETOSURFACEFILTER_H_HEADER_INCLUDED_C10B4740 */
diff --git a/Core/Code/Algorithms/mitkUIDGenerator.cpp b/Core/Code/Algorithms/mitkUIDGenerator.cpp
index 4d5be7d6bd..659bb2d0af 100644
--- a/Core/Code/Algorithms/mitkUIDGenerator.cpp
+++ b/Core/Code/Algorithms/mitkUIDGenerator.cpp
@@ -1,84 +1,83 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkUIDGenerator.h>
#include <mitkLogMacros.h>
#include <ctime>
#include <cstdlib>
#include <sstream>
#include <math.h>
#include <stdexcept>
#include <iostream>
namespace mitk {
UIDGenerator::UIDGenerator(const char* prefix, unsigned int lengthOfRandomPart)
:m_Prefix(prefix),
m_LengthOfRandomPart(lengthOfRandomPart)
{
if (lengthOfRandomPart < 5)
{
MITK_ERROR << lengthOfRandomPart << " are not really unique, right?" << std::endl;
throw std::invalid_argument("To few digits requested");
}
std::srand((unsigned int) time( (time_t *)0 ));
}
std::string UIDGenerator::GetUID()
{
std::ostringstream s;
s << m_Prefix;
time_t tt = time(0);
tm* t = gmtime(&tt);
if (t)
{
s << t->tm_year + 1900;
if (t->tm_mon < 9) s << "0"; // add a 0 for months 1 to 9
s << t->tm_mon + 1;
if (t->tm_mday < 10) s << "0"; // add a 0 for days 1 to 9
s << t->tm_mday;
if (t->tm_hour < 10) s << "0"; // add a 0 for hours 1 to 9
s << t->tm_hour;
if (t->tm_min < 10) s << "0"; // add a 0 for minutes 1 to 9
s << t->tm_min;
if (t->tm_sec < 10) s << "0"; // add a 0 for seconds 1 to 9
s << t->tm_sec;
std::ostringstream rs;
rs << (long int)( pow(10.0, double(m_LengthOfRandomPart)) / double(RAND_MAX) * double(rand()) );
for (size_t i = rs.str().length(); i < m_LengthOfRandomPart; ++i)
{
s << "X";
}
s << rs.str();
}
return s.str();
}
}
diff --git a/Core/Code/Algorithms/mitkUIDGenerator.h b/Core/Code/Algorithms/mitkUIDGenerator.h
index 0549a17a4b..417de7c4f4 100644
--- a/Core/Code/Algorithms/mitkUIDGenerator.h
+++ b/Core/Code/Algorithms/mitkUIDGenerator.h
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITK_UID_GENERATOR_INDCLUDED_FASAWE
#define MITK_UID_GENERATOR_INDCLUDED_FASAWE
#include<string>
#include <MitkExports.h>
namespace mitk {
/*!
\brief Generated unique IDs
Creates (somehow most of the time) unique IDs from a given prefix,
the current date/time and a random part.
The prefix is given to the constructor, together with the desired
length of the random part (minimum 5 digits).
You will get another quite unique ID each time you call GetUID.
*/
class MITK_CORE_EXPORT UIDGenerator
{
public:
UIDGenerator(const char* prefix = "UID_", unsigned int lengthOfRandomPart = 8);
std::string GetUID();
private:
std::string m_Prefix;
unsigned int m_LengthOfRandomPart;
};
}
#endif
diff --git a/Core/Code/Algorithms/mitkVolumeCalculator.cpp b/Core/Code/Algorithms/mitkVolumeCalculator.cpp
index 4360560e34..e09b14eb89 100644
--- a/Core/Code/Algorithms/mitkVolumeCalculator.cpp
+++ b/Core/Code/Algorithms/mitkVolumeCalculator.cpp
@@ -1,123 +1,122 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVolumeCalculator.h"
#include "mitkImageAccessByItk.h"
#include <itkImageRegionConstIterator.h>
#include "mitkImageStatisticsHolder.h"
template < typename TPixel, unsigned int VImageDimension >
void mitk::VolumeCalculator::InternalCompute(itk::Image< TPixel, VImageDimension >* itkImage)
{
itk::ImageRegionConstIterator<itk::Image < TPixel, VImageDimension > > imageIt(itkImage, itkImage->GetLargestPossibleRegion() );
unsigned long int count = 0;
for (imageIt.GoToBegin(); !imageIt.IsAtEnd(); ++imageIt)
{
if ( (int)(imageIt.Get()) >= m_Threshold )
{
count++;
}
}
if (itkImage->GetLargestPossibleRegion().GetImageDimension() == 3)
{
m_Volume = count / 1000.0 * itkImage->GetSpacing()[0] * itkImage->GetSpacing()[1] * itkImage->GetSpacing()[2];
}
else if (itkImage->GetLargestPossibleRegion().GetImageDimension() == 2)
{
m_Volume = count / 100.0 * itkImage->GetSpacing()[0] * itkImage->GetSpacing()[1];
}
m_VoxelCount = count;
}
mitk::VolumeCalculator::VolumeCalculator()
: m_Image(NULL),
m_Threshold(0),
m_Volume(0)
{
m_TimeSelector = ImageTimeSelector::New();
}
mitk::VolumeCalculator::~VolumeCalculator()
{
}
std::vector<float> mitk::VolumeCalculator::GetVolumes()
{
return m_Volumes;
}
void mitk::VolumeCalculator::ComputeVolume()
{
const_cast<Image*>(m_Image.GetPointer())->SetRequestedRegionToLargestPossibleRegion();
if (m_Image->GetDimension() == 4)
{
m_TimeSelector->SetInput(m_Image);
m_Volumes.resize(m_Image->GetDimension(3));
for (unsigned int timeStep = 0; timeStep<m_Image->GetDimension(3); ++timeStep)
{
m_TimeSelector->SetTimeNr(timeStep);
m_TimeSelector->Update();
AccessFixedDimensionByItk(m_TimeSelector->GetOutput(),InternalCompute,3);
m_Volumes[timeStep] = m_Volume;
}
}
else if (m_Image->GetDimension() == 3)
{
const_cast<Image*>(m_Image.GetPointer())->Update();
AccessFixedDimensionByItk(m_Image,InternalCompute,3);
}
else if (m_Image->GetDimension() == 2)
{
const_cast<Image*>(m_Image.GetPointer())->Update();
AccessFixedDimensionByItk(m_Image,InternalCompute,2);
}
}
void mitk::VolumeCalculator::ComputeVolumeFromImageStatistics()
{
unsigned int dim = m_Image->GetDimension();
if(dim == 4)
{
m_Volumes.resize(m_Image->GetDimension(3),0);
Vector3D spacing = m_Image->GetSlicedGeometry()->GetSpacing();
for(unsigned int t = 0; t < m_Image->GetDimension(3); ++t )
{
m_Volumes[t] = m_Image->GetStatistics()->GetCountOfMaxValuedVoxels(t) / 1000.0 * spacing[0] * spacing[1] * spacing[2];
}
}
else if(dim == 3)
{
Vector3D spacing = m_Image->GetSlicedGeometry()->GetSpacing();
m_Volume = m_Image->GetStatistics()->GetCountOfMaxValuedVoxels() / 1000.0 * spacing[0] * spacing[1] * spacing[2];
}
else if (dim == 2)
{
Vector3D spacing = m_Image->GetGeometry()->GetSpacing();
m_Volume = m_Image->GetStatistics()->GetCountOfMaxValuedVoxels() / 100.0 * spacing[0] * spacing[1];
}
else itkExceptionMacro(<<"Wrong image dimension...");
}
float mitk::VolumeCalculator::ComputeVolume(Vector3D spacing, unsigned int voxelCount)
{
return (voxelCount / 1000.0 * spacing[0] * spacing[1] * spacing[2]);
}
diff --git a/Core/Code/Algorithms/mitkVolumeCalculator.h b/Core/Code/Algorithms/mitkVolumeCalculator.h
index d525b16f64..86de99fd51 100644
--- a/Core/Code/Algorithms/mitkVolumeCalculator.h
+++ b/Core/Code/Algorithms/mitkVolumeCalculator.h
@@ -1,74 +1,73 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 VOLUME_CALCULATOR_H_HEADER_INCLUDED
#define VOLUME_CALCULATOR_H_HEADER_INCLUDED
#include "itkObject.h"
#include "itkObjectFactory.h"
#include "itkImage.h"
#include <MitkExports.h>
#include "mitkImage.h"
#include "mitkImageTimeSelector.h"
namespace mitk
{
/**
* @brief Calculates the volume of a mitk::Image.
* The given volume is in milliliters or as a voxel count.
* Voxels are counted if their gray value is above a threshold (see SetThreshold), the default threshold is 0.
*
* The filter works for 2D, 3D and 3D+t. In the 3D+t case a vector of volumes is provided (see GetVolumes()).
*/
class MITK_CORE_EXPORT VolumeCalculator : public itk::Object
{
public:
mitkClassMacro(VolumeCalculator,itk::Object);
itkNewMacro(Self);
itkSetObjectMacro(Image,Image);
itkSetMacro(Threshold,int);
itkGetMacro(Volume,float);
itkGetMacro(VoxelCount,unsigned long int);
std::vector<float> GetVolumes();
void ComputeVolume();
void ComputeVolumeFromImageStatistics();
static float ComputeVolume(Vector3D spacing, unsigned int voxelCount);
protected:
VolumeCalculator();
virtual ~VolumeCalculator();
template < typename TPixel, unsigned int VImageDimension >
void InternalCompute(itk::Image< TPixel, VImageDimension >* itkImage);
Image::ConstPointer m_Image;
int m_Threshold;
float m_Volume;
unsigned long int m_VoxelCount;
std::vector<float> m_Volumes;
ImageTimeSelector::Pointer m_TimeSelector;
};
} // namespace mitk
#endif /* VOLUME_CALCULATOR_H_HEADER_INCLUDED */
diff --git a/Core/Code/Common/mitkException.cpp b/Core/Code/Common/mitkException.cpp
index ef21755136..150ced1897 100644
--- a/Core/Code/Common/mitkException.cpp
+++ b/Core/Code/Common/mitkException.cpp
@@ -1,18 +1,17 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkException.h"
\ No newline at end of file
diff --git a/Core/Code/Common/mitkException.h b/Core/Code/Common/mitkException.h
index 78894ca838..56ceb03923 100644
--- a/Core/Code/Common/mitkException.h
+++ b/Core/Code/Common/mitkException.h
@@ -1,89 +1,88 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKEXCEPTION_H_INCLUDED
#define MITKEXCEPTION_H_INCLUDED
#include <MitkExports.h>
#include <itkExceptionObject.h>
namespace mitk {
/**Documentation
* \brief An object of this class represents an exception of MITK.
* Please don't instantiate exceptions manually, but use the
* exception macros (file mitkExceptionMacro.h) instead.
* Simple use in your code is:
*
* mitkThrow() << "optional exception message";
*
* You can also define specialized exceptions which must inherit
* from this class. Please always use the mitkExceptionClassMacro
* when implementing specialized exceptions. A simple implementation
* can look like:
*
* class MyException : public mitk::Exception
* {
* public:
* mitkExceptionClassMacro(MyException,mitk::Exception);
* };
*
* You can then throw your specialized exceptions by using the macro
*
* mitkThrowException(MyException) << "optional exception message";
*/
class MITK_CORE_EXPORT Exception : public itk::ExceptionObject
{
public:
Exception(const char *file, unsigned int lineNumber=0,
const char *desc="None", const char *loc="Unknown") :
itk::ExceptionObject(file,lineNumber,desc,loc){}
virtual ~Exception() throw() {}
itkTypeMacro(ClassName, SuperClassName);
/** \brief Definition of the bit shift operator for this class.*/
template <class T> inline Exception& operator<<(const T& data)
{
std::stringstream ss;
ss << this->GetDescription() << data;
this->SetDescription(ss.str());
return *this;
}
/** \brief Definition of the bit shift operator for this class (for non const data).*/
template <class T> inline Exception& operator<<(T& data)
{
std::stringstream ss;
ss << this->GetDescription() << data;
this->SetDescription(ss.str());
return *this;
}
/** \brief Definition of the bit shift operator for this class (for functions).*/
inline Exception& operator<<(std::ostream& (*func)(std::ostream&))
{
std::stringstream ss;
ss << this->GetDescription() << func;
this->SetDescription(ss.str());
return *this;
}
};
} // namespace mitk
#endif
diff --git a/Core/Code/Common/mitkExceptionMacro.h b/Core/Code/Common/mitkExceptionMacro.h
index 0d36241432..516776c735 100644
--- a/Core/Code/Common/mitkExceptionMacro.h
+++ b/Core/Code/Common/mitkExceptionMacro.h
@@ -1,77 +1,76 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITK_EXCEPTIONMACRO_H_DEFINED
#define MITK_EXCEPTIONMACRO_H_DEFINED
#include <itkMacro.h>
#include <mitkLogMacros.h>
#include <sstream>
#include "mitkException.h"
/** The exception macro is used to print error information / throw an exception
* (i.e., usually a condition that results in program failure).
*
* Example usage looks like:
* mitkThrow() << "this is error info";
*/
#define mitkThrow() throw mitk::Exception(__FILE__,__LINE__,"",ITK_LOCATION)
/** The specialized exception macro is used to print error information / throw exceptions
* in cases of specialized errors. This means the second parameter must be a class which
* inherits from mitk::Exception. An object of this exception is thrown when using the macro.
* Thus, more differentiated excaptions can be thrown, when needed.
*
* Example usage:
* mitkSpecializedExceptionMacro(mitk::MySpecializedException) << "this is error info";
*/
#define mitkThrowException(classname) throw classname(__FILE__,__LINE__,"",ITK_LOCATION)
/** Class macro for MITK exception classes.
* All MITK exception classes should derive from MITK::Exception.
*/
#define mitkExceptionClassMacro(ClassName,SuperClassName) \
ClassName(const char *file, unsigned int lineNumber, const char *desc, const char *loc) :\
SuperClassName(file,lineNumber,desc,loc){}\
itkTypeMacro(ClassName, SuperClassName);\
/** \brief Definition of the bit shift operator for this class. It can be used to add messages.*/\
template <class T> inline ClassName& operator<<(const T& data)\
{\
std::stringstream ss;\
ss << this->GetDescription() << data;\
this->SetDescription(ss.str());\
return *this;\
}\
/** \brief Definition of the bit shift operator for this class (for non const data).*/\
template <class T> inline ClassName& operator<<(T& data)\
{\
std::stringstream ss;\
ss << this->GetDescription() << data;\
this->SetDescription(ss.str());\
return *this;\
}\
/** \brief Definition of the bit shift operator for this class (for functions).*/\
inline ClassName& operator<<(std::ostream& (*func)(std::ostream&))\
{\
std::stringstream ss;\
ss << this->GetDescription() << func;\
this->SetDescription(ss.str());\
return *this;\
}\
#endif
\ No newline at end of file
diff --git a/Core/Code/Controllers/mitkBaseController.cpp b/Core/Code/Controllers/mitkBaseController.cpp
index 4fcabe3b17..d5a74dc066 100644
--- a/Core/Code/Controllers/mitkBaseController.cpp
+++ b/Core/Code/Controllers/mitkBaseController.cpp
@@ -1,40 +1,39 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkBaseController.h"
#include "mitkBaseRenderer.h"
mitk::BaseController::BaseController(const char * type) : StateMachine(type), m_LastUpdateTime(0)
{
m_Slice = Stepper::New();
m_Time = Stepper::New();
}
mitk::BaseController::~BaseController()
{
}
mitk::Stepper* mitk::BaseController::GetSlice()
{
return m_Slice.GetPointer();
}
mitk::Stepper* mitk::BaseController::GetTime()
{
return m_Time.GetPointer();
}
diff --git a/Core/Code/Controllers/mitkBaseController.h b/Core/Code/Controllers/mitkBaseController.h
index 89c43502d5..37bfb9925f 100644
--- a/Core/Code/Controllers/mitkBaseController.h
+++ b/Core/Code/Controllers/mitkBaseController.h
@@ -1,81 +1,80 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 BASECONTROLLER_H_HEADER_INCLUDED_C1E745A3
#define BASECONTROLLER_H_HEADER_INCLUDED_C1E745A3
#include <MitkExports.h>
#include "mitkStepper.h"
#include "mitkStateMachine.h"
#include <itkObjectFactory.h>
namespace mitk {
class BaseRenderer;
//##Documentation
//## @brief Baseclass for renderer slice-/camera-control
//##
//## Tells the render (subclass of BaseRenderer) which slice (subclass
//## SliceNavigationController) or from which direction (subclass
//## CameraController) it has to render. Contains two Stepper for stepping
//## through the slices or through different camera views (e.g., for the
//## creation of a movie around the data), respectively, and through time, if
//## there is 3D+t data.
//## @note not yet implemented
//## @ingroup NavigationControl
class MITK_CORE_EXPORT BaseController : public StateMachine
{
public:
/** Standard class typedefs. */
mitkClassMacro(BaseController, StateMachine);
itkNewMacro(Self);
/** Method for creation through ::New */
mitkNewMacro1Param(Self, const char *);
//##Documentation
//## @brief Get the Stepper through the slices
mitk::Stepper* GetSlice();
//##Documentation
//## @brief Get the Stepper through the time
mitk::Stepper* GetTime();
protected:
/**
* @brief Default Constructor
**/
BaseController(const char * type = NULL);
/**
* @brief Default Destructor
**/
virtual ~BaseController();
//## @brief Stepper through the time
Stepper::Pointer m_Time;
//## @brief Stepper through the slices
Stepper::Pointer m_Slice;
unsigned long m_LastUpdateTime;
};
} // namespace mitk
#endif /* BASECONTROLLER_H_HEADER_INCLUDED_C1E745A3 */
diff --git a/Core/Code/Controllers/mitkCallbackFromGUIThread.cpp b/Core/Code/Controllers/mitkCallbackFromGUIThread.cpp
index 84d1900946..d352984711 100644
--- a/Core/Code/Controllers/mitkCallbackFromGUIThread.cpp
+++ b/Core/Code/Controllers/mitkCallbackFromGUIThread.cpp
@@ -1,58 +1,57 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkCallbackFromGUIThread.h"
#include <mitkLogMacros.h>
mitk::CallbackFromGUIThread* mitk::CallbackFromGUIThread::m_Instance = NULL;
mitk::CallbackFromGUIThreadImplementation* mitk::CallbackFromGUIThread::m_Implementation = NULL;
namespace mitk {
CallbackFromGUIThread::CallbackFromGUIThread()
{
}
CallbackFromGUIThread* CallbackFromGUIThread::GetInstance()
{
if (!m_Instance)
{
m_Instance = new CallbackFromGUIThread();
}
return m_Instance;
}
void CallbackFromGUIThread::RegisterImplementation(CallbackFromGUIThreadImplementation* implementation)
{
m_Implementation = implementation;
}
void CallbackFromGUIThread::CallThisFromGUIThread(itk::Command* cmd, itk::EventObject* e)
{
if (m_Implementation)
{
m_Implementation->CallThisFromGUIThread(cmd, e);
}
else
{
MITK_ERROR << "in mitk::CallbackFromGUIThread::CallbackFromGUIThread(): no implementation registered." << std::endl;
}
}
} // namespace
diff --git a/Core/Code/Controllers/mitkCallbackFromGUIThread.h b/Core/Code/Controllers/mitkCallbackFromGUIThread.h
index 90e44c8155..dc91892d6f 100644
--- a/Core/Code/Controllers/mitkCallbackFromGUIThread.h
+++ b/Core/Code/Controllers/mitkCallbackFromGUIThread.h
@@ -1,205 +1,204 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 MITK_CALLBACK_WITHIN_GUI_TREAD_H_INCLUDGEWQ
#define MITK_CALLBACK_WITHIN_GUI_TREAD_H_INCLUDGEWQ
#include<itkCommand.h>
#include <itkEventObject.h>
#include <MitkExports.h>
namespace mitk
{
/*!
\brief Used by CallbackFromGUIThread to pass parameters.
*/
template <class T>
class CallbackEventOneParameter : public itk::AnyEvent
{
public:
typedef CallbackEventOneParameter Self;
typedef itk::AnyEvent Superclass;
CallbackEventOneParameter(const T t )
: m_Data(t) {}
virtual ~CallbackEventOneParameter() {}
virtual const char * GetEventName() const
{
return "CallbackEventOneParameter";
}
virtual bool CheckEvent(const ::itk::EventObject* e) const
{
return dynamic_cast<const Self*>(e);
}
virtual ::itk::EventObject* MakeObject() const
{
return new Self( m_Data );
}
const T GetData() const
{
return m_Data;
}
CallbackEventOneParameter(const Self& s) : itk::AnyEvent(s), m_Data(s.m_Data) {};
protected:
const T m_Data;
private:
void operator=(const Self&);
};
/*!
\brief Toolkit specific implementation of mitk::CallbackFromGUIThread
For any toolkit, this class has to be sub-classed. One instance of that sub-class has to
be registered with mitk::CallbackFromGUIThread. See the (very simple) implmentation of
QmitkCallbackFromGUIThread for an example.
*/
class MITK_CORE_EXPORT CallbackFromGUIThreadImplementation
{
public:
/// Change the current application cursor
virtual void CallThisFromGUIThread(itk::Command*, itk::EventObject*) = 0;
virtual ~CallbackFromGUIThreadImplementation() {};
protected:
private:
};
/*!
\brief Allows threads to call some method from within the GUI thread.
This class is useful for use with GUI toolkits that are not thread-safe, e.g. Qt. Any thread that
needs to work with the GUI at some time during its execution (e.g. at the end, to display some results)
can use this class to ask for a call to a member function from the GUI thread.
<b>Usage example</b>
We assume that you have a class ThreadedClass, that basically lives in a thread that is different
from the GUI thread. Now this class has to change some element of the GUI to indicate its status.
This could be dangerous (with Qt it is for sure).
The solution is, that ThreadedClass asks mitk::CallbackFromGUIThread to call a method from the GUI
thread (main thread).
Here is part of the header of ThreadedClass:
\code
class ThreadedClass : public ParentClass
{
public:
... // All you need
// This function runs in its own thread !
void ThreadedFunction();
// This should be called from the GUI thread
void ChangeGUIElementsToIndicateProgress(const itk::EventObject&);
...
};
\endcode
\code
#include "mitkCallbackFromGUIThread.h"
#include <itkCommand.h>
// This method runs in a thread of its own! So it can't manipulate GUI elements directly without causing trouble
void ThreadedClass::ThreadedFunction()
{
...
// Create a command object (passing parameters comes later)
itk::ReceptorMemberCommand<ThreadedClass>::Pointer command = itk::ReceptorMemberCommand<ThreadedClass>::New();
command->SetCallbackFunction(this, &ThreadedClass::ChangeGUIElementsToIndicateProgress);
// Ask to execute that command from the GUI thread
mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(command);
...
}
// Do dangerous GUI changing stuff here
void ThreadedClass::ChangeGUIElementsToIndicateProgress(const itk::EventObject& e)
{
Application::GetButtonGrid()->AddButton("Stop"); // this is pseudo code
}
\endcode
This obviously won't allow you to pass parameters to ChangeGUIElementsToIndicateProgress. If you need to do that,
you have to create a kind of itk::EventObject that can be asked for a parameter (this solution is not nice, if you see
a better solution, please mail to mitk-users@lists.sourceforge.net).
The itk::EventObject has to be created with "new" (which can also be done by calling MakeObject on an existing EventObject).
\code
const mitk::OneParameterEvent* event = new mitk::OneParameterEvent(1); // this class is not yet defined but will be
itk::ReceptorMemberCommand<ThreadedClass>::Pointer command = itk::ReceptorMemberCommand<ThreadedClass>::New();
command->SetCallbackFunction(this, &ThreadedClass::ChangeGUIElementsToIndicateProgress);
mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(command, event);
// DO NOT delete event now. This will be done by CallThisFromGUIThread after the command will executed.
\endcode
\todo Create a set of "normal" parameter-event-objects that people might want to use.
*/
class MITK_CORE_EXPORT CallbackFromGUIThread
{
public:
/// This class is a singleton.
static CallbackFromGUIThread* GetInstance();
/// To be called by a toolkit specific CallbackFromGUIThreadImplementation.
static void RegisterImplementation(CallbackFromGUIThreadImplementation* implementation);
/// Change the current application cursor
void CallThisFromGUIThread(itk::Command*, itk::EventObject* e = NULL);
protected:
/// Purposely hidden - singleton
CallbackFromGUIThread();
private:
static CallbackFromGUIThreadImplementation* m_Implementation;
static CallbackFromGUIThread* m_Instance;
};
} // namespace
#endif
diff --git a/Core/Code/Controllers/mitkCameraController.cpp b/Core/Code/Controllers/mitkCameraController.cpp
index 3ddd05ac58..06d6618316 100644
--- a/Core/Code/Controllers/mitkCameraController.cpp
+++ b/Core/Code/Controllers/mitkCameraController.cpp
@@ -1,170 +1,169 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkCameraController.h"
#include "mitkVtkPropRenderer.h"
#include "mitkRenderingManager.h"
#include <vtkRenderWindowInteractor.h>
#include "vtkCommand.h"
#include "vtkCamera.h"
#include "vtkRenderer.h"
mitk::CameraController::CameraController(const char * type) : BaseController(type), m_Renderer(NULL), m_ZoomFactor(1.0)
{}
mitk::CameraController::~CameraController()
{}
void mitk::CameraController::Resize(int, int)
{}
void mitk::CameraController::MousePressEvent(mitk::MouseEvent*)
{}
void mitk::CameraController::MouseReleaseEvent(mitk::MouseEvent*)
{}
void mitk::CameraController::MouseMoveEvent(mitk::MouseEvent*)
{}
void mitk::CameraController::KeyPressEvent(mitk::KeyEvent*)
{}
void mitk::CameraController::SetViewToAnterior()
{
this->SetStandardView(ANTERIOR);
}
void mitk::CameraController::SetViewToPosterior()
{
this->SetStandardView(POSTERIOR);
}
void mitk::CameraController::SetViewToSinister()
{
this->SetStandardView(SINISTER);
}
void mitk::CameraController::SetViewToDexter()
{
this->SetStandardView(DEXTER);
}
void mitk::CameraController::SetViewToCranial()
{
this->SetStandardView(CRANIAL);
}
void mitk::CameraController::SetViewToCaudal()
{
this->SetStandardView(CAUDAL);
}
void mitk::CameraController::SetStandardView( mitk::CameraController::StandardView view )
{
const mitk::VtkPropRenderer* glRenderer = dynamic_cast<const mitk::VtkPropRenderer*>(m_Renderer);
if (glRenderer == NULL)
return;
vtkRenderer* vtkRenderer = glRenderer->GetVtkRenderer();
assert (vtkRenderer);
mitk::BoundingBox::Pointer bb;
mitk::DataStorage* ds = m_Renderer->GetDataStorage();
if (ds != NULL)
bb = ds->ComputeBoundingBox();
else
return;
if(m_Renderer->GetMapperID() == mitk::BaseRenderer::Standard3D)
{
//set up the view for the 3D render window. The views for 2D are set up in the mitkVtkPropRenderer
mitk::Point3D middle = bb->GetCenter();
vtkRenderer->GetActiveCamera()->SetFocalPoint(middle[0], middle[1], middle[2]);
switch(view)
{
case ANTERIOR:
case POSTERIOR:
case SINISTER:
case DEXTER:
vtkRenderer->GetActiveCamera()->SetViewUp(0,0,1);
break;
case CRANIAL:
case CAUDAL:
vtkRenderer->GetActiveCamera()->SetViewUp(0,-1,0);
break;
}
switch(view)
{
case ANTERIOR:
vtkRenderer->GetActiveCamera()->SetPosition(middle[0],-100000,middle[2]);
break;
case POSTERIOR:
vtkRenderer->GetActiveCamera()->SetPosition(middle[0],+100000,middle[2]);
break;
case SINISTER:
vtkRenderer->GetActiveCamera()->SetPosition(+100000,middle[1],middle[2]);
break;
case DEXTER:
vtkRenderer->GetActiveCamera()->SetPosition(-100000,middle[1],middle[2]);
break;
case CRANIAL:
vtkRenderer->GetActiveCamera()->SetPosition(middle[0],middle[1],100000);
break;
case CAUDAL:
vtkRenderer->GetActiveCamera()->SetPosition(middle[0],middle[1],-100000);
break;
}
vtkRenderer->ResetCamera();
double *cameraPosition = vtkRenderer->GetActiveCamera()->GetPosition();
switch(view)
{
case ANTERIOR:
case POSTERIOR:
vtkRenderer->GetActiveCamera()->SetPosition(cameraPosition[0],cameraPosition[1] / m_ZoomFactor,cameraPosition[2]);
break;
case SINISTER:
case DEXTER:
vtkRenderer->GetActiveCamera()->SetPosition(cameraPosition[0] / m_ZoomFactor,cameraPosition[1],cameraPosition[2]);
break;
case CRANIAL:
case CAUDAL:
vtkRenderer->GetActiveCamera()->SetPosition(cameraPosition[0],cameraPosition[1],cameraPosition[2] / m_ZoomFactor);
break;
}
vtkRenderer->ResetCameraClippingRange();
}
mitk::RenderingManager* rm = m_Renderer->GetRenderingManager();
rm->RequestUpdateAll();
}
diff --git a/Core/Code/Controllers/mitkCameraController.h b/Core/Code/Controllers/mitkCameraController.h
index d2c2227589..7bab74aac2 100644
--- a/Core/Code/Controllers/mitkCameraController.h
+++ b/Core/Code/Controllers/mitkCameraController.h
@@ -1,93 +1,92 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 CAMERACONTROLLER_H_HEADER_INCLUDED_C1C53722
#define CAMERACONTROLLER_H_HEADER_INCLUDED_C1C53722
#include <MitkExports.h>
#include "mitkBaseController.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkKeyEvent.h"
namespace mitk {
//##Documentation
//## @brief controls the camera used by the associated BaseRenderer
//##
//## Subclass of BaseController. Controls the camera used by the associated
//## BaseRenderer.
//## @ingroup NavigationControl
class MITK_CORE_EXPORT CameraController : public BaseController
{
public:
enum StandardView { ANTERIOR,POSTERIOR,SINISTER,DEXTER,CRANIAL,CAUDAL };
mitkClassMacro(CameraController, BaseController);
mitkNewMacro1Param(Self, const char*);
itkSetMacro(Renderer,BaseRenderer*);
itkSetMacro(ZoomFactor,double);
itkGetConstMacro(Renderer,const BaseRenderer*);
itkGetConstMacro(ZoomFactor,double);
//##Documentation
//## @brief Implemented in sub-classes.
virtual void Resize(int w, int h);
//##Documentation
//## @brief Implemented in sub-classes.
virtual void MousePressEvent(mitk::MouseEvent*);
//##Documentation
//## @brief Implemented in sub-classes.
virtual void MouseReleaseEvent(mitk::MouseEvent*);
//##Documentation
//## @brief Implemented in sub-classes.
virtual void MouseMoveEvent(mitk::MouseEvent*);
//##Documentation
//## @brief Implemented in sub-classes.
virtual void KeyPressEvent(mitk::KeyEvent*);
virtual void SetViewToAnterior();
virtual void SetViewToPosterior();
virtual void SetViewToSinister();
virtual void SetViewToDexter();
virtual void SetViewToCranial();
virtual void SetViewToCaudal();
virtual void SetStandardView(StandardView view);
protected:
/**
* @brief Default Constructor
**/
CameraController(const char * type = NULL);
/**
* @brief Default Destructor
**/
virtual ~CameraController();
const BaseRenderer* m_Renderer;
double m_ZoomFactor; ///< zoom factor used for the standard view camera
};
} // namespace mitk
#endif /* CAMERACONTROLLER_H_HEADER_INCLUDED_C1C53722 */
diff --git a/Core/Code/Controllers/mitkCameraRotationController.cpp b/Core/Code/Controllers/mitkCameraRotationController.cpp
index 33bbbaf6d0..ac6563e964 100644
--- a/Core/Code/Controllers/mitkCameraRotationController.cpp
+++ b/Core/Code/Controllers/mitkCameraRotationController.cpp
@@ -1,100 +1,99 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkCameraRotationController.h"
#include <vtkCamera.h>
#include <itkCommand.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include "mitkVtkPropRenderer.h"
#include "mitkRenderingManager.h"
mitk::CameraRotationController::CameraRotationController(const char * type)
: BaseController(type), m_LastStepperValue(180), m_Camera(NULL), m_RenderWindow(NULL)
{
m_Slice->SetAutoRepeat(true);
m_Slice->SetSteps(360);
m_Slice->SetPos(180);
itk::SimpleMemberCommand<CameraRotationController>::Pointer sliceStepperChangedCommand, timeStepperChangedCommand;
sliceStepperChangedCommand = itk::SimpleMemberCommand<CameraRotationController>::New();
sliceStepperChangedCommand->SetCallbackFunction(this, &CameraRotationController::RotateCamera);
m_Slice->AddObserver(itk::ModifiedEvent(), sliceStepperChangedCommand);
}
mitk::CameraRotationController::~CameraRotationController()
{
}
void mitk::CameraRotationController::RotateCamera()
{
if (!m_Camera)
{
this->AcquireCamera();
}
if (m_Camera)
{
int newStepperValue = m_Slice->GetPos();
m_Camera->Azimuth( m_LastStepperValue - newStepperValue );
m_LastStepperValue = newStepperValue;
//const_cast< RenderWindow* >(m_RenderWindow)->RequestUpdate(); // TODO does not work with movie generator!
mitk::RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow);
//m_MultiWidget->RequestUpdate();
}
}
void mitk::CameraRotationController::AcquireCamera()
{
BaseRenderer* renderer = mitk::BaseRenderer::GetInstance(m_RenderWindow);
const mitk::VtkPropRenderer *propRenderer = dynamic_cast<const mitk::VtkPropRenderer * >( renderer );
if (propRenderer)
{
// get vtk renderer
vtkRenderer* vtkrenderer = propRenderer->GetVtkRenderer();
if (vtkrenderer)
{
// get vtk camera
vtkCamera* vtkcam = vtkrenderer->GetActiveCamera();
if (vtkcam)
{
// vtk smart pointer handling
if (!m_Camera)
{
m_Camera = vtkcam;
m_Camera->Register( NULL );
}
else
{
m_Camera->UnRegister( NULL );
m_Camera = vtkcam;
m_Camera->Register( NULL );
}
}
}
}
}
bool mitk::CameraRotationController::ExecuteAction(
Action*, mitk::StateEvent const*)
{
return false;
}
diff --git a/Core/Code/Controllers/mitkCameraRotationController.h b/Core/Code/Controllers/mitkCameraRotationController.h
index 637d7ff600..d197da7b1d 100644
--- a/Core/Code/Controllers/mitkCameraRotationController.h
+++ b/Core/Code/Controllers/mitkCameraRotationController.h
@@ -1,59 +1,58 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 CAMERAROTATIONCONTROLLER_H_HEADER_INCLUDED_NXYCBIU
#define CAMERAROTATIONCONTROLLER_H_HEADER_INCLUDED_NXYCBIU
#include <MitkExports.h>
#include "mitkBaseController.h"
class vtkCamera;
class vtkRenderWindow;
namespace mitk {
class MITK_CORE_EXPORT CameraRotationController : public BaseController
{
public:
mitkClassMacro(CameraRotationController,BaseController);
itkNewMacro(Self);
mitkNewMacro1Param(Self, const char *);
void RotateCamera();
void AcquireCamera();
void SetRenderWindow(vtkRenderWindow * renWin)
{
m_RenderWindow = renWin;
}
virtual bool ExecuteAction( Action* action, mitk::StateEvent const* stateEvent );
protected:
CameraRotationController(const char * type = NULL);
virtual ~CameraRotationController();
private:
int m_LastStepperValue;
vtkCamera* m_Camera;
vtkRenderWindow* m_RenderWindow;
};
}
#endif
diff --git a/Core/Code/Controllers/mitkCoreActivator.cpp b/Core/Code/Controllers/mitkCoreActivator.cpp
index dda53f6db8..22a996b3ef 100644
--- a/Core/Code/Controllers/mitkCoreActivator.cpp
+++ b/Core/Code/Controllers/mitkCoreActivator.cpp
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRenderingManager.h"
#include "mitkPlanePositionManager.h"
#include "mitkCoreDataNodeReader.h"
#include <mitkModuleActivator.h>
/*
* This is the module activator for the "Mitk" module. It registers core services
* like ...
*/
class MitkCoreActivator : public mitk::ModuleActivator
{
public:
void Load(mitk::ModuleContext* context)
{
//m_RenderingManager = mitk::RenderingManager::New();
//context->RegisterService<mitk::RenderingManager>(renderingManager.GetPointer());
m_PlanePositionManager = mitk::PlanePositionManagerService::New();
context->RegisterService<mitk::PlanePositionManagerService>(m_PlanePositionManager);
m_CoreDataNodeReader = mitk::CoreDataNodeReader::New();
context->RegisterService<mitk::IDataNodeReader>(m_CoreDataNodeReader);
}
void Unload(mitk::ModuleContext* )
{
// The mitk::ModuleContext* argument of the Unload() method
// will always be 0 for the Mitk library. It makes no sense
// to use it at this stage anyway, since all libraries which
// know about the module system have already been unloaded.
}
private:
//mitk::RenderingManager::Pointer m_RenderingManager;
mitk::PlanePositionManagerService::Pointer m_PlanePositionManager;
mitk::CoreDataNodeReader::Pointer m_CoreDataNodeReader;
};
US_EXPORT_MODULE_ACTIVATOR(Mitk, MitkCoreActivator)
diff --git a/Core/Code/Controllers/mitkFocusManager.cpp b/Core/Code/Controllers/mitkFocusManager.cpp
index ad013fafe6..a2b0f33c5a 100755
--- a/Core/Code/Controllers/mitkFocusManager.cpp
+++ b/Core/Code/Controllers/mitkFocusManager.cpp
@@ -1,146 +1,145 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkFocusManager.h"
mitk::FocusManager::FocusManager()
{
m_Loop = true;//default
m_FocusList.clear();
m_FocElement = NULL;
}
mitk::FocusManager::~FocusManager()
{
}
bool mitk::FocusManager::AddElement(FocusElement* element)
{
// Try find
mitk::FocusManager::FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element);
if (position != m_FocusList.end())
return false;
m_FocusList.push_back(element);
if (m_FocElement.GetPointer() == NULL)
m_FocElement = element;
return true;
}
bool mitk::FocusManager::RemoveElement(FocusElement* element)
{
// Try find
mitk::FocusManager::FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element);
if (position == m_FocusList.end())
return false;
position = m_FocusList.erase(position);
// first delete the one on the position, and store the one afterewards into position
if ( m_FocusList.size() == 0 )
{
// no more FocusElements available
m_FocElement = NULL;
}
else if ( position == m_FocusList.end() )
{
// deleted was the last in row, then take the one before
m_FocElement = m_FocusList.back();
}
else
{
// m_FocElement is equal to the next one in row
m_FocElement = *position;
}
return true;
}
mitk::FocusManager::FocusElement* mitk::FocusManager::GetFocused() const
{
return m_FocElement.GetPointer();
}
bool mitk::FocusManager::SetFocused(FocusElement* element)
{
if (m_FocElement == element)
return true;
FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element);
if (position == m_FocusList.end())//not found
return false;
m_FocElement = *position;
((const itk::Object*)this)->InvokeEvent(FocusEvent());
return true;
}
bool mitk::FocusManager::IsLast()
{
return (m_FocElement == m_FocusList.back());
}
bool mitk::FocusManager::IsFirst()
{
return (m_FocElement == m_FocusList.front());
}
const mitk::FocusManager::FocusElement* mitk::FocusManager::GetFirst() const
{
return (m_FocusList.front()).GetPointer();
}
const mitk::FocusManager::FocusElement* mitk::FocusManager::GetLast() const
{
return (m_FocusList.back()).GetPointer();
}
bool mitk::FocusManager::GoToNext()
{
//find the m_FocElement
FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),m_FocElement);
if (position == m_FocusList.end())//not found
return false;
else if (*position == m_FocusList.back())//last in row
{
if (m_Loop)
{
m_FocElement = *(m_FocusList.begin());
return true;
}
else
{
return false;//last in row and loop == false, so GoToNext == false
}
}
else //not last in row
{
m_FocElement = *(++position);//increase position and set m_FocElement
return true;
}
return false;
}
//##Documentation
//## returns an iterator, that points to the
//## beginning of the list
mitk::FocusManager::FocusListIterator mitk::FocusManager::GetIter()
{
return m_FocusList.begin();
}
void mitk::FocusManager::SetLoop(bool loop)
{
m_Loop = loop;
}
diff --git a/Core/Code/Controllers/mitkFocusManager.h b/Core/Code/Controllers/mitkFocusManager.h
index 0fecea1562..91e353bbad 100755
--- a/Core/Code/Controllers/mitkFocusManager.h
+++ b/Core/Code/Controllers/mitkFocusManager.h
@@ -1,150 +1,149 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197
#define MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197
#include <MitkExports.h>
#include "mitkBaseRenderer.h"
#include <vector>
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
namespace mitk {
//##Documentation
//## @brief manages a list of BaseRenderer.
//##
//## A focuspointer can be set and read.
//## GoToNext can be used to switch through the list.
//## if the switch m_Loop is set to true, GetNext loops through the list; after
//## the last it goes to the first.
//## if it is not set, it returnes NULL if it steps behind the last Widget.
//## @ingroup Interaction
class MITK_CORE_EXPORT FocusManager : public itk::Object
{
public:
mitkClassMacro(FocusManager, itk::Object);
itkNewMacro(Self);
//##Documentation
//##@brief Element, that can be focused and held here.
//##
//## has to be an itk-Objekct in order to use itk-Smartpointer!
typedef mitk::BaseRenderer FocusElement;
typedef itk::WeakPointer<FocusElement> FocusElementWeakPointer;
typedef std::vector<FocusElementWeakPointer> FocusElementList;
typedef std::vector<FocusElementWeakPointer>::iterator FocusListIterator;
//##Documentation
//## Destructor
~FocusManager();
//##Documentation
//## Adds the widget into the set of managed Widgets after the focused
//## widget and sets the focus to the added one if the list was empty before
bool AddElement(FocusElement* element);
//##Documentation
//## removes the given widget from the list.
//## true if found and removed, else false
//## afterwards the focused widget is the one behind the deleted
//## or if the deleted was the last, then the one before the deleted
//## that way you can delete sequentialy from the back on or from front to back
bool RemoveElement(FocusElement* element);
//##Documentation
//## returns the focused Widget
FocusElement* GetFocused() const;
//##Documentation
//## searches the given Widget in List;
//## if found, sets the focus to this widget and returns true
bool SetFocused(FocusElement* element);
//##Documentation
//## returns, if this focused widget points behind the end of the List
bool IsLast();
//##Documentation
//## returns true, if the focused widget is the first in the list
bool IsFirst();
//##Documentation
//## returns the first widget in list
const FocusElement* GetFirst() const;
//##Documentation
//## returns the last widget in list
const FocusElement* GetLast() const;
//##Documentation
//## sets the focus to the next in list
//## loops the list, if switch loop is true
//## returns true if successful, else false
bool GoToNext();
//##Documentation
//## returns an iterator, that points to the
//## beginning of the list
//## no changes are made to the current focused element
FocusListIterator GetIter();
//##Documentation
//## Sets the LoopMode.
//## if set to true-> the one after the last is the first
void SetLoop(bool loop);
friend class GlobalInteraction;
protected:
//##Documentation
//## Constructor
FocusManager();
private:
//##Documentation
//## stores the Widgets
FocusElementList m_FocusList;
//##Documentation
//## holds the focused Widget
itk::WeakPointer<FocusElement> m_FocElement;
//##Documentation
//## switch which sets the LoopMode.
//## if true, then the next after the last one is the first
bool m_Loop;
};
#pragma GCC visibility push(default)
//##Documentation
//## @brief connect to this Event to get noticed when the focus changes
itkEventMacro( FocusEvent , itk::AnyEvent );
#pragma GCC visibility pop
} // namespace mitk
#endif /* MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197 */
diff --git a/Core/Code/Controllers/mitkLimitedLinearUndo.cpp b/Core/Code/Controllers/mitkLimitedLinearUndo.cpp
index a22e900f5e..e22241c5fb 100644
--- a/Core/Code/Controllers/mitkLimitedLinearUndo.cpp
+++ b/Core/Code/Controllers/mitkLimitedLinearUndo.cpp
@@ -1,213 +1,212 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLimitedLinearUndo.h"
#include <mitkRenderingManager.h>
mitk::LimitedLinearUndo::LimitedLinearUndo()
{
// nothing to do
}
mitk::LimitedLinearUndo::~LimitedLinearUndo()
{
//delete undo and redo list
this->ClearList(&m_UndoList);
this->ClearList(&m_RedoList);
}
void mitk::LimitedLinearUndo::ClearList(UndoContainer* list)
{
while(!list->empty())
{
UndoStackItem* item = list->back();
list->pop_back();
delete item;
}
}
bool mitk::LimitedLinearUndo::SetOperationEvent(UndoStackItem* stackItem)
{
OperationEvent* operationEvent = dynamic_cast<OperationEvent*>(stackItem);
if (!operationEvent) return false;
// clear the redolist, if a new operation is saved
if (!m_RedoList.empty())
{
this->ClearList(&m_RedoList);
InvokeEvent( RedoEmptyEvent() );
}
m_UndoList.push_back(operationEvent);
InvokeEvent( UndoNotEmptyEvent() );
return true;
}
bool mitk::LimitedLinearUndo::Undo(bool fine)
{
if (fine)
{
// undo one object event ID
return Undo();
}
else
{
// undo one group event ID
int oeid = FirstObjectEventIdOfCurrentGroup(m_UndoList); // get the Object Event ID of the first item with a differnt Group ID (as seen from the end of stack)
return Undo(oeid);
}
}
bool mitk::LimitedLinearUndo::Undo()
{
if(m_UndoList.empty()) return false;
int undoObjectEventId = m_UndoList.back()->GetObjectEventId();
return Undo( undoObjectEventId );
}
bool mitk::LimitedLinearUndo::Undo(int oeid)
{
if(m_UndoList.empty()) return false;
do
{
m_UndoList.back()->ReverseAndExecute();
m_RedoList.push_back(m_UndoList.back()); // move to redo stack
m_UndoList.pop_back();
InvokeEvent( RedoNotEmptyEvent() );
if (m_UndoList.empty())
{
InvokeEvent( UndoEmptyEvent() );
return false;
}
}
while ( m_UndoList.back()->GetObjectEventId() >= oeid );
//Update. Check Rendering Mechanism where to request updates
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return true;
}
bool mitk::LimitedLinearUndo::Redo(bool)
{
return Redo();
}
bool mitk::LimitedLinearUndo::Redo()
{
if (m_RedoList.empty()) return false;
int redoObjectEventId = m_RedoList.back()->GetObjectEventId();
return Redo( redoObjectEventId );
}
bool mitk::LimitedLinearUndo::Redo(int oeid)
{
if (m_RedoList.empty()) return false;
do
{
m_RedoList.back()->ReverseAndExecute();
m_UndoList.push_back(m_RedoList.back());
m_RedoList.pop_back();
InvokeEvent( UndoNotEmptyEvent() );
if (m_RedoList.empty())
{
InvokeEvent( RedoEmptyEvent() );
break;
}
}
while ( m_RedoList.back()->GetObjectEventId() <= oeid );
//Update. This should belong into the ExecuteOperation() of OperationActors, but it seems not to be used everywhere
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return true;
}
void mitk::LimitedLinearUndo::Clear()
{
this->ClearList(&m_UndoList);
InvokeEvent( UndoEmptyEvent() );
this->ClearList(&m_RedoList);
InvokeEvent( RedoEmptyEvent() );
}
void mitk::LimitedLinearUndo::ClearRedoList()
{
this->ClearList(&m_RedoList);
InvokeEvent( RedoEmptyEvent() );
}
bool mitk::LimitedLinearUndo::RedoListEmpty()
{
return m_RedoList.empty();
}
int mitk::LimitedLinearUndo::GetLastObjectEventIdInList()
{
return m_UndoList.back()->GetObjectEventId();
}
int mitk::LimitedLinearUndo::GetLastGroupEventIdInList()
{
return m_UndoList.back()->GetGroupEventId();
}
mitk::OperationEvent* mitk::LimitedLinearUndo::GetLastOfType(OperationActor* destination, OperationType opType)
{
// When/where is this function needed? In CoordinateSupplier...
for ( UndoContainerRevIter iter = m_UndoList.rbegin(); iter != m_UndoList.rend(); ++iter )
{
OperationEvent* opEvent = dynamic_cast<OperationEvent*>(*iter);
if (!opEvent) continue;
if ( opEvent->GetOperation() != NULL
&& opEvent->GetOperation()->GetOperationType() == opType
&& opEvent->IsValid()
&& opEvent->GetDestination() == destination )
return opEvent;
}
return NULL;
}
int mitk::LimitedLinearUndo::FirstObjectEventIdOfCurrentGroup(mitk::LimitedLinearUndo::UndoContainer& stack)
{
int currentGroupEventId = stack.back()->GetGroupEventId();
int firstObjectEventId = -1;
for ( UndoContainerRevIter iter = stack.rbegin(); iter != stack.rend(); ++iter )
{
if ( (*iter)->GetGroupEventId() == currentGroupEventId )
{
firstObjectEventId = (*iter)->GetObjectEventId();
}
else break;
}
return firstObjectEventId;
}
diff --git a/Core/Code/Controllers/mitkLimitedLinearUndo.h b/Core/Code/Controllers/mitkLimitedLinearUndo.h
index b7fcd6afac..cf782863a2 100644
--- a/Core/Code/Controllers/mitkLimitedLinearUndo.h
+++ b/Core/Code/Controllers/mitkLimitedLinearUndo.h
@@ -1,145 +1,144 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 LIMITEDLINEARUNDO_H_HEADER_INCLUDED_C16E9C96
#define LIMITEDLINEARUNDO_H_HEADER_INCLUDED_C16E9C96
// MITK header
#include <MitkExports.h>
#include "mitkOperationEvent.h"
#include "mitkUndoModel.h"
// STL header
#include <vector>
// ITK header
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
namespace mitk {
//##Documentation
//## @brief A linear undo model with one undo and one redo stack.
//##
//## Derived from UndoModel AND itk::Object. Invokes ITK-events to signal listening
//## GUI elements, whether each of the stacks is empty or not (to enable/disable button, ...)
class MITK_CORE_EXPORT LimitedLinearUndo : public UndoModel
{
public:
typedef std::vector<UndoStackItem*> UndoContainer;
typedef std::vector<UndoStackItem*>::reverse_iterator UndoContainerRevIter;
mitkClassMacro(LimitedLinearUndo, UndoModel);
itkNewMacro(Self);
virtual bool SetOperationEvent(UndoStackItem* stackItem);
//##Documentation
//## @brief Undoes the last changes
//##
//## Reads the top element of the Undo-Stack,
//## executes the operation,
//## swaps the OperationEvent-Undo with the Operation
//## and sets it to Redo-Stack
virtual bool Undo();
virtual bool Undo(bool);
//##Documentation
//## @brief Undoes all changes until ObjectEventID oeid
virtual bool Undo(int oeid);
//##Documentation
//## @brief Undoes the last changes
//##
//## Reads the top element of the Redo-Stack,
//## executes the operation,
//## swaps the OperationEvent-Operation with the Undo-Operation
//## and sets it to Undo-Stack
virtual bool Redo();
virtual bool Redo(bool);
//##Documentation
//## @brief Redoes all changes until ObjectEventID oeid
virtual bool Redo(int oeid);
//##Documentation
//## @brief Clears UndoList and RedoList
virtual void Clear();
//##Documentation
//## @brief Clears the RedoList
virtual void ClearRedoList();
//##Documentation
//## @brief True, if RedoList is empty
virtual bool RedoListEmpty();
//##Documentation
//## @brief Returns the ObjectEventId of the
//## top element in the OperationHistory
virtual int GetLastObjectEventIdInList();
//##Documentation
//## @brief Returns the GroupEventId of the
//## top element in the OperationHistory
virtual int GetLastGroupEventIdInList();
//##Documentation
//## @brief Returns the last specified OperationEvent in Undo-list
//## corresponding to the given values; if nothing found, then returns NULL
virtual OperationEvent* GetLastOfType(OperationActor* destination, OperationType opType);
protected:
//##Documentation
//## Constructor
LimitedLinearUndo();
//##Documentation
//## Destructor
virtual ~LimitedLinearUndo();
//## @brief Convenience method to free the memory of
//## elements in the list and to clear the list
void ClearList(UndoContainer* list);
UndoContainer m_UndoList;
UndoContainer m_RedoList;
private:
int FirstObjectEventIdOfCurrentGroup(UndoContainer& stack);
};
#pragma GCC visibility push(default)
/// Some itk events to notify listening GUI elements, when the undo or redo stack is empty (diable undo button)
/// or when there are items in the stack (enable button)
itkEventMacro( UndoStackEvent, itk::ModifiedEvent );
itkEventMacro( UndoEmptyEvent, UndoStackEvent );
itkEventMacro( RedoEmptyEvent, UndoStackEvent );
itkEventMacro( UndoNotEmptyEvent, UndoStackEvent );
itkEventMacro( RedoNotEmptyEvent, UndoStackEvent );
/// Additional unused events, if anybody wants to put an artificial limit to the possible number of items in the stack
itkEventMacro( UndoFullEvent, UndoStackEvent );
itkEventMacro( RedoFullEvent, UndoStackEvent );
#pragma GCC visibility pop
} //namespace mitk
#endif /* LIMITEDLINEARUNDO_H_HEADER_INCLUDED_C16E9C96 */
diff --git a/Core/Code/Controllers/mitkOperationEvent.cpp b/Core/Code/Controllers/mitkOperationEvent.cpp
index 03f5a0a0f0..49d3ac5094 100644
--- a/Core/Code/Controllers/mitkOperationEvent.cpp
+++ b/Core/Code/Controllers/mitkOperationEvent.cpp
@@ -1,176 +1,175 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkOperationEvent.h"
#include <itkCommand.h>
int mitk::UndoStackItem::m_CurrObjectEventId = 0;
int mitk::UndoStackItem::m_CurrGroupEventId = 0;
bool mitk::UndoStackItem::m_IncrObjectEventId = false;
bool mitk::UndoStackItem::m_IncrGroupEventId = false;
mitk::UndoStackItem::UndoStackItem(std::string description)
: m_Reversed(false),
m_Description(description)
{
m_ObjectEventId = GetCurrObjectEventId();
m_GroupEventId = GetCurrGroupEventId();
}
mitk::UndoStackItem::~UndoStackItem()
{
// nothing to do
}
void mitk::UndoStackItem::ExecuteIncrement()
{
if (m_IncrObjectEventId)
{
++m_CurrObjectEventId;
m_IncrObjectEventId = false;
}
if (m_IncrGroupEventId)
{
++m_CurrGroupEventId;
m_IncrGroupEventId = false;
}
}
int mitk::UndoStackItem::GetCurrObjectEventId()
{
return m_CurrObjectEventId;
}
int mitk::UndoStackItem::GetCurrGroupEventId()
{
return m_CurrGroupEventId;
}
void mitk::UndoStackItem::IncCurrObjectEventId()
{
m_IncrObjectEventId = true;
}
void mitk::UndoStackItem::IncCurrGroupEventId()
{
m_IncrGroupEventId = true;
}
int mitk::UndoStackItem::GetObjectEventId()
{
return m_ObjectEventId;
}
int mitk::UndoStackItem::GetGroupEventId()
{
return m_GroupEventId;
}
std::string mitk::UndoStackItem::GetDescription()
{
return m_Description;
}
void mitk::UndoStackItem::ReverseOperations()
{
m_Reversed = !m_Reversed;
}
void mitk::UndoStackItem::ReverseAndExecute()
{
ReverseOperations();
}
// ******************** mitk::OperationEvent ********************
mitk::Operation* mitk::OperationEvent::GetOperation()
{
return m_Operation;
}
mitk::OperationEvent::OperationEvent(OperationActor* destination,
Operation* operation, Operation* undoOperation,
std::string description)
: UndoStackItem(description),
m_Destination(destination),
m_Operation(operation),
m_UndoOperation(undoOperation),
m_Invalid(false)
{
//connect to delete event
if (itk::Object* object = dynamic_cast<itk::Object*>( m_Destination ))
{
itk::SimpleMemberCommand< OperationEvent >::Pointer command = itk::SimpleMemberCommand< OperationEvent >::New();
command->SetCallbackFunction( this, &OperationEvent::OnObjectDeleted );
m_DeleteTag = object->AddObserver( itk::DeleteEvent(), command );
}
}
mitk::OperationEvent::~OperationEvent()
{
//remove the observer if the data m_Destination still is present
if (!m_Invalid)
{
if (itk::Object* object = dynamic_cast<itk::Object*>( m_Destination ))
{
object->RemoveObserver( m_DeleteTag );
}
}
delete m_Operation;
delete m_UndoOperation;
}
//##Documentation
//## swaps the Undo and Redo- operation and changes m_Reversed
void mitk::OperationEvent::ReverseOperations()
{
if (m_Operation == NULL)
return;
Operation *tempOperation = m_Operation;
m_Operation = m_UndoOperation;
m_UndoOperation = tempOperation;
UndoStackItem::ReverseOperations();
}
void mitk::OperationEvent::ReverseAndExecute()
{
ReverseOperations();
if (m_Destination && m_Operation && !m_Invalid)
m_Destination->ExecuteOperation( m_Operation );
}
mitk::OperationActor* mitk::OperationEvent::GetDestination()
{
return m_Destination;
}
void mitk::OperationEvent::OnObjectDeleted()
{
m_Invalid = true;
}
bool mitk::OperationEvent::IsValid()
{
return !m_Invalid;
}
diff --git a/Core/Code/Controllers/mitkOperationEvent.h b/Core/Code/Controllers/mitkOperationEvent.h
index 615743a281..046604595f 100644
--- a/Core/Code/Controllers/mitkOperationEvent.h
+++ b/Core/Code/Controllers/mitkOperationEvent.h
@@ -1,211 +1,210 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 OPERATIONEVENT_H_HEADER_INCLUDED_C16E83FC
#define OPERATIONEVENT_H_HEADER_INCLUDED_C16E83FC
#include <MitkExports.h>
#include "mitkOperation.h"
#include "mitkOperationActor.h"
#include "mitkUndoModel.h"
#include <string>
#include <list>
namespace mitk {
//##Documentation
//## @brief Represents an entry of the undo or redo stack.
//##
//## This basic entry includes a textual description of the item and a pair of IDs. Static
//## member functions handle creation and incrementing of these IDs.
//##
//## The ObjectEventID is increased by the global EventMapper for most of the events (see
//## code for details). Incrementation of the IDs is done in two steps. First the
//## EventMapper sets a flag via (possibly multiple calls of) IncCurrObjectEventID(), then
//## ExecuteIncrement() does the actual incementation.
//##
//## The GroupEventID is intended for logical grouping of several related Operations.
//## Currently this is used only by PointSetInteractor. How this is done and when to use
//## GroupEventIDs is still undocumented.
//## @ingroup Undo
class MITK_CORE_EXPORT UndoStackItem
{
public:
UndoStackItem(std::string description = "");
virtual ~UndoStackItem();
//##Documentation
//## @brief For combining operations in groups
//##
//## This ID is used in the undo mechanism.
//## For separation of the seperate operations
//## If the GroupEventId of two OperationEvents is equal,
//## then they share one group and will be undone in case of Undo(fine==false)
static int GetCurrGroupEventId();
//##Documentation
//## @brief For combining operations in Objects
//##
//## This ID is used in the Undo-Mechanism.
//## For separation of the seperate operations
//## If the ObjectEventId of two OperationEvents is equal,
//## then they share one Object and will be undone in all cases of Undo(true and false).
//## they shal not be seperated, because they were produced to realize one object-change.
//## for example: OE_statechange and OE_addlastpoint
static int GetCurrObjectEventId();
//##Documentation
//## @brief Returns the GroupEventId for this object
int GetGroupEventId();
//##Documentation
//## @brief Returns the ObjectEventId for this object
int GetObjectEventId();
//##Documentation
//## @brief Returns the textual description of this object
std::string GetDescription();
virtual void ReverseOperations();
virtual void ReverseAndExecute();
//##Documentation
//## @brief Sets the current ObjectEventId to be incremended when ExecuteIncrement is called
//## For example if a button click generates operations the ObjectEventId has to be incremented to be able to undo the operations.
//## Difference between ObjectEventId and GroupEventId: The ObjectEventId capsulates all operations caused by one event.
//## A GroupEventId capsulates several ObjectEventIds so that several operations caused by several events can be undone with one Undo call.
static void IncCurrObjectEventId();
//##Documentation
//## @brief Sets the current GroupEventId to be incremended when ExecuteIncrement is called
//## For example if a button click generates operations the GroupEventId has to be incremented to be able to undo the operations.
//## Difference between ObjectEventId and GroupEventId: The ObjectEventId capsulates all operations caused by one event.
//## A GroupEventId capsulates several ObjectEventIds so that several operations caused by several events can be undone with one Undo call.
static void IncCurrGroupEventId();
//##Documentation
//## @brief Executes the incrementation of objectEventId and groupEventId if they are set to be incremented
static void ExecuteIncrement();
protected:
//##Documentation
//## @brief true, if operation and undooperation have been swaped/changed
bool m_Reversed;
private:
static int m_CurrObjectEventId;
static int m_CurrGroupEventId;
static bool m_IncrObjectEventId;
static bool m_IncrGroupEventId;
int m_ObjectEventId;
int m_GroupEventId;
std::string m_Description;
UndoStackItem(UndoStackItem&); // hide copy constructor
void operator=(const UndoStackItem&); // hide operator=
};
//##Documentation
//## @brief Represents a pair of operations: undo and the according redo.
//##
//## Additionally to the base class UndoStackItem, which only provides a description of an
//## item, OperationEvent does the actual accounting of the undo/redo stack. This class
//## holds two Operation objects (operation and its inverse operation) and the corresponding
//## OperationActor. The operations may be swapped by the
//## undo models, when an OperationEvent is moved from their undo to their redo
//## stack or vice versa.
//##
//## Note, that memory management of operation and undooperation is done by this class.
//## Memory of both objects is freed in the destructor. For this, the method IsValid() is needed which holds
//## information of the state of m_Destination. In case the object referenced by m_Destination is already deleted,
//## isValid() returns false.
//## In more detail if the destination happens to be an itk::Object (often the case), OperationEvent is informed as soon
//## as the object is deleted - from this moment on the OperationEvent gets invalid. You should
//## check this flag before you call anything on destination
//##
//## @ingroup Undo
class MITK_CORE_EXPORT OperationEvent : public UndoStackItem
{
public:
//## @brief default constructor
OperationEvent(OperationActor* destination, Operation* operation, Operation* undoOperation, std::string description = "" );
//## @brief default destructor
//##
//## removes observers if destination is valid
//## and frees memory referenced by m_Operation and m_UndoOperation
virtual ~OperationEvent();
//## @brief Returns the operation
Operation* GetOperation();
//## @brief Returns the destination of the operations
OperationActor* GetDestination();
friend class UndoModel;
//## @brief Swaps the two operations and sets a flag,
//## that it has been swapped and doOp is undoOp and undoOp is doOp
virtual void ReverseOperations();
//##reverses and executes both operations (used, when moved from undo to redo stack)
virtual void ReverseAndExecute();
//## @brief returns true if the destination still is present
//## and false if it already has been deleted
virtual bool IsValid();
protected:
void OnObjectDeleted();
private:
// Has to be observed for itk::DeleteEvents.
// When destination is deleted, this stack item is invalid!
OperationActor* m_Destination;
//## reference to the operation
Operation* m_Operation;
//## reference to the undo operation
Operation* m_UndoOperation;
//## hide copy constructor
OperationEvent(OperationEvent&);
//## hide operator=
void operator=(const OperationEvent&);
//observertag used to listen to m_Destination
unsigned long m_DeleteTag;
//## stores if destination is valid or already has been freed
bool m_Invalid;
};
} //namespace mitk
#endif /* OPERATIONEVENT_H_HEADER_INCLUDED_C16E83FC */
diff --git a/Core/Code/Controllers/mitkPlanePositionManager.h b/Core/Code/Controllers/mitkPlanePositionManager.h
index 36fb49252f..e664610827 100644
--- a/Core/Code/Controllers/mitkPlanePositionManager.h
+++ b/Core/Code/Controllers/mitkPlanePositionManager.h
@@ -1,104 +1,103 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 mitkPlanePositionManager_h_Included
#define mitkPlanePositionManager_h_Included
#include "mitkCommon.h"
//#include "MitkExtExports.h"
#include "mitkRestorePlanePositionOperation.h"
#include "mitkDataStorage.h"
#include <mitkServiceReference.h>
#include <mitkModuleContext.h>
#include <mitkServiceInterface.h>
class MitkCoreActivator;
namespace mitk
{
/**
The mitk::PlanePositionManagerService holds and manages a list of certain planepositions.
To store a new position you need to specify the first slice of your slicestack and the
slicenumber you want to restore in the mitk::PlanePositionManager::AddNewPlanePosition() function.
To restore a position call mitk::PlanePositionManagerService::GetPlanePosition(ID) where ID is the position
in the plane positionlist (returned by AddNewPlanePostion). This will give a mitk::RestorePlanePositionOperation
which can be executed by the SliceNavigationController of the slicestack.
\sa QmitkSegmentationView.cpp
*/
class MITK_CORE_EXPORT PlanePositionManagerService : public itk::LightObject
{
public:
/**
\brief Adds a new plane position to the list. If this geometry is identical to one of the list nothing will be added
\a plane THE FIRST! slice of the slice stack
\a sliceIndex the slice number of the selected slice
\return returns the ID i.e. the position in the positionlist. If the PlaneGeometry which is to be added already exists the existing
ID will be returned.
*/
unsigned int AddNewPlanePosition(const mitk::Geometry2D* plane, unsigned int sliceIndex = 0);
/**
\brief Removes the plane at the position \a ID from the list.
\a ID the plane ID which should be removed, i.e. its position in the list
\return true if the plane was removed successfully and false if it is an invalid ID
*/
bool RemovePlanePosition(unsigned int ID);
/// \brief Clears the complete positionlist
void RemoveAllPlanePositions();
/**
\brief Getter for a specific plane position with a given ID
\a ID the ID of the plane position
\return Returns a RestorePlanePositionOperation which can be executed by th SliceNavigationController or NULL for an invalid ID
*/
mitk::RestorePlanePositionOperation* GetPlanePosition( unsigned int ID);
/// \brief Getting the number of all stored planes
unsigned int GetNumberOfPlanePositions();
friend class ::MitkCoreActivator;
private:
mitkClassMacro(PlanePositionManagerService, LightObject);
itkFactorylessNewMacro(PlanePositionManagerService);
PlanePositionManagerService();
~PlanePositionManagerService();
// Disable copy constructor and assignment operator.
PlanePositionManagerService(const PlanePositionManagerService&);
PlanePositionManagerService& operator=(const PlanePositionManagerService&);
static PlanePositionManagerService* m_Instance;
std::vector<mitk::RestorePlanePositionOperation*> m_PositionList;
};
}
US_DECLARE_SERVICE_INTERFACE(mitk::PlanePositionManagerService, "org.mitk.PlanePositionManagerService")
#endif
diff --git a/Core/Code/Controllers/mitkProgressBar.cpp b/Core/Code/Controllers/mitkProgressBar.cpp
index c16758f8dc..2c75af0e7f 100644
--- a/Core/Code/Controllers/mitkProgressBar.cpp
+++ b/Core/Code/Controllers/mitkProgressBar.cpp
@@ -1,132 +1,131 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkProgressBar.h"
#include "mitkCallbackFromGUIThread.h"
#include "mitkProgressBarImplementation.h"
#include <itkObjectFactory.h>
#include <itkOutputWindow.h>
#include <itkCommand.h>
#include <algorithm>
namespace mitk
{
ProgressBar* ProgressBar::m_Instance = NULL;
/**
* Sets the current amount of progress to current progress + steps.
* @param steps the number of steps done since last Progress(int steps) call.
*/
void ProgressBar::Progress(unsigned int steps)
{
if ( !m_Implementations.empty() )
{
ProgressBarImplementationsListIterator iter;
for ( iter = m_Implementations.begin(); iter != m_Implementations.end(); iter++ )
{
// update progress for all ProgressBarImplementations
if ( (*iter) != NULL )
{
(*iter)->Progress(steps);
}
}
}
}
/**
* Adds steps to totalSteps.
*/
void ProgressBar::AddStepsToDo(unsigned int steps)
{
if ( !m_Implementations.empty() )
{
ProgressBarImplementationsListIterator iter;
for ( iter = m_Implementations.begin(); iter != m_Implementations.end(); iter++ )
{
// set steps to do for all ProgressBarImplementations
if ( (*iter) != NULL )
{
(*iter)->AddStepsToDo(steps);
}
}
}
}
/**
* Sets whether the current progress value is displayed.
*/
void ProgressBar::SetPercentageVisible(bool visible)
{
if ( !m_Implementations.empty() )
{
ProgressBarImplementationsListIterator iter;
for ( iter = m_Implementations.begin(); iter != m_Implementations.end(); iter++ )
{
// set percentage visible for all ProgressBarImplementations
if ( (*iter) != NULL )
{
(*iter)->SetPercentageVisible(visible);
}
}
}
}
/**
* Get the instance of this ProgressBar
*/
ProgressBar* ProgressBar::GetInstance()
{
if (m_Instance == NULL)
{
m_Instance = new ProgressBar();
}
return m_Instance;
}
/**
* Set an instance of this; application must do this!See Header!
*/
void ProgressBar::RegisterImplementationInstance(ProgressBarImplementation* implementation)
{
if ( std::find( m_Implementations.begin(), m_Implementations.end(), implementation ) == m_Implementations.end() )
{
m_Implementations.push_back( implementation );
}
}
void ProgressBar::UnregisterImplementationInstance(ProgressBarImplementation* implementation)
{
ProgressBarImplementationsListIterator iter = std::find( m_Implementations.begin(), m_Implementations.end(), implementation );
if ( iter != m_Implementations.end() )
{
m_Implementations.erase( iter );
}
}
ProgressBar::ProgressBar()
{
}
ProgressBar::~ProgressBar()
{
}
}//end namespace mitk
diff --git a/Core/Code/Controllers/mitkProgressBar.h b/Core/Code/Controllers/mitkProgressBar.h
index 385b1fddaf..97ae84f0a3 100644
--- a/Core/Code/Controllers/mitkProgressBar.h
+++ b/Core/Code/Controllers/mitkProgressBar.h
@@ -1,86 +1,85 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPROGRESSBAR_H
#define MITKPROGRESSBAR_H
#include <itkObject.h>
#include <MitkExports.h>
namespace mitk
{
class ProgressBarImplementation;
//##Documentation
//## @brief Sending a message to the applications ProgressBar
//##
//## Holds a GUI dependent ProgressBarImplementation and sends the progress further.
//## All mitk-classes use this class to display progress on GUI-ProgressBar.
//## The mainapplication has to set the internal held ProgressBarImplementation with SetImplementationInstance(..).
//## @ingroup Interaction
class MITK_CORE_EXPORT ProgressBar : public itk::Object
{
public:
itkTypeMacro(ProgressBar, itk::Object);
//##Documentation
//## @brief static method to get the GUI dependent ProgressBar-instance
//## so the methods for steps to do and progress can be called
//## No reference counting, cause of decentral static use!
static ProgressBar* GetInstance();
//##Documentation
//## @brief Supply a GUI- dependent ProgressBar. Has to be set by the application
//## to connect the application dependent subclass of mitkProgressBar
void RegisterImplementationInstance(ProgressBarImplementation* implementation);
void UnregisterImplementationInstance(ProgressBarImplementation* implementation);
//##Documentation
//## @brief Adds steps to totalSteps.
void AddStepsToDo(unsigned int steps);
//##Documentation
//## @brief Sets the current amount of progress to current progress + steps.
//## @param: steps the number of steps done since last Progress(int steps) call.
void Progress(unsigned int steps = 1);
//##Documentation
//## @brief Sets whether the current progress value is displayed.
void SetPercentageVisible (bool visible);
protected:
typedef std::vector< ProgressBarImplementation* > ProgressBarImplementationsList;
typedef ProgressBarImplementationsList::iterator ProgressBarImplementationsListIterator;
ProgressBar();
virtual ~ProgressBar();
ProgressBarImplementationsList m_Implementations;
static ProgressBar* m_Instance;
};
}// end namespace mitk
#endif /* define MITKPROGRESSBAR_H */
diff --git a/Core/Code/Controllers/mitkProgressBarImplementation.h b/Core/Code/Controllers/mitkProgressBarImplementation.h
index 44dbf7c591..ae2a1fd8e0 100644
--- a/Core/Code/Controllers/mitkProgressBarImplementation.h
+++ b/Core/Code/Controllers/mitkProgressBarImplementation.h
@@ -1,58 +1,57 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPROGRESSBARIMPLEMENTATION_H
#define MITKPROGRESSBARIMPLEMENTATION_H
#include <MitkExports.h>
namespace mitk
{
//##Documentation
//## @brief GUI indepentent Interface for all Gui depentent implementations of a ProgressBar.
class MITK_CORE_EXPORT ProgressBarImplementation
{
public:
//##Documentation
//## @brief Constructor
ProgressBarImplementation(){};
//##Documentation
//## @brief Destructor
virtual ~ProgressBarImplementation(){};
//##Documentation
//## @brief Sets whether the current progress value is displayed.
virtual void SetPercentageVisible (bool visible) =0;
//##Documentation
//## @brief Adds steps to totalSteps.
virtual void AddStepsToDo(unsigned int steps) =0;
//##Documentation
//## @brief Sets the current amount of progress to current progress + steps.
//## @param steps the number of steps done since last Progress(int steps) call.
virtual void Progress(unsigned int steps) =0;
};
}// end namespace mitk
#endif /* define MITKPROGRESSBARIMPLEMENTATION_H */
diff --git a/Core/Code/Controllers/mitkReferenceCountWatcher.h b/Core/Code/Controllers/mitkReferenceCountWatcher.h
index b3cea990b9..21761850e9 100644
--- a/Core/Code/Controllers/mitkReferenceCountWatcher.h
+++ b/Core/Code/Controllers/mitkReferenceCountWatcher.h
@@ -1,108 +1,107 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "itkCommand.h"
#include <MitkExports.h>
namespace mitk
{
//##Documentation
//## @brief Keeps track of the reference count of an object even if
//## it is destroyed.
//##
//## Example usage:
//## \code
//## SomeFilter* filter = GetSomeFilter();
//## ReferenceCountWatcher::Pointer filterWatcher;
//## filterWatcher = new ReferenceCountWatcher(filter, "name of filter");
//## filterWatcher->GetReferenceCount();
//## \endcode
//## @ingroup Testing
class ReferenceCountWatcher : public itk::Object
{
public:
typedef itk::SimpleMemberCommand<ReferenceCountWatcher> CommandType;
mitkClassMacro(ReferenceCountWatcher, itk::Object);
protected:
//##Documentation
//## @brief Object to be watched
itk::Object* m_Object;
//##Documentation
//## @brief Optional comment, e.g. for debugging output
std::string m_Comment;
//##Documentation
//## @brief If \a true, \a m_Object is no longer valid
//## and the returned reference count will be 0.
bool m_Deleted;
//##Documentation
//## @brief itk::Command to get a notification when the object
//## is deleted.
CommandType::Pointer m_DeleteCommand;
public:
//##Documentation
//## @brief Constructor requiring object to be watched and allowing
//## an optional comment.
ReferenceCountWatcher(itk::Object* o, const char *comment="") : m_Object(o), m_Comment(comment), m_Deleted(false), m_ObserverTag(0)
{
m_DeleteCommand = CommandType::New();
m_DeleteCommand->SetCallbackFunction(this, &ReferenceCountWatcher::DeleteObserver);
if(m_Object!=NULL)
m_ObserverTag = m_Object->AddObserver(itk::DeleteEvent(), m_DeleteCommand);
m_ReferenceCountLock.Lock();
m_ReferenceCount = 0;
m_ReferenceCountLock.Unlock();
}
//##Documentation
//## @brief Destructor: remove observer
~ReferenceCountWatcher()
{
if((m_Deleted == false) && (m_Object != NULL))
{
m_Object->RemoveObserver(m_ObserverTag);
}
}
//##Documentation
//## @brief Return the reference count of the watched object or
//## 0 if it has been destroyed
int GetReferenceCount() const
{
if(m_Object == NULL) return -1;
if(m_Deleted) return 0;
return m_Object->GetReferenceCount();
}
//##Documentation
//## @brief Return the optional string comment
itkGetStringMacro(Comment);
protected:
//##Documentation
//## @brief Callback called on itk::DeleteEvent() of wathched object.
void DeleteObserver()
{
m_Deleted = true;
}
unsigned long m_ObserverTag;
};
}
diff --git a/Core/Code/Controllers/mitkRenderingManager.cpp b/Core/Code/Controllers/mitkRenderingManager.cpp
index e67e297d4c..61bfbd3641 100644
--- a/Core/Code/Controllers/mitkRenderingManager.cpp
+++ b/Core/Code/Controllers/mitkRenderingManager.cpp
@@ -1,1038 +1,1037 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRenderingManager.h"
#include "mitkRenderingManagerFactory.h"
#include "mitkBaseRenderer.h"
#include "mitkGlobalInteraction.h"
#include <vtkRenderWindow.h>
#include <itkCommand.h>
#include "mitkVector.h"
#include <itkAffineGeometryFrame.h>
#include <itkScalableAffineTransform.h>
#include <mitkVtkPropRenderer.h>
#include <algorithm>
namespace mitk
{
RenderingManager::Pointer RenderingManager::s_Instance = 0;
RenderingManagerFactory *RenderingManager::s_RenderingManagerFactory = 0;
RenderingManager
::RenderingManager()
: m_UpdatePending( false ),
m_MaxLOD( 1 ),
m_LODIncreaseBlocked( false ),
m_LODAbortMechanismEnabled( false ),
m_ClippingPlaneEnabled( false ),
m_TimeNavigationController( NULL ),
m_DataStorage( NULL ),
m_ConstrainedPaddingZooming ( true )
{
m_ShadingEnabled.assign( 3, false );
m_ShadingValues.assign( 4, 0.0 );
m_GlobalInteraction = mitk::GlobalInteraction::GetInstance();
InitializePropertyList();
}
RenderingManager
::~RenderingManager()
{
// Decrease reference counts of all registered vtkRenderWindows for
// proper destruction
RenderWindowVector::iterator it;
for ( it = m_AllRenderWindows.begin(); it != m_AllRenderWindows.end(); ++it )
{
(*it)->UnRegister( NULL );
RenderWindowCallbacksList::iterator callbacks_it = this->m_RenderWindowCallbacksList.find(*it);
(*it)->RemoveObserver(callbacks_it->second.commands[0u]);
(*it)->RemoveObserver(callbacks_it->second.commands[1u]);
(*it)->RemoveObserver(callbacks_it->second.commands[2u]);
}
}
void
RenderingManager
::SetFactory( RenderingManagerFactory *factory )
{
s_RenderingManagerFactory = factory;
}
const RenderingManagerFactory *
RenderingManager
::GetFactory()
{
return s_RenderingManagerFactory;
}
bool
RenderingManager
::HasFactory()
{
if ( RenderingManager::s_RenderingManagerFactory )
{
return true;
}
else
{
return false;
}
}
RenderingManager::Pointer
RenderingManager
::New()
{
const RenderingManagerFactory* factory = GetFactory();
if(factory == NULL)
return NULL;
return factory->CreateRenderingManager();
}
RenderingManager *
RenderingManager
::GetInstance()
{
if ( !RenderingManager::s_Instance )
{
if ( s_RenderingManagerFactory )
{
s_Instance = s_RenderingManagerFactory->CreateRenderingManager();
}
}
return s_Instance;
}
bool
RenderingManager
::IsInstantiated()
{
if ( RenderingManager::s_Instance )
return true;
else
return false;
}
void
RenderingManager
::AddRenderWindow( vtkRenderWindow *renderWindow )
{
if ( renderWindow
&& (m_RenderWindowList.find( renderWindow ) == m_RenderWindowList.end()) )
{
m_RenderWindowList[renderWindow] = RENDERING_INACTIVE;
m_AllRenderWindows.push_back( renderWindow );
if ( m_DataStorage.IsNotNull() )
mitk::BaseRenderer::GetInstance( renderWindow )->SetDataStorage( m_DataStorage.GetPointer() );
// Register vtkRenderWindow instance
renderWindow->Register( NULL );
typedef itk::MemberCommand< RenderingManager > MemberCommandType;
// Add callbacks for rendering abort mechanism
//BaseRenderer *renderer = BaseRenderer::GetInstance( renderWindow );
vtkCallbackCommand *startCallbackCommand = vtkCallbackCommand::New();
startCallbackCommand->SetCallback(
RenderingManager::RenderingStartCallback );
renderWindow->AddObserver( vtkCommand::StartEvent, startCallbackCommand );
vtkCallbackCommand *progressCallbackCommand = vtkCallbackCommand::New();
progressCallbackCommand->SetCallback(
RenderingManager::RenderingProgressCallback );
renderWindow->AddObserver( vtkCommand::AbortCheckEvent, progressCallbackCommand );
vtkCallbackCommand *endCallbackCommand = vtkCallbackCommand::New();
endCallbackCommand->SetCallback(
RenderingManager::RenderingEndCallback );
renderWindow->AddObserver( vtkCommand::EndEvent, endCallbackCommand );
RenderWindowCallbacks callbacks;
callbacks.commands[0u] = startCallbackCommand;
callbacks.commands[1u] = progressCallbackCommand;
callbacks.commands[2u] = endCallbackCommand;
this->m_RenderWindowCallbacksList[renderWindow] = callbacks;
//Delete vtk variables correctly
startCallbackCommand->Delete();
progressCallbackCommand->Delete();
endCallbackCommand->Delete();
}
}
void
RenderingManager
::RemoveRenderWindow( vtkRenderWindow *renderWindow )
{
if (m_RenderWindowList.erase( renderWindow ))
{
RenderWindowCallbacksList::iterator callbacks_it = this->m_RenderWindowCallbacksList.find(renderWindow);
renderWindow->RemoveObserver(callbacks_it->second.commands[0u]);
renderWindow->RemoveObserver(callbacks_it->second.commands[1u]);
renderWindow->RemoveObserver(callbacks_it->second.commands[2u]);
this->m_RenderWindowCallbacksList.erase(callbacks_it);
RenderWindowVector::iterator rw_it = std::find( m_AllRenderWindows.begin(), m_AllRenderWindows.end(), renderWindow );
// Decrease reference count for proper destruction
(*rw_it)->UnRegister(NULL);
m_AllRenderWindows.erase( rw_it );
}
}
const RenderingManager::RenderWindowVector&
RenderingManager
::GetAllRegisteredRenderWindows()
{
return m_AllRenderWindows;
}
void
RenderingManager
::RequestUpdate( vtkRenderWindow *renderWindow )
{
// If the renderWindow is not valid, we do not want to inadvertantly create
// an entry in the m_RenderWindowList map. It is possible if the user is
// regularly calling AddRenderer and RemoveRenderer for a rendering update
// to come into this method with a renderWindow pointer that is valid in the
// sense that the window does exist within the application, but that
// renderWindow has been temporarily removed from this RenderingManager for
// performance reasons.
if (m_RenderWindowList.find( renderWindow ) == m_RenderWindowList.end())
{
return;
}
m_RenderWindowList[renderWindow] = RENDERING_REQUESTED;
if ( !m_UpdatePending )
{
m_UpdatePending = true;
this->GenerateRenderingRequestEvent();
}
}
void
RenderingManager
::ForceImmediateUpdate( vtkRenderWindow *renderWindow )
{
// If the renderWindow is not valid, we do not want to inadvertantly create
// an entry in the m_RenderWindowList map. It is possible if the user is
// regularly calling AddRenderer and RemoveRenderer for a rendering update
// to come into this method with a renderWindow pointer that is valid in the
// sense that the window does exist within the application, but that
// renderWindow has been temporarily removed from this RenderingManager for
// performance reasons.
if (m_RenderWindowList.find( renderWindow ) == m_RenderWindowList.end())
{
return;
}
// Erase potentially pending requests for this window
m_RenderWindowList[renderWindow] = RENDERING_INACTIVE;
m_UpdatePending = false;
// Immediately repaint this window (implementation platform specific)
// If the size is 0 it crahses
int *size = renderWindow->GetSize();
if ( 0 != size[0] && 0 != size[1] )
{
//prepare the camera etc. before rendering
//Note: this is a very important step which should be called before the VTK render!
//If you modify the camera anywhere else or after the render call, the scene cannot be seen.
mitk::VtkPropRenderer *vPR =
dynamic_cast<mitk::VtkPropRenderer*>(mitk::BaseRenderer::GetInstance( renderWindow ));
if(vPR)
vPR->PrepareRender();
// Execute rendering
renderWindow->Render();
}
}
void
RenderingManager
::RequestUpdateAll( RequestType type )
{
RenderWindowList::iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
int id = BaseRenderer::GetInstance(it->first)->GetMapperID();
if ( (type == REQUEST_UPDATE_ALL)
|| ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1))
|| ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)) )
{
this->RequestUpdate( it->first );
}
}
}
void
RenderingManager
::ForceImmediateUpdateAll( RequestType type )
{
RenderWindowList::iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
int id = BaseRenderer::GetInstance(it->first)->GetMapperID();
if ( (type == REQUEST_UPDATE_ALL)
|| ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1))
|| ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)) )
{
// Immediately repaint this window (implementation platform specific)
// If the size is 0, it crashes
this->ForceImmediateUpdate(it->first);
// int *size = it->first->GetSize();
// if ( 0 != size[0] && 0 != size[1] )
// {
// //prepare the camera before rendering
// //Note: this is a very important step which should be called before the VTK render!
// //If you modify the camera anywhere else or after the render call, the scene cannot be seen.
// mitk::VtkPropRenderer *vPR =
// dynamic_cast<mitk::VtkPropRenderer*>(mitk::BaseRenderer::GetInstance( it->first ));
// if(vPR)
// vPR->PrepareRender();
// // Execute rendering
// it->first->Render();
// }
// it->second = RENDERING_INACTIVE;
}
}
//m_UpdatePending = false;
}
//bool RenderingManager::InitializeViews( const mitk::DataStorage * storage, const DataNode* node = NULL, RequestType type, bool preserveRoughOrientationInWorldSpace )
//{
// mitk::Geometry3D::Pointer geometry;
// if ( storage != NULL )
// {
// geometry = storage->ComputeVisibleBoundingGeometry3D(node, "visible", NULL, "includeInBoundingBox" );
//
// if ( geometry.IsNotNull() )
// {
// // let's see if we have data with a limited live-span ...
// mitk::TimeBounds timebounds = geometry->GetTimeBounds();
// if ( timebounds[1] < mitk::ScalarTypeNumericTraits::max() )
// {
// mitk::ScalarType duration = timebounds[1]-timebounds[0];
//
// mitk::TimeSlicedGeometry::Pointer timegeometry =
// mitk::TimeSlicedGeometry::New();
// timegeometry->InitializeEvenlyTimed(
// geometry, (unsigned int) duration );
// timegeometry->SetTimeBounds( timebounds );
//
// timebounds[1] = timebounds[0] + 1.0;
// geometry->SetTimeBounds( timebounds );
//
// geometry = timegeometry;
// }
// }
// }
//
// // Use geometry for initialization
// return this->InitializeViews( geometry.GetPointer(), type );
//}
bool
RenderingManager
::InitializeViews( const Geometry3D * dataGeometry, RequestType type, bool preserveRoughOrientationInWorldSpace )
{
MITK_DEBUG << "initializing views";
bool boundingBoxInitialized = false;
Geometry3D::ConstPointer geometry = dataGeometry;
if (dataGeometry && preserveRoughOrientationInWorldSpace)
{
// clone the input geometry
Geometry3D::Pointer modifiedGeometry = dynamic_cast<Geometry3D*>( dataGeometry->Clone().GetPointer() );
assert(modifiedGeometry.IsNotNull());
// construct an affine transform from it
AffineGeometryFrame3D::TransformType::Pointer transform = AffineGeometryFrame3D::TransformType::New();
assert( modifiedGeometry->GetIndexToWorldTransform() );
transform->SetMatrix( modifiedGeometry->GetIndexToWorldTransform()->GetMatrix() );
transform->SetOffset( modifiedGeometry->GetIndexToWorldTransform()->GetOffset() );
// get transform matrix
AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType& oldMatrix =
const_cast< AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType& > ( transform->GetMatrix().GetVnlMatrix() );
AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType newMatrix(oldMatrix);
// get offset and bound
Vector3D offset = modifiedGeometry->GetIndexToWorldTransform()->GetOffset();
Geometry3D::BoundsArrayType oldBounds = modifiedGeometry->GetBounds();
Geometry3D::BoundsArrayType newBounds = modifiedGeometry->GetBounds();
// get rid of rotation other than pi/2 degree
for ( unsigned int i = 0; i < 3; ++i )
{
// i-th column of the direction matrix
Vector3D currentVector;
currentVector[0] = oldMatrix(0,i);
currentVector[1] = oldMatrix(1,i);
currentVector[2] = oldMatrix(2,i);
// matchingRow will store the row that holds the biggest
// value in the column
unsigned int matchingRow = 0;
// maximum value in the column
float max = std::numeric_limits<float>::min();
// sign of the maximum value (-1 or 1)
int sign = 1;
// iterate through the column vector
for (unsigned int dim = 0; dim < 3; ++dim)
{
if ( fabs(currentVector[dim]) > max )
{
matchingRow = dim;
max = fabs(currentVector[dim]);
if(currentVector[dim]<0)
sign = -1;
else
sign = 1;
}
}
// in case we found a negative maximum,
// we negate the column and adjust the offset
// (in order to run through the dimension in the opposite direction)
if(sign == -1)
{
currentVector *= sign;
offset += modifiedGeometry->GetAxisVector(i);
}
// matchingRow is now used as column index to place currentVector
// correctly in the new matrix
vnl_vector<ScalarType> newMatrixColumn(3);
newMatrixColumn[0] = currentVector[0];
newMatrixColumn[1] = currentVector[1];
newMatrixColumn[2] = currentVector[2];
newMatrix.set_column( matchingRow, newMatrixColumn );
// if a column is moved, we also have to adjust the bounding
// box accordingly, this is done here
newBounds[2*matchingRow ] = oldBounds[2*i ];
newBounds[2*matchingRow+1] = oldBounds[2*i+1];
}
// set the newly calculated bounds array
modifiedGeometry->SetBounds(newBounds);
// set new offset and direction matrix
AffineGeometryFrame3D::TransformType::MatrixType newMatrixITK( newMatrix );
transform->SetMatrix( newMatrixITK );
transform->SetOffset( offset );
modifiedGeometry->SetIndexToWorldTransform( transform );
geometry = modifiedGeometry;
}
int warningLevel = vtkObject::GetGlobalWarningDisplay();
vtkObject::GlobalWarningDisplayOff();
if ( (geometry.IsNotNull() ) && (const_cast< mitk::BoundingBox * >(
geometry->GetBoundingBox())->GetDiagonalLength2() > mitk::eps) )
{
boundingBoxInitialized = true;
}
if (geometry.IsNotNull() )
{// make sure bounding box has an extent bigger than zero in any direction
// clone the input geometry
Geometry3D::Pointer modifiedGeometry = dynamic_cast<Geometry3D*>( dataGeometry->Clone().GetPointer() );
assert(modifiedGeometry.IsNotNull());
Geometry3D::BoundsArrayType newBounds = modifiedGeometry->GetBounds();
for( unsigned int dimension = 0; ( 2 * dimension ) < newBounds.Size() ; dimension++ )
{
//check for equality but for an epsilon
if( Equal( newBounds[ 2 * dimension ], newBounds[ 2 * dimension + 1 ] ) )
{
newBounds[ 2 * dimension + 1 ] += 1;
}
}
// set the newly calculated bounds array
modifiedGeometry->SetBounds(newBounds);
geometry = modifiedGeometry;
}
RenderWindowList::iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
mitk::BaseRenderer *baseRenderer =
mitk::BaseRenderer::GetInstance( it->first );
baseRenderer->GetDisplayGeometry()->SetConstrainZoomingAndPanning(m_ConstrainedPaddingZooming);
int id = baseRenderer->GetMapperID();
if ( ((type == REQUEST_UPDATE_ALL)
|| ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1))
|| ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)))
)
{
this->InternalViewInitialization( baseRenderer, geometry,
boundingBoxInitialized, id );
}
}
if ( m_TimeNavigationController != NULL )
{
if ( boundingBoxInitialized )
{
m_TimeNavigationController->SetInputWorldGeometry( geometry );
}
m_TimeNavigationController->Update();
}
this->RequestUpdateAll( type );
vtkObject::SetGlobalWarningDisplay( warningLevel );
// Inform listeners that views have been initialized
this->InvokeEvent( mitk::RenderingManagerViewsInitializedEvent() );
return boundingBoxInitialized;
}
bool
RenderingManager
::InitializeViews( RequestType type )
{
RenderWindowList::iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
mitk::BaseRenderer *baseRenderer =
mitk::BaseRenderer::GetInstance( it->first );
int id = baseRenderer->GetMapperID();
if ( (type == REQUEST_UPDATE_ALL)
|| ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1))
|| ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)) )
{
mitk::SliceNavigationController *nc =
baseRenderer->GetSliceNavigationController();
// Re-initialize view direction
nc->SetViewDirectionToDefault();
// Update the SNC
nc->Update();
}
}
this->RequestUpdateAll( type );
return true;
}
//bool RenderingManager::InitializeView( vtkRenderWindow * renderWindow, const DataStorage* ds, const DataNode node = NULL, bool initializeGlobalTimeSNC )
//{
// mitk::Geometry3D::Pointer geometry;
// if ( ds != NULL )
// {
// geometry = ds->ComputeVisibleBoundingGeometry3D(node, NULL, "includeInBoundingBox" );
//
// if ( geometry.IsNotNull() )
// {
// // let's see if we have data with a limited live-span ...
// mitk::TimeBounds timebounds = geometry->GetTimeBounds();
// if ( timebounds[1] < mitk::ScalarTypeNumericTraits::max() )
// {
// mitk::ScalarType duration = timebounds[1]-timebounds[0];
//
// mitk::TimeSlicedGeometry::Pointer timegeometry =
// mitk::TimeSlicedGeometry::New();
// timegeometry->InitializeEvenlyTimed(
// geometry, (unsigned int) duration );
// timegeometry->SetTimeBounds( timebounds );
//
// timebounds[1] = timebounds[0] + 1.0;
// geometry->SetTimeBounds( timebounds );
//
// geometry = timegeometry;
// }
// }
// }
//
// // Use geometry for initialization
// return this->InitializeView( renderWindow,
// geometry.GetPointer(), initializeGlobalTimeSNC );
//}
bool RenderingManager::InitializeView( vtkRenderWindow * renderWindow, const Geometry3D * geometry, bool initializeGlobalTimeSNC )
{
bool boundingBoxInitialized = false;
int warningLevel = vtkObject::GetGlobalWarningDisplay();
vtkObject::GlobalWarningDisplayOff();
if ( (geometry != NULL ) && (const_cast< mitk::BoundingBox * >(
geometry->GetBoundingBox())->GetDiagonalLength2() > mitk::eps) )
{
boundingBoxInitialized = true;
}
mitk::BaseRenderer *baseRenderer =
mitk::BaseRenderer::GetInstance( renderWindow );
int id = baseRenderer->GetMapperID();
this->InternalViewInitialization( baseRenderer, geometry,
boundingBoxInitialized, id );
if ( m_TimeNavigationController != NULL )
{
if ( boundingBoxInitialized && initializeGlobalTimeSNC )
{
m_TimeNavigationController->SetInputWorldGeometry( geometry );
}
m_TimeNavigationController->Update();
}
this->RequestUpdate( renderWindow );
vtkObject::SetGlobalWarningDisplay( warningLevel );
return boundingBoxInitialized;
}
bool RenderingManager::InitializeView( vtkRenderWindow * renderWindow )
{
mitk::BaseRenderer *baseRenderer =
mitk::BaseRenderer::GetInstance( renderWindow );
mitk::SliceNavigationController *nc =
baseRenderer->GetSliceNavigationController();
// Re-initialize view direction
nc->SetViewDirectionToDefault();
// Update the SNC
nc->Update();
this->RequestUpdate( renderWindow );
return true;
}
void RenderingManager::InternalViewInitialization(mitk::BaseRenderer *baseRenderer, const mitk::Geometry3D *geometry, bool boundingBoxInitialized, int mapperID )
{
mitk::SliceNavigationController *nc = baseRenderer->GetSliceNavigationController();
// Re-initialize view direction
nc->SetViewDirectionToDefault();
if ( boundingBoxInitialized )
{
// Set geometry for NC
nc->SetInputWorldGeometry( geometry );
nc->Update();
if ( mapperID == 1 )
{
// For 2D SNCs, steppers are set so that the cross is centered
// in the image
nc->GetSlice()->SetPos( nc->GetSlice()->GetSteps() / 2 );
}
// Fit the render window DisplayGeometry
baseRenderer->GetDisplayGeometry()->Fit();
baseRenderer->GetCameraController()->SetViewToAnterior();
}
else
{
nc->Update();
}
}
void RenderingManager::SetTimeNavigationController( SliceNavigationController *nc )
{
m_TimeNavigationController = nc;
}
const SliceNavigationController* RenderingManager::GetTimeNavigationController() const
{
return m_TimeNavigationController;
}
SliceNavigationController* RenderingManager::GetTimeNavigationController()
{
return m_TimeNavigationController;
}
void RenderingManager::ExecutePendingRequests()
{
m_UpdatePending = false;
// Satisfy all pending update requests
RenderWindowList::iterator it;
int i = 0;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it, ++i )
{
if ( it->second == RENDERING_REQUESTED )
{
this->ForceImmediateUpdate( it->first );
}
}
}
void RenderingManager::RenderingStartCallback( vtkObject *caller, unsigned long , void *, void * )
{
vtkRenderWindow *renderWindow = dynamic_cast< vtkRenderWindow * >( caller );
mitk::RenderingManager* renman = mitk::BaseRenderer::GetInstance(renderWindow)->GetRenderingManager();
RenderWindowList &renderWindowList = renman->m_RenderWindowList;
if ( renderWindow )
{
renderWindowList[renderWindow] = RENDERING_INPROGRESS;
}
renman->m_UpdatePending = false;
}
void
RenderingManager
::RenderingProgressCallback( vtkObject *caller, unsigned long , void *, void * )
{
vtkRenderWindow *renderWindow = dynamic_cast< vtkRenderWindow * >( caller );
mitk::RenderingManager* renman = mitk::BaseRenderer::GetInstance(renderWindow)->GetRenderingManager();
if ( renman->m_LODAbortMechanismEnabled )
{
vtkRenderWindow *renderWindow = dynamic_cast< vtkRenderWindow * >( caller );
if ( renderWindow )
{
BaseRenderer *renderer = BaseRenderer::GetInstance( renderWindow );
if ( renderer && (renderer->GetNumberOfVisibleLODEnabledMappers() > 0) )
{
renman->DoMonitorRendering();
}
}
}
}
void
RenderingManager
::RenderingEndCallback( vtkObject *caller, unsigned long , void *, void * )
{
vtkRenderWindow *renderWindow = dynamic_cast< vtkRenderWindow * >( caller );
mitk::RenderingManager* renman = mitk::BaseRenderer::GetInstance(renderWindow)->GetRenderingManager();
RenderWindowList &renderWindowList = renman->m_RenderWindowList;
RendererIntMap &nextLODMap = renman->m_NextLODMap;
if ( renderWindow )
{
BaseRenderer *renderer = BaseRenderer::GetInstance( renderWindow );
if ( renderer )
{
renderWindowList[renderer->GetRenderWindow()] = RENDERING_INACTIVE;
// Level-of-Detail handling
if ( renderer->GetNumberOfVisibleLODEnabledMappers() > 0 )
{
if(nextLODMap[renderer]==0)
renman->StartOrResetTimer();
else
nextLODMap[renderer] = 0;
}
}
}
}
bool
RenderingManager
::IsRendering() const
{
RenderWindowList::const_iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
if ( it->second == RENDERING_INPROGRESS )
{
return true;
}
}
return false;
}
void
RenderingManager
::AbortRendering()
{
RenderWindowList::iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
if ( it->second == RENDERING_INPROGRESS )
{
it->first->SetAbortRender( true );
m_RenderingAbortedMap[BaseRenderer::GetInstance(it->first)] = true;
}
}
}
int
RenderingManager
::GetNextLOD( BaseRenderer *renderer )
{
if ( renderer != NULL )
{
return m_NextLODMap[renderer];
}
else
{
return 0;
}
}
void
RenderingManager
::ExecutePendingHighResRenderingRequest()
{
RenderWindowList::iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
BaseRenderer *renderer = BaseRenderer::GetInstance( it->first );
if(renderer->GetNumberOfVisibleLODEnabledMappers()>0)
{
if(m_NextLODMap[renderer]==0)
{
m_NextLODMap[renderer]=1;
RequestUpdate( it->first );
}
}
}
}
void
RenderingManager
::SetMaximumLOD( unsigned int max )
{
m_MaxLOD = max;
}
//enable/disable shading
void
RenderingManager
::SetShading(bool state, unsigned int lod)
{
if(lod>m_MaxLOD)
{
itkWarningMacro(<<"LOD out of range requested: " << lod << " maxLOD: " << m_MaxLOD);
return;
}
m_ShadingEnabled[lod] = state;
}
bool
RenderingManager
::GetShading(unsigned int lod)
{
if(lod>m_MaxLOD)
{
itkWarningMacro(<<"LOD out of range requested: " << lod << " maxLOD: " << m_MaxLOD);
return false;
}
return m_ShadingEnabled[lod];
}
//enable/disable the clipping plane
void
RenderingManager
::SetClippingPlaneStatus(bool status)
{
m_ClippingPlaneEnabled = status;
}
bool
RenderingManager
::GetClippingPlaneStatus()
{
return m_ClippingPlaneEnabled;
}
void
RenderingManager
::SetShadingValues(float ambient, float diffuse, float specular, float specpower)
{
m_ShadingValues[0] = ambient;
m_ShadingValues[1] = diffuse;
m_ShadingValues[2] = specular;
m_ShadingValues[3] = specpower;
}
RenderingManager::FloatVector &
RenderingManager
::GetShadingValues()
{
return m_ShadingValues;
}
void RenderingManager::SetDepthPeelingEnabled( bool enabled )
{
RenderWindowList::iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance( it->first );
baseRenderer->SetDepthPeelingEnabled(enabled);
}
}
void RenderingManager::SetMaxNumberOfPeels( int maxNumber )
{
RenderWindowList::iterator it;
for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
{
mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance( it->first );
baseRenderer->SetMaxNumberOfPeels(maxNumber);
}
}
void RenderingManager::InitializePropertyList()
{
if (m_PropertyList.IsNull())
{
m_PropertyList = PropertyList::New();
}
this->SetProperty("coupled-zoom", BoolProperty::New(false));
this->SetProperty("coupled-plane-rotation", BoolProperty::New(false));
this->SetProperty("MIP-slice-rendering", BoolProperty::New(false));
}
PropertyList::Pointer RenderingManager::GetPropertyList() const
{
return m_PropertyList;
}
BaseProperty* RenderingManager::GetProperty(const char *propertyKey) const
{
return m_PropertyList->GetProperty(propertyKey);
}
void RenderingManager::SetProperty(const char *propertyKey, BaseProperty* propertyValue)
{
m_PropertyList->SetProperty(propertyKey, propertyValue);
}
void RenderingManager::SetDataStorage( DataStorage* storage )
{
if ( storage != NULL )
{
m_DataStorage = storage;
RenderingManager::RenderWindowVector::iterator iter;
for ( iter = m_AllRenderWindows.begin(); iter<m_AllRenderWindows.end(); iter++ )
{
mitk::BaseRenderer::GetInstance( (*iter) )->SetDataStorage( m_DataStorage.GetPointer() );
}
}
}
mitk::DataStorage* RenderingManager::GetDataStorage()
{
return m_DataStorage;
}
void RenderingManager::SetGlobalInteraction( mitk::GlobalInteraction* globalInteraction )
{
if ( globalInteraction != NULL )
{
m_GlobalInteraction = globalInteraction;
}
}
mitk::GlobalInteraction* RenderingManager::GetGlobalInteraction()
{
return m_GlobalInteraction;
}
// Create and register generic RenderingManagerFactory.
TestingRenderingManagerFactory renderingManagerFactory;
} // namespace
diff --git a/Core/Code/Controllers/mitkRenderingManager.h b/Core/Code/Controllers/mitkRenderingManager.h
index c6f6906834..956e553f02 100644
--- a/Core/Code/Controllers/mitkRenderingManager.h
+++ b/Core/Code/Controllers/mitkRenderingManager.h
@@ -1,420 +1,419 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKRENDERINGMANAGER_H_HEADER_INCLUDED_C135A197
#define MITKRENDERINGMANAGER_H_HEADER_INCLUDED_C135A197
#include <MitkExports.h>
#include <vtkCallbackCommand.h>
#include <string>
#include <itkObject.h>
#include <itkObjectFactory.h>
#include "mitkPropertyList.h"
#include "mitkProperties.h"
class vtkRenderWindow;
class vtkObject;
namespace mitk
{
class RenderingManager;
class RenderingManagerFactory;
class Geometry3D;
class SliceNavigationController;
class BaseRenderer;
class DataStorage;
class GlobalInteraction;
/**
* \brief Manager for coordinating the rendering process.
*
* RenderingManager is a central instance retrieving and executing
* RenderWindow update requests. Its main purpose is to coordinate
* distributed requests which cannot be aware of each other - lacking the
* knowledge of whether they are really necessary or not. For example, two
* objects might determine that a specific RenderWindow needs to be updated.
* This would result in one unnecessary update, if both executed the update
* on their own.
*
* The RenderingManager addresses this by letting each such object
* <em>request</em> an update, and waiting for other objects to possibly
* issue the same request. The actual update will then only be executed at a
* well-defined point in the main event loop (this may be each time after
* event processing is done).
*
* Convinience methods for updating all RenderWindows which have been
* registered with the RenderingManager exist. If theses methods are not
* used, it is not required to register (add) RenderWindows prior to using
* the RenderingManager.
*
* The methods #ForceImmediateUpdate() and #ForceImmediateUpdateAll() can
* be used to force the RenderWindow update execution without any delay,
* bypassing the request functionality.
*
* The interface of RenderingManager is platform independent. Platform
* specific subclasses have to be implemented, though, to supply an
* appropriate event issueing for controlling the update execution process.
* See method documentation for a description of how this can be done.
*
* \sa TestingRenderingManager An "empty" RenderingManager implementation which
* can be used in tests etc.
*
*/
class MITK_CORE_EXPORT RenderingManager : public itk::Object
{
public:
mitkClassMacro(RenderingManager,itk::Object);
typedef std::vector< vtkRenderWindow* > RenderWindowVector;
typedef std::vector< float > FloatVector;
typedef std::vector< bool > BoolVector;
typedef itk::SmartPointer< DataStorage > DataStoragePointer;
typedef itk::SmartPointer< GlobalInteraction > GlobalInteractionPointer;
enum RequestType
{
REQUEST_UPDATE_ALL = 0,
REQUEST_UPDATE_2DWINDOWS,
REQUEST_UPDATE_3DWINDOWS
};
static Pointer New();
/** Set the object factory which produces the desired platform specific
* RenderingManager singleton instance. */
static void SetFactory( RenderingManagerFactory *factory );
/** Get the object factory which produces the platform specific
* RenderingManager instances. */
static const RenderingManagerFactory *GetFactory();
/** Returns true if a factory has already been set. */
static bool HasFactory();
/** Get the RenderingManager singleton instance. */
static RenderingManager *GetInstance();
/** Returns true if the singleton instance does already exist. */
static bool IsInstantiated();
/** Adds a RenderWindow. This is required if the methods #RequestUpdateAll
* or #ForceImmediateUpdate are to be used. */
void AddRenderWindow( vtkRenderWindow *renderWindow );
/** Removes a RenderWindow. */
void RemoveRenderWindow( vtkRenderWindow *renderWindow );
/** Get a list of all registered RenderWindows */
const RenderWindowVector &GetAllRegisteredRenderWindows();
/** Requests an update for the specified RenderWindow, to be executed as
* soon as the main loop is ready for rendering. */
void RequestUpdate( vtkRenderWindow *renderWindow );
/** Immediately executes an update of the specified RenderWindow. */
void ForceImmediateUpdate( vtkRenderWindow *renderWindow );
/** Requests all currently registered RenderWindows to be updated.
* If only 2D or 3D windows should be updated, this can be specified
* via the parameter requestType. */
void RequestUpdateAll( RequestType type = REQUEST_UPDATE_ALL );
/** Immediately executes an update of all registered RenderWindows.
* If only 2D or 3D windows should be updated, this can be specified
* via the parameter requestType. */
void ForceImmediateUpdateAll( RequestType type = REQUEST_UPDATE_ALL );
/** Initializes the windows specified by requestType to the geometry of the
* given DataStorage. */
//virtual bool InitializeViews( const DataStorage *storage, const DataNode* node = NULL,
// RequestType type = REQUEST_UPDATE_ALL, bool preserveRoughOrientationInWorldSpace = false );
/** Initializes the windows specified by requestType to the given
* geometry. PLATFORM SPECIFIC. TODO: HOW IS THIS PLATFORM SPECIFIC? */
virtual bool InitializeViews( const Geometry3D *geometry,
RequestType type = REQUEST_UPDATE_ALL, bool preserveRoughOrientationInWorldSpace = false );
/** Initializes the windows to the default viewing direction
* (geomtry information is NOT changed). PLATFORM SPECIFIC. */
virtual bool InitializeViews( RequestType type = REQUEST_UPDATE_ALL );
/** Initializes the specified window to the geometry of the given
* DataNode. Set "initializeGlobalTimeSNC" to true in order to use this
* geometry as global TimeSlicedGeometry. PLATFORM SPECIFIC. */
//virtual bool InitializeView( vtkRenderWindow *renderWindow, const DataStorage* ds, const DataNode* node = NULL, bool initializeGlobalTimeSNC = false );
/** Initializes the specified window to the given geometry. Set
* "initializeGlobalTimeSNC" to true in order to use this geometry as
* global TimeSlicedGeometry. PLATFORM SPECIFIC. */
virtual bool InitializeView( vtkRenderWindow *renderWindow, const Geometry3D *geometry, bool initializeGlobalTimeSNC = false);
/** Initializes the specified window to the default viewing direction
* (geomtry information is NOT changed). PLATFORM SPECIFIC. */
virtual bool InitializeView( vtkRenderWindow *renderWindow );
/** Sets the (global) SliceNavigationController responsible for
* time-slicing. */
void SetTimeNavigationController( SliceNavigationController *nc );
/** Gets the (global) SliceNavigationController responsible for
* time-slicing. */
const SliceNavigationController *GetTimeNavigationController() const;
/** Gets the (global) SliceNavigationController responsible for
* time-slicing. */
SliceNavigationController *GetTimeNavigationController();
virtual ~RenderingManager();
/** Executes all pending requests. This method has to be called by the
* system whenever a RenderingManager induced request event occurs in
* the system pipeline (see concrete RenderingManager implementations). */
virtual void ExecutePendingRequests();
bool IsRendering() const;
void AbortRendering();
/** En-/Disable LOD increase globally. */
itkSetMacro( LODIncreaseBlocked, bool );
/** En-/Disable LOD increase globally. */
itkGetMacro( LODIncreaseBlocked, bool );
/** En-/Disable LOD increase globally. */
itkBooleanMacro( LODIncreaseBlocked );
/** En-/Disable LOD abort mechanism. */
itkSetMacro( LODAbortMechanismEnabled, bool );
/** En-/Disable LOD abort mechanism. */
itkGetMacro( LODAbortMechanismEnabled, bool );
/** En-/Disable LOD abort mechanism. */
itkBooleanMacro( LODAbortMechanismEnabled );
/** En-/Disable depth peeling for all renderers */
void SetDepthPeelingEnabled(bool enabled);
/** Set maximum number of peels for all renderers */
void SetMaxNumberOfPeels(int maxNumber);
/** Force a sub-class to start a timer for a pending hires-rendering request */
virtual void StartOrResetTimer() {};
/** To be called by a sub-class from a timer callback */
void ExecutePendingHighResRenderingRequest();
virtual void DoStartRendering() {};
virtual void DoMonitorRendering() {};
virtual void DoFinishAbortRendering() {};
int GetNextLOD( BaseRenderer* renderer );
/** Set current LOD (NULL means all renderers)*/
void SetMaximumLOD( unsigned int max );
void SetShading( bool state, unsigned int lod );
bool GetShading( unsigned int lod );
void SetClippingPlaneStatus( bool status );
bool GetClippingPlaneStatus();
void SetShadingValues( float ambient, float diffuse,
float specular, float specpower );
FloatVector &GetShadingValues();
/** Returns a property list */
PropertyList::Pointer GetPropertyList() const;
/** Returns a property from m_PropertyList */
BaseProperty* GetProperty(const char *propertyKey) const;
/** Sets or adds (if not present) a property in m_PropertyList */
void SetProperty(const char *propertyKey, BaseProperty* propertyValue);
/**
* \brief Setter / Getter for internal DataStorage
*
* Sets / returns the mitk::DataStorage that is used internally. This instance holds all mitk::DataNodes that are
* rendered by the registered BaseRenderers.
*
* If this DataStorage is changed at runtime by calling SetDataStorage(),
* all currently registered BaseRenderers are automatically given the correct instance.
* When a new BaseRenderer is added, it is automatically initialized with the currently active DataStorage.
*/
void SetDataStorage( mitk::DataStorage* storage );
/**
* \brief Setter / Getter for internal DataStorage
*
* Sets / returns the mitk::DataStorage that is used internally. This instance holds all mitk::DataNodes that are
* rendered by the registered BaseRenderers.
*
* If this DataStorage is changed at runtime by calling SetDataStorage(),
* all currently registered BaseRenderers are automatically given the correct instance.
* When a new BaseRenderer is added, it is automatically initialized with the currently active DataStorage.
*/
mitk::DataStorage* GetDataStorage();
/**
* \brief Setter / Getter for internal GloabInteraction
*
* Sets / returns the instance of mitk::GlobalInteraction that is internally held.
* It'S not actually used by this class but offers it to all registered BaseRenderers.
* These need it for their own internal initialization of the FocusManager and the corresponding EventMappers.
*/
void SetGlobalInteraction( mitk::GlobalInteraction* globalInteraction );
/**
* \brief Setter / Getter for internal GloabInteraction
*
* Sets / returns the instance of mitk::GlobalInteraction that is internally held.
* It'S not actually used by this class but offers it to all registered BaseRenderers.
* These need it for their own internal initialization of the FocusManager and the corresponding EventMappers.
*/
mitk::GlobalInteraction* GetGlobalInteraction();
itkSetMacro(ConstrainedPaddingZooming, bool);
protected:
enum
{
RENDERING_INACTIVE = 0,
RENDERING_REQUESTED,
RENDERING_INPROGRESS
};
RenderingManager();
/** Abstract method for generating a system specific event for rendering
* request. This method is called whenever an update is requested */
virtual void GenerateRenderingRequestEvent() = 0;
virtual void InitializePropertyList();
bool m_UpdatePending;
typedef std::map< BaseRenderer *, unsigned int > RendererIntMap;
typedef std::map< BaseRenderer *, bool > RendererBoolMap;
RendererBoolMap m_RenderingAbortedMap;
RendererIntMap m_NextLODMap;
unsigned int m_MaxLOD;
bool m_LODIncreaseBlocked;
bool m_LODAbortMechanismEnabled;
BoolVector m_ShadingEnabled;
bool m_ClippingPlaneEnabled;
FloatVector m_ShadingValues;
static void RenderingStartCallback(
vtkObject *caller, unsigned long eid, void *clientdata, void *calldata );
static void RenderingProgressCallback(
vtkObject *caller, unsigned long eid, void *clientdata, void *calldata );
static void RenderingEndCallback(
vtkObject *caller, unsigned long eid, void *clientdata, void *calldata );
typedef std::map< vtkRenderWindow *, int > RenderWindowList;
RenderWindowList m_RenderWindowList;
RenderWindowVector m_AllRenderWindows;
struct RenderWindowCallbacks
{
vtkCallbackCommand* commands[3u];
};
typedef std::map<vtkRenderWindow*, RenderWindowCallbacks> RenderWindowCallbacksList;
RenderWindowCallbacksList m_RenderWindowCallbacksList;
SliceNavigationController *m_TimeNavigationController;
static RenderingManager::Pointer s_Instance;
static RenderingManagerFactory *s_RenderingManagerFactory;
PropertyList::Pointer m_PropertyList;
DataStoragePointer m_DataStorage;
GlobalInteractionPointer m_GlobalInteraction;
bool m_ConstrainedPaddingZooming;
private:
void InternalViewInitialization(
mitk::BaseRenderer *baseRenderer, const mitk::Geometry3D *geometry,
bool boundingBoxInitialized, int mapperID );
};
#pragma GCC visibility push(default)
itkEventMacro( RenderingManagerEvent, itk::AnyEvent );
itkEventMacro( RenderingManagerViewsInitializedEvent, RenderingManagerEvent );
#pragma GCC visibility pop
/**
* Generic RenderingManager implementation for "non-rendering-plattform",
* e.g. for tests. Its factory (TestingRenderingManagerFactory) is
* automatically on start-up and is used by default if not other
* RenderingManagerFactory is instantiated explicitly thereafter.
* (see mitkRenderingManager.cpp)
*/
class MITK_CORE_EXPORT TestingRenderingManager : public RenderingManager
{
public:
mitkClassMacro(TestingRenderingManager,RenderingManager);
itkNewMacro(Self);
protected:
virtual void GenerateRenderingRequestEvent()
{
ForceImmediateUpdateAll();
};
};
} // namespace mitk
#endif /* MITKRenderingManager_H_HEADER_INCLUDED_C135A197 */
diff --git a/Core/Code/Controllers/mitkRenderingManagerFactory.h b/Core/Code/Controllers/mitkRenderingManagerFactory.h
index f05a84a5bb..a835fc376f 100644
--- a/Core/Code/Controllers/mitkRenderingManagerFactory.h
+++ b/Core/Code/Controllers/mitkRenderingManagerFactory.h
@@ -1,92 +1,91 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKRENDERINGMANAGERFACTORY_H_HEADER_INCLUDED_C135A197
#define MITKRENDERINGMANAGERFACTORY_H_HEADER_INCLUDED_C135A197
#include "mitkRenderingManager.h"
namespace mitk
{
/**
* \brief Factory interface for facilitating the usage of a platform-specific
* mitk::RenderingManager instance.
*
* This class provides an interface for creating the required singleton
* instance of RenderingManager. Concrete platform-specific subclasses should
* be instantiated once during startup of the framework (e.g. as a static
* instance). Their constructor then merely has to call
* mitk::RenderingManager::SetFactory().
*
* \note Instead of using an external class for the manager
* instantiation, the factory mechanism could be integrated into the
* RenderingManager (and its subclasses) itself. However, this would make
* the framework specific instantiation more complicated. Simply creating a
* static instance somewhere would not work since RenderingManager derives from
* itk::Object, which itself depends on the initialization of static members
* (which is problematic since the order of static member initializations
* cannot easily be controlled).
* \ingroup Renderer
*/
class MITK_CORE_EXPORT RenderingManagerFactory
{
public:
virtual ~RenderingManagerFactory() {};
/** \brief Factory method to create platform specific instances of
* RenderingManager. */
virtual RenderingManager::Pointer CreateRenderingManager() const = 0;
protected:
RenderingManagerFactory()
{
};
private:
};
/**
* Factory for the TestingRenderingManager
*/
class MITK_CORE_EXPORT TestingRenderingManagerFactory : public RenderingManagerFactory
{
public:
TestingRenderingManagerFactory()
{
if ( !mitk::RenderingManager::HasFactory() )
{
mitk::RenderingManager::SetFactory( this );
}
};
virtual ~TestingRenderingManagerFactory() {};
virtual mitk::RenderingManager::Pointer CreateRenderingManager() const
{
TestingRenderingManager::Pointer specificSmartPtr = TestingRenderingManager::New();
RenderingManager::Pointer smartPtr = specificSmartPtr.GetPointer();
return smartPtr;
};
};
} // namespace mitk
#endif
diff --git a/Core/Code/Controllers/mitkSliceNavigationController.cpp b/Core/Code/Controllers/mitkSliceNavigationController.cpp
index 97d98babf2..fdc3b2fd2d 100644
--- a/Core/Code/Controllers/mitkSliceNavigationController.cpp
+++ b/Core/Code/Controllers/mitkSliceNavigationController.cpp
@@ -1,735 +1,734 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSliceNavigationController.h"
#include "mitkBaseRenderer.h"
#include "mitkSlicedGeometry3D.h"
#include "mitkPlaneGeometry.h"
#include "mitkOperation.h"
#include "mitkOperationActor.h"
#include "mitkStateEvent.h"
#include "mitkCrosshairPositionEvent.h"
#include "mitkPositionEvent.h"
#include "mitkInteractionConst.h"
#include "mitkAction.h"
#include "mitkGlobalInteraction.h"
#include "mitkEventMapper.h"
#include "mitkFocusManager.h"
#include "mitkVtkPropRenderer.h"
#include "mitkRenderingManager.h"
#include "mitkInteractionConst.h"
#include "mitkPointOperation.h"
#include "mitkPlaneOperation.h"
#include "mitkUndoController.h"
#include "mitkOperationEvent.h"
#include "mitkNodePredicateDataType.h"
#include "mitkStatusBar.h"
#include "mitkMemoryUtilities.h"
#include <itkCommand.h>
namespace mitk {
SliceNavigationController::SliceNavigationController( const char *type )
: BaseController( type ),
m_InputWorldGeometry( NULL ),
m_CreatedWorldGeometry( NULL ),
m_ViewDirection( Transversal ),
m_DefaultViewDirection( Transversal ),
m_RenderingManager( NULL ),
m_Renderer( NULL ),
m_Top( false ),
m_FrontSide( false ),
m_Rotated( false ),
m_BlockUpdate( false ),
m_SliceLocked( false ),
m_SliceRotationLocked( false ),
m_OldPos(0)
{
typedef itk::SimpleMemberCommand< SliceNavigationController > SNCCommandType;
SNCCommandType::Pointer sliceStepperChangedCommand, timeStepperChangedCommand;
sliceStepperChangedCommand = SNCCommandType::New();
timeStepperChangedCommand = SNCCommandType::New();
sliceStepperChangedCommand->SetCallbackFunction(
this, &SliceNavigationController::SendSlice );
timeStepperChangedCommand->SetCallbackFunction(
this, &SliceNavigationController::SendTime );
m_Slice->AddObserver( itk::ModifiedEvent(), sliceStepperChangedCommand );
m_Time->AddObserver( itk::ModifiedEvent(), timeStepperChangedCommand );
m_Slice->SetUnitName( "mm" );
m_Time->SetUnitName( "ms" );
m_Top = false;
m_FrontSide = false;
m_Rotated = false;
}
SliceNavigationController::~SliceNavigationController()
{
}
void
SliceNavigationController::SetInputWorldGeometry( const Geometry3D *geometry )
{
if ( geometry != NULL )
{
if ( const_cast< BoundingBox * >( geometry->GetBoundingBox())
->GetDiagonalLength2() < eps )
{
itkWarningMacro( "setting an empty bounding-box" );
geometry = NULL;
}
}
if ( m_InputWorldGeometry != geometry )
{
m_InputWorldGeometry = geometry;
this->Modified();
}
}
RenderingManager *
SliceNavigationController::GetRenderingManager() const
{
mitk::RenderingManager* renderingManager = m_RenderingManager.GetPointer();
if (renderingManager != NULL)
return renderingManager;
if ( m_Renderer != NULL )
{
renderingManager = m_Renderer->GetRenderingManager();
if (renderingManager != NULL)
return renderingManager;
}
return mitk::RenderingManager::GetInstance();
}
void SliceNavigationController::SetViewDirectionToDefault()
{
m_ViewDirection = m_DefaultViewDirection;
}
void SliceNavigationController::Update()
{
if ( !m_BlockUpdate )
{
if ( m_ViewDirection == Transversal )
{
this->Update( Transversal, false, false, true );
}
else
{
this->Update( m_ViewDirection );
}
}
}
void
SliceNavigationController::Update(
SliceNavigationController::ViewDirection viewDirection,
bool top, bool frontside, bool rotated )
{
const TimeSlicedGeometry* worldTimeSlicedGeometry =
dynamic_cast< const TimeSlicedGeometry * >(
m_InputWorldGeometry.GetPointer() );
if( m_BlockUpdate ||
m_InputWorldGeometry.IsNull() ||
( (worldTimeSlicedGeometry != NULL) && (worldTimeSlicedGeometry->GetTimeSteps() == 0) )
)
{
return;
}
m_BlockUpdate = true;
if ( m_LastUpdateTime < m_InputWorldGeometry->GetMTime() )
{
Modified();
}
this->SetViewDirection( viewDirection );
this->SetTop( top );
this->SetFrontSide( frontside );
this->SetRotated( rotated );
if ( m_LastUpdateTime < GetMTime() )
{
m_LastUpdateTime = GetMTime();
// initialize the viewplane
SlicedGeometry3D::Pointer slicedWorldGeometry = NULL;
m_CreatedWorldGeometry = NULL;
switch ( viewDirection )
{
case Original:
if ( worldTimeSlicedGeometry != NULL )
{
m_CreatedWorldGeometry = static_cast< TimeSlicedGeometry * >(
m_InputWorldGeometry->Clone().GetPointer() );
worldTimeSlicedGeometry = m_CreatedWorldGeometry.GetPointer();
slicedWorldGeometry = dynamic_cast< SlicedGeometry3D * >(
m_CreatedWorldGeometry->GetGeometry3D( this->GetTime()->GetPos() ) );
if ( slicedWorldGeometry.IsNotNull() )
{
break;
}
}
else
{
const SlicedGeometry3D *worldSlicedGeometry =
dynamic_cast< const SlicedGeometry3D * >(
m_InputWorldGeometry.GetPointer());
if ( worldSlicedGeometry != NULL )
{
slicedWorldGeometry = static_cast< SlicedGeometry3D * >(
m_InputWorldGeometry->Clone().GetPointer());
break;
}
}
//else: use Transversal: no "break" here!!
case Transversal:
slicedWorldGeometry = SlicedGeometry3D::New();
slicedWorldGeometry->InitializePlanes(
m_InputWorldGeometry, PlaneGeometry::Transversal,
top, frontside, rotated );
slicedWorldGeometry->SetSliceNavigationController( this );
break;
case Frontal:
slicedWorldGeometry = SlicedGeometry3D::New();
slicedWorldGeometry->InitializePlanes( m_InputWorldGeometry,
PlaneGeometry::Frontal, top, frontside, rotated );
slicedWorldGeometry->SetSliceNavigationController( this );
break;
case Sagittal:
slicedWorldGeometry = SlicedGeometry3D::New();
slicedWorldGeometry->InitializePlanes( m_InputWorldGeometry,
PlaneGeometry::Sagittal, top, frontside, rotated );
slicedWorldGeometry->SetSliceNavigationController( this );
break;
default:
itkExceptionMacro("unknown ViewDirection");
}
m_Slice->SetPos( 0 );
m_Slice->SetSteps( (int)slicedWorldGeometry->GetSlices() );
if ( m_CreatedWorldGeometry.IsNull() )
{
// initialize TimeSlicedGeometry
m_CreatedWorldGeometry = TimeSlicedGeometry::New();
}
if ( worldTimeSlicedGeometry == NULL )
{
m_CreatedWorldGeometry->InitializeEvenlyTimed( slicedWorldGeometry, 1 );
m_Time->SetSteps( 0 );
m_Time->SetPos( 0 );
m_Time->InvalidateRange();
}
else
{
m_BlockUpdate = true;
m_Time->SetSteps( worldTimeSlicedGeometry->GetTimeSteps() );
m_Time->SetPos( 0 );
const TimeBounds &timeBounds = worldTimeSlicedGeometry->GetTimeBounds();
m_Time->SetRange( timeBounds[0], timeBounds[1] );
m_BlockUpdate = false;
assert( worldTimeSlicedGeometry->GetGeometry3D( this->GetTime()->GetPos() ) != NULL );
slicedWorldGeometry->SetTimeBounds(
worldTimeSlicedGeometry->GetGeometry3D( this->GetTime()->GetPos() )->GetTimeBounds() );
//@todo implement for non-evenly-timed geometry!
m_CreatedWorldGeometry->InitializeEvenlyTimed(
slicedWorldGeometry, worldTimeSlicedGeometry->GetTimeSteps() );
}
}
// unblock update; we may do this now, because if m_BlockUpdate was already
// true before this method was entered, then we will never come here.
m_BlockUpdate = false;
// Send the geometry. Do this even if nothing was changed, because maybe
// Update() was only called to re-send the old geometry and time/slice data.
this->SendCreatedWorldGeometry();
this->SendSlice();
this->SendTime();
// Adjust the stepper range of slice stepper according to geometry
this->AdjustSliceStepperRange();
}
void
SliceNavigationController::SendCreatedWorldGeometry()
{
// Send the geometry. Do this even if nothing was changed, because maybe
// Update() was only called to re-send the old geometry.
if ( !m_BlockUpdate )
{
this->InvokeEvent( GeometrySendEvent(m_CreatedWorldGeometry, 0) );
}
}
void
SliceNavigationController::SendCreatedWorldGeometryUpdate()
{
if ( !m_BlockUpdate )
{
this->InvokeEvent(
GeometryUpdateEvent(m_CreatedWorldGeometry, m_Slice->GetPos()) );
}
}
void
SliceNavigationController::SendSlice()
{
if ( !m_BlockUpdate )
{
if ( m_CreatedWorldGeometry.IsNotNull() )
{
this->InvokeEvent(
GeometrySliceEvent(m_CreatedWorldGeometry, m_Slice->GetPos()) );
// send crosshair event
crosshairPositionEvent.Send();
// Request rendering update for all views
this->GetRenderingManager()->RequestUpdateAll();
}
}
}
void
SliceNavigationController::SendTime()
{
if ( !m_BlockUpdate )
{
if ( m_CreatedWorldGeometry.IsNotNull() )
{
this->InvokeEvent(
GeometryTimeEvent(m_CreatedWorldGeometry, m_Time->GetPos()) );
// Request rendering update for all views
this->GetRenderingManager()->RequestUpdateAll();
}
}
}
void
SliceNavigationController::SetGeometry( const itk::EventObject & )
{
}
void
SliceNavigationController
::SetGeometryTime( const itk::EventObject &geometryTimeEvent )
{
const SliceNavigationController::GeometryTimeEvent *timeEvent =
dynamic_cast< const SliceNavigationController::GeometryTimeEvent * >(
&geometryTimeEvent);
assert( timeEvent != NULL );
TimeSlicedGeometry *timeSlicedGeometry = timeEvent->GetTimeSlicedGeometry();
assert( timeSlicedGeometry != NULL );
if ( m_CreatedWorldGeometry.IsNotNull() )
{
int timeStep = (int) timeEvent->GetPos();
ScalarType timeInMS;
timeInMS = timeSlicedGeometry->TimeStepToMS( timeStep );
timeStep = m_CreatedWorldGeometry->MSToTimeStep( timeInMS );
this->GetTime()->SetPos( timeStep );
}
}
void
SliceNavigationController
::SetGeometrySlice(const itk::EventObject & geometrySliceEvent)
{
const SliceNavigationController::GeometrySliceEvent* sliceEvent =
dynamic_cast<const SliceNavigationController::GeometrySliceEvent *>(
&geometrySliceEvent);
assert(sliceEvent!=NULL);
this->GetSlice()->SetPos(sliceEvent->GetPos());
}
void
SliceNavigationController::SelectSliceByPoint( const Point3D &point )
{
//@todo add time to PositionEvent and use here!!
SlicedGeometry3D* slicedWorldGeometry = dynamic_cast< SlicedGeometry3D * >(
m_CreatedWorldGeometry->GetGeometry3D( this->GetTime()->GetPos() ) );
if ( slicedWorldGeometry )
{
int bestSlice = -1;
double bestDistance = itk::NumericTraits<double>::max();
int s, slices;
slices = slicedWorldGeometry->GetSlices();
if ( slicedWorldGeometry->GetEvenlySpaced() )
{
mitk::Geometry2D *plane = slicedWorldGeometry->GetGeometry2D( 0 );
const Vector3D &direction = slicedWorldGeometry->GetDirectionVector();
Point3D projectedPoint;
plane->Project( point, projectedPoint );
// Check whether the point is somewhere within the slice stack volume;
// otherwise, the defualt slice (0) will be selected
if ( direction[0] * (point[0] - projectedPoint[0])
+ direction[1] * (point[1] - projectedPoint[1])
+ direction[2] * (point[2] - projectedPoint[2]) >= 0 )
{
bestSlice = (int)(plane->Distance( point )
/ slicedWorldGeometry->GetSpacing()[2] + 0.5);
}
}
else
{
Point3D projectedPoint;
for ( s = 0; s < slices; ++s )
{
slicedWorldGeometry->GetGeometry2D( s )->Project( point, projectedPoint );
Vector3D distance = projectedPoint - point;
ScalarType currentDistance = distance.GetSquaredNorm();
if ( currentDistance < bestDistance )
{
bestDistance = currentDistance;
bestSlice = s;
}
}
}
if ( bestSlice >= 0 )
{
this->GetSlice()->SetPos( bestSlice );
}
else
{
this->GetSlice()->SetPos( 0 );
}
this->SendCreatedWorldGeometryUpdate();
}
}
void
SliceNavigationController::ReorientSlices( const Point3D &point,
const Vector3D &normal )
{
PlaneOperation op( OpORIENT, point, normal );
m_CreatedWorldGeometry->ExecuteOperation( &op );
this->SendCreatedWorldGeometryUpdate();
}
const mitk::TimeSlicedGeometry *
SliceNavigationController::GetCreatedWorldGeometry()
{
return m_CreatedWorldGeometry;
}
const mitk::Geometry3D *
SliceNavigationController::GetCurrentGeometry3D()
{
if ( m_CreatedWorldGeometry.IsNotNull() )
{
return m_CreatedWorldGeometry->GetGeometry3D( this->GetTime()->GetPos() );
}
else
{
return NULL;
}
}
const mitk::PlaneGeometry *
SliceNavigationController::GetCurrentPlaneGeometry()
{
const mitk::SlicedGeometry3D *slicedGeometry =
dynamic_cast< const mitk::SlicedGeometry3D * >
( this->GetCurrentGeometry3D() );
if ( slicedGeometry )
{
const mitk::PlaneGeometry *planeGeometry =
dynamic_cast< mitk::PlaneGeometry * >
( slicedGeometry->GetGeometry2D(this->GetSlice()->GetPos()) );
return planeGeometry;
}
else
{
return NULL;
}
}
void
SliceNavigationController::SetRenderer( BaseRenderer *renderer )
{
m_Renderer = renderer;
}
BaseRenderer *
SliceNavigationController::GetRenderer() const
{
return m_Renderer;
}
void
SliceNavigationController::AdjustSliceStepperRange()
{
const mitk::SlicedGeometry3D *slicedGeometry =
dynamic_cast< const mitk::SlicedGeometry3D * >
( this->GetCurrentGeometry3D() );
const Vector3D &direction = slicedGeometry->GetDirectionVector();
int c = 0;
int i, k = 0;
for ( i = 0; i < 3; ++i )
{
if ( fabs( (float) direction[i] ) < 0.000000001 ) { ++c; }
else { k = i; }
}
if ( c == 2 )
{
ScalarType min = m_InputWorldGeometry->GetOrigin()[k];
ScalarType max = min + m_InputWorldGeometry->GetExtentInMM( k );
m_Slice->SetRange( min, max );
}
else
{
m_Slice->InvalidateRange();
}
}
void
SliceNavigationController::ExecuteOperation( Operation *operation )
{
// switch on type
// - select best slice for a given point
// - rotate created world geometry according to Operation->SomeInfo()
if ( !operation )
{
return;
}
switch ( operation->GetOperationType() )
{
case OpMOVE: // should be a point operation
{
if ( !m_SliceLocked ) //do not move the cross position
{
// select a slice
PointOperation *po = dynamic_cast< PointOperation * >( operation );
if ( po && po->GetIndex() == -1 )
{
this->SelectSliceByPoint( po->GetPoint() );
}
else if ( po && po->GetIndex() != -1 ) // undo case because index != -1, index holds the old position of this slice
{
this->GetSlice()->SetPos( po->GetIndex() );
}
}
break;
}
case OpRESTOREPLANEPOSITION:
{
m_CreatedWorldGeometry->ExecuteOperation( operation );
this->SendCreatedWorldGeometryUpdate();
break;
}
default:
{
// do nothing
break;
}
}
}
// Relict from the old times, when automous decisions were accepted
// behavior. Remains in here, because some RenderWindows do exist outside
// of StdMultiWidgets.
bool
SliceNavigationController
::ExecuteAction( Action* action, StateEvent const* stateEvent )
{
bool ok = false;
const PositionEvent* posEvent = dynamic_cast< const PositionEvent * >(
stateEvent->GetEvent() );
if ( posEvent != NULL )
{
if ( m_CreatedWorldGeometry.IsNull() )
{
return true;
}
switch (action->GetActionId())
{
case AcMOVE:
{
BaseRenderer *baseRenderer = posEvent->GetSender();
if ( !baseRenderer )
{
baseRenderer = const_cast<BaseRenderer *>(
GlobalInteraction::GetInstance()->GetFocus() );
}
if ( baseRenderer )
if ( baseRenderer->GetMapperID() == 1 )
{
PointOperation* doOp = new mitk::PointOperation(OpMOVE, posEvent->GetWorldPosition());
if (m_UndoEnabled)
{
m_OldPos = this->GetSlice()->GetPos();
// m_OldPos holds the old slice position. For the undo controller this old position will be stored as index in mitk::PointOperation
PointOperation* undoOp = new mitk::PointOperation(OpMOVE, posEvent->GetWorldPosition(), m_OldPos);
OperationEvent *operationEvent = new mitk::OperationEvent(this, doOp, undoOp, "Move slices");
m_UndoController->SetOperationEvent(operationEvent);
}
this->ExecuteOperation( doOp );
// If click was performed in this render window than we have to update the status bar information about position and pixel value.
if(baseRenderer == m_Renderer)
{
{
std::string statusText;
TNodePredicateDataType<mitk::Image>::Pointer isImageData = TNodePredicateDataType<mitk::Image>::New();
mitk::DataStorage::SetOfObjects::ConstPointer nodes = baseRenderer->GetDataStorage()->GetSubset(isImageData).GetPointer();
mitk::Point3D worldposition = posEvent->GetWorldPosition();
int maxlayer = -32768;
mitk::Image::Pointer image3D;
// find image with largest layer, that is the image shown on top in the render window
for (unsigned int x = 0; x < nodes->size(); x++)
{
//Just consider image data that is no helper object. E.g. do not consider nodes created for the slice interpolation
bool isHelper (false);
nodes->at(x)->GetBoolProperty("helper object", isHelper);
if(nodes->at(x)->GetData()->GetGeometry()->IsInside(worldposition) && isHelper == false)
{
int layer = 0;
if(!(nodes->at(x)->GetIntProperty("layer", layer))) continue;
if(layer > maxlayer)
{
if(static_cast<mitk::DataNode::Pointer>(nodes->at(x))->IsVisible(m_Renderer))
{
image3D = dynamic_cast<mitk::Image*>(nodes->at(x)->GetData());
maxlayer = layer;
}
}
}
}
std::stringstream stream;
stream.imbue(std::locale::classic());
// get the position and gray value from the image and build up status bar text
if(image3D.IsNotNull())
{
Index3D p;
image3D->GetGeometry()->WorldToIndex(worldposition, p);
stream.precision(2);
stream<<"Position: <" << std::fixed <<worldposition[0] << ", " << std::fixed << worldposition[1] << ", " << std::fixed << worldposition[2] << "> mm";
stream<<"; Index: <"<<p[0] << ", " << p[1] << ", " << p[2] << "> ";
mitk::ScalarType pixelValue = image3D->GetPixelValueByIndex(p, baseRenderer->GetTimeStep());
if (fabs(pixelValue)>1000000)
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<<std::scientific<<image3D->GetPixelValueByIndex(p, baseRenderer->GetTimeStep())<<" ";
}
else
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<<image3D->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 7bd345605a..1f70623b30 100644
--- a/Core/Code/Controllers/mitkSliceNavigationController.h
+++ b/Core/Code/Controllers/mitkSliceNavigationController.h
@@ -1,511 +1,510 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 <MitkExports.h>
#include "mitkBaseController.h"
#include "mitkRenderingManager.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkMessage.h"
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
#include <itkCommand.h>
#include <sstream>
#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<const Self*>(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);
*
* // 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};
/**
* \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<const Self*>(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 <typename T>
void ConnectGeometrySendEvent(T* receiver)
{
typedef typename itk::ReceptorMemberCommand<T>::Pointer
ReceptorMemberCommandPointer;
ReceptorMemberCommandPointer eventReceptorCommand =
itk::ReceptorMemberCommand<T>::New();
eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometry);
AddObserver(GeometrySendEvent(NULL,0), eventReceptorCommand);
}
template <typename T>
void ConnectGeometryUpdateEvent(T* receiver)
{
typedef typename itk::ReceptorMemberCommand<T>::Pointer
ReceptorMemberCommandPointer;
ReceptorMemberCommandPointer eventReceptorCommand =
itk::ReceptorMemberCommand<T>::New();
eventReceptorCommand->SetCallbackFunction(receiver, &T::UpdateGeometry);
AddObserver(GeometryUpdateEvent(NULL,0), eventReceptorCommand);
}
template <typename T>
void ConnectGeometrySliceEvent(T* receiver, bool connectSendEvent=true)
{
typedef typename itk::ReceptorMemberCommand<T>::Pointer
ReceptorMemberCommandPointer;
ReceptorMemberCommandPointer eventReceptorCommand =
itk::ReceptorMemberCommand<T>::New();
eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometrySlice);
AddObserver(GeometrySliceEvent(NULL,0), eventReceptorCommand);
if(connectSendEvent)
ConnectGeometrySendEvent(receiver);
}
template <typename T>
void ConnectGeometryTimeEvent(T* receiver, bool connectSendEvent=true)
{
typedef typename itk::ReceptorMemberCommand<T>::Pointer
ReceptorMemberCommandPointer;
ReceptorMemberCommandPointer eventReceptorCommand =
itk::ReceptorMemberCommand<T>::New();
eventReceptorCommand->SetCallbackFunction(receiver, &T::SetGeometryTime);
AddObserver(GeometryTimeEvent(NULL,0), eventReceptorCommand);
if(connectSendEvent)
ConnectGeometrySendEvent(receiver);
}
template <typename T>
void ConnectGeometryEvents(T* receiver)
{
//connect sendEvent only once
ConnectGeometrySliceEvent(receiver, false);
ConnectGeometryTimeEvent(receiver);
}
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 <class T>
static void buildstring( mitkIpPicDescriptor *pic, itk::Point<int, 3> p, std::string &s, T = 0)
{
std::string value;
std::stringstream stream;
stream.imbue(std::locale::classic());
stream<<s<<"; Pixelvalue: ";
if ( (p[0]>=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;
};
} // namespace mitk
#endif /* SLICENAVIGATIONCONTROLLER_H_HEADER_INCLUDED_C1C55A2F */
diff --git a/Core/Code/Controllers/mitkSlicesCoordinator.cpp b/Core/Code/Controllers/mitkSlicesCoordinator.cpp
index c6d21ac31d..056075ee53 100644
--- a/Core/Code/Controllers/mitkSlicesCoordinator.cpp
+++ b/Core/Code/Controllers/mitkSlicesCoordinator.cpp
@@ -1,103 +1,102 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkSlicesCoordinator.h>
#include <mitkApplicationCursor.h>
namespace mitk {
SlicesCoordinator::SlicesCoordinator(const char* machine)
: StateMachine(machine),
m_LinkPlanes( true ),
m_MouseCursorSet( false )
{
}
SlicesCoordinator::~SlicesCoordinator()
{
}
void SlicesCoordinator::AddSliceController(SliceNavigationController* snc)
{
if (!snc) return;
m_SliceNavigationControllers.push_back(snc);
OnSliceControllerAdded(snc); // notify
}
void SlicesCoordinator::RemoveSliceController(SliceNavigationController* snc)
{
if (!snc) return;
// see, whether snc is in our list
SNCVector::iterator iter;
for (iter = m_SliceNavigationControllers.begin(); iter != m_SliceNavigationControllers.end(); ++iter)
if (*iter == snc) break;
// if found, remove from list
if ( iter != m_SliceNavigationControllers.end() )
{
m_SliceNavigationControllers.erase( iter );
OnSliceControllerRemoved(snc);
}
}
void SlicesCoordinator::ResetMouseCursor()
{
if ( m_MouseCursorSet )
{
ApplicationCursor::GetInstance()->PopCursor();
m_MouseCursorSet = false;
}
}
void SlicesCoordinator::SetMouseCursor( const char *xpm[], int hotspotX, int hotspotY )
{
// Remove previously set mouse cursor
if ( m_MouseCursorSet )
{
ApplicationCursor::GetInstance()->PopCursor();
}
ApplicationCursor::GetInstance()->PushCursor( xpm, hotspotX, hotspotY );
m_MouseCursorSet = true;
}
void SlicesCoordinator::OnSliceControllerAdded(SliceNavigationController*)
{
// implement in subclasses
}
void SlicesCoordinator::OnSliceControllerRemoved(SliceNavigationController*)
{
// implement in subclasses
}
bool SlicesCoordinator::ExecuteAction(Action*, StateEvent const*)
{
// implement in subclasses
return false;
}
} // namespace
diff --git a/Core/Code/Controllers/mitkSlicesCoordinator.h b/Core/Code/Controllers/mitkSlicesCoordinator.h
index 08a0fc4440..49d8836ae3 100644
--- a/Core/Code/Controllers/mitkSlicesCoordinator.h
+++ b/Core/Code/Controllers/mitkSlicesCoordinator.h
@@ -1,119 +1,118 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 SLICESCOORDINATOR_H_HEADER_INCLUDED_C1C55A2F
#define SLICESCOORDINATOR_H_HEADER_INCLUDED_C1C55A2F
#include <mitkStateMachine.h>
#include <vector>
namespace mitk {
class SliceNavigationController;
class Action;
class StateEvent;
#pragma GCC visibility push(default)
itkEventMacro( SliceRotationEvent, itk::AnyEvent);
#pragma GCC visibility pop
/**
* \brief Coordinates a list of SliceNavigationControllers.
*
* Each SliceNavigationController can select one slice from a
* TimeSlicedGeometry. This class (SlicesCoordinator) coordinates several
* SliceNavigationControllers to facilitate e.g. rotation of slices. A new
* class is needed, because for rotation one has to know an axis of rotation.
* Such an axis is most easily determined from the "other slices", which are
* not known by a SliceNavigationController.
* This class registers itself as a listener to GlobalInteraction and holds a
* list of SliceNavigationControllers. Any functionality, such as slice
* rotation, is done in subclasses. This separation is done for the case that
* some other multi-slice coordination should be implemented.
*/
class MITK_CORE_EXPORT SlicesCoordinator : public StateMachine
{
public:
typedef std::vector<SliceNavigationController*> SNCVector;
mitkClassMacro(SlicesCoordinator, StateMachine);
mitkNewMacro1Param(Self, const char*);
/** Add to list of managed slices. Check if CreatedWorldGeometry of SNC is
* managable (i.e. there is basically only one planegeometry) */
void AddSliceController(SliceNavigationController* snc);
/** Remove one controller, which is then added as listener to
* GlobalInteraction */
void RemoveSliceController(SliceNavigationController* snc);
/* Reset all Slices to central slice, no rotation */
// void ResetAllSlices();
/** Set/Get whether planes should stay linked to each other (by fixing
* their relative angle) */
itkSetMacro( LinkPlanes, bool );
itkGetMacro( LinkPlanes, bool );
itkBooleanMacro( LinkPlanes );
/** \brief Resets the mouse cursor (if modified by the SlicesCoordinator)
* to its original state.
*
* Should be used by subclasses and from external application instead
* of using QmitkApplicationCursor directly to avoid conflicts. */
void ResetMouseCursor();
protected:
/** \brief Default Constructor */
SlicesCoordinator(const char* machine);
/** clear list of controllers */
virtual ~SlicesCoordinator();
/** \brief Sets the specified mouse cursor.
*
* Use this in subclasses instead of using QmitkApplicationCursor directly.
*/
void SetMouseCursor( const char *xpm[], int hotspotX, int hotspotY );
/** for implementation in subclasses */
virtual void OnSliceControllerAdded(SliceNavigationController* snc);
/** for implementation in subclasses */
virtual void OnSliceControllerRemoved(SliceNavigationController* snc);
/** for implementation in subclasses */
virtual bool ExecuteAction(Action * action, StateEvent const* stateEvent);
SNCVector m_SliceNavigationControllers;
bool m_LinkPlanes;
bool m_MouseCursorSet;
};
} // namespace
#endif
diff --git a/Core/Code/Controllers/mitkSlicesRotator.cpp b/Core/Code/Controllers/mitkSlicesRotator.cpp
index 34221fbf43..c2a7336399 100644
--- a/Core/Code/Controllers/mitkSlicesRotator.cpp
+++ b/Core/Code/Controllers/mitkSlicesRotator.cpp
@@ -1,582 +1,581 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkSlicesRotator.h>
#include <mitkSliceNavigationController.h>
#include <mitkStateEvent.h>
#include <mitkAction.h>
#include <mitkInteractionConst.h>
#include <mitkDisplayPositionEvent.h>
#include <mitkRotationOperation.h>
#include <mitkBaseRenderer.h>
#include <mitkRenderingManager.h>
#include <mitkLine.h>
#include <mitkGeometry3D.h>
#include <mitkGeometry2D.h>
#include <mitkPlaneGeometry.h>
#include <mitkDisplayGeometry.h>
#include <mitkSlicedGeometry3D.h>
#include <mitkTimeSlicedGeometry.h>
#include <vtkLinearTransform.h>
#include <math.h>
#include "rotate_cursor.xpm"
namespace mitk {
SlicesRotator::Pointer SlicesRotator::New()
{
return SlicesRotator::New("slices-rotator");
}
SlicesRotator::SlicesRotator(const char* machine)
: SlicesCoordinator(machine)
{
}
SlicesRotator::~SlicesRotator()
{
}
// check if the slices of this SliceNavigationController can be rotated (???) Possible
void SlicesRotator::OnSliceControllerAdded(SliceNavigationController* snc)
{
if (!snc) return;
snc->ConnectGeometrySendEvent(this); // connects creation of new world geometry to Self::SetGeometry
}
void SlicesRotator::OnSliceControllerRemoved(SliceNavigationController* snc)
{
if (!snc) return;
// nothing to do
}
/// Is called whenever a SliceNavigationController invokes an event. Will update the list
/// of SliceNavigationControllers that can handle rotation
void SlicesRotator::SetGeometry(const itk::EventObject& /*EventObject*/)
{
// there is no way to determine the sender?
// ==> update whole list of SNCs
UpdateRelevantSNCs();
}
void SlicesRotator::RotateToPoint( SliceNavigationController *rotationPlaneSNC,
SliceNavigationController *rotatedPlaneSNC,
const Point3D &point, bool linked )
{
SliceNavigationController *thirdSNC = NULL;
SNCVector::iterator iter;
for ( iter = m_RelevantSNCs.begin(); iter != m_RelevantSNCs.end(); ++iter )
{
if ( ((*iter) != rotationPlaneSNC)
&& ((*iter) != rotatedPlaneSNC) )
{
thirdSNC = *iter;
break;
}
}
if ( thirdSNC == NULL )
{
return;
}
const PlaneGeometry *rotationPlane = rotationPlaneSNC->GetCurrentPlaneGeometry();
const PlaneGeometry *rotatedPlane = rotatedPlaneSNC->GetCurrentPlaneGeometry();
const PlaneGeometry *thirdPlane = thirdSNC->GetCurrentPlaneGeometry();
if ( (rotationPlane == NULL) || (rotatedPlane == NULL)
|| (thirdPlane == NULL) )
{
return;
}
if ( rotatedPlane->DistanceFromPlane( point ) < 0.001 )
{
// Skip irrelevant rotations
return;
}
Point3D projectedPoint;
Line3D intersection;
Point3D rotationCenter;
if ( !rotationPlane->Project( point, projectedPoint )
|| !rotationPlane->IntersectionLine( rotatedPlane, intersection )
|| !thirdPlane->IntersectionPoint( intersection, rotationCenter ) )
{
return;
}
// All pre-requirements are met; execute the rotation
Point3D referencePoint = intersection.Project( projectedPoint );
Vector3D toProjected = referencePoint - rotationCenter;
Vector3D toCursor = projectedPoint - rotationCenter;
// cross product: | A x B | = |A| * |B| * sin(angle)
Vector3D axisOfRotation;
vnl_vector_fixed< ScalarType, 3 > vnlDirection =
vnl_cross_3d( toCursor.GetVnlVector(), toProjected.GetVnlVector() );
axisOfRotation.SetVnlVector( vnlDirection );
// scalar product: A * B = |A| * |B| * cos(angle)
// tan = sin / cos
ScalarType angle = - atan2(
(double)(axisOfRotation.GetNorm()),
(double)(toCursor * toProjected) );
angle *= 180.0 / vnl_math::pi;
// create RotationOperation and apply to all SNCs that should be rotated
RotationOperation op(OpROTATE, rotationCenter, axisOfRotation, angle);
if ( !linked )
{
BaseRenderer *renderer = rotatedPlaneSNC->GetRenderer();
if ( renderer == NULL )
{
return;
}
DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
Point2D point2DWorld, point2DDisplayPre, point2DDisplayPost;
displayGeometry->Map( rotationCenter, point2DWorld );
displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPre );
const Geometry3D *geometry3D = rotatedPlaneSNC->GetCreatedWorldGeometry();
const TimeSlicedGeometry *timeSlicedGeometry =
dynamic_cast<const TimeSlicedGeometry*>( geometry3D );
if ( !timeSlicedGeometry )
{
return;
}
const_cast< TimeSlicedGeometry * >( timeSlicedGeometry )->ExecuteOperation( &op );
displayGeometry->Map( rotationCenter, point2DWorld );
displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPost );
Vector2D vector2DDisplayDiff = point2DDisplayPost - point2DDisplayPre;
//Vector2D origin = displayGeometry->GetOriginInMM();
displayGeometry->MoveBy( vector2DDisplayDiff );
rotatedPlaneSNC->SendCreatedWorldGeometryUpdate();
}
else
{
SNCVector::iterator iter;
for ( iter = m_RelevantSNCs.begin(); iter != m_RelevantSNCs.end(); ++iter )
{
BaseRenderer *renderer = (*iter)->GetRenderer();
if ( renderer == NULL )
{
continue;
}
DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
Point2D point2DWorld, point2DDisplayPre, point2DDisplayPost;
displayGeometry->Map( rotationCenter, point2DWorld );
displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPre );
const Geometry3D* geometry3D = (*iter)->GetCreatedWorldGeometry();
const TimeSlicedGeometry *timeSlicedGeometry =
dynamic_cast<const TimeSlicedGeometry*>( geometry3D );
if ( !timeSlicedGeometry )
{
continue;
}
const_cast< TimeSlicedGeometry * >( timeSlicedGeometry )->ExecuteOperation( &op );
displayGeometry->Map( rotationCenter, point2DWorld );
displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPost );
Vector2D vector2DDisplayDiff = point2DDisplayPost - point2DDisplayPre;
//Vector2D origin = displayGeometry->GetOriginInMM();
displayGeometry->MoveBy( vector2DDisplayDiff );
(*iter)->SendCreatedWorldGeometryUpdate();
}
}
}
/// Updates the list of SliceNavigationControllers that can handle rotation
void SlicesRotator::UpdateRelevantSNCs()
{
m_RelevantSNCs.clear();
for (SNCVector::iterator iter = m_SliceNavigationControllers.begin(); iter != m_SliceNavigationControllers.end(); ++iter)
{
const Geometry3D* geometry3D = (*iter)->GetCreatedWorldGeometry();
const TimeSlicedGeometry* timeSlicedGeometry = dynamic_cast<const TimeSlicedGeometry*>( geometry3D );
if (!timeSlicedGeometry) continue;
const SlicedGeometry3D* slicedGeometry = dynamic_cast<const SlicedGeometry3D*>( timeSlicedGeometry->GetGeometry3D(0) );
if (!slicedGeometry) continue;
Geometry2D* firstSlice(NULL);
//Geometry2D* secondSlice(NULL);
if (slicedGeometry->IsValidSlice(0)) firstSlice = slicedGeometry->GetGeometry2D(0);
//if (slicedGeometry->IsValidSlice(1)) secondSlice = slicedGeometry->GetGeometry2D(1);
// if the direction vector of these two slices is the same, then accept this slice stack as rotatable
Vector3D right1 = firstSlice->GetAxisVector(0);
Vector3D up1 = firstSlice->GetAxisVector(1);
vnl_vector_fixed< ScalarType, 3 > vnlDirection1 = vnl_cross_3d(right1.GetVnlVector(), up1.GetVnlVector());
Vector3D direction1;
direction1.SetVnlVector(vnlDirection1);
Vector3D right2 = firstSlice->GetAxisVector(0);
Vector3D up2 = firstSlice->GetAxisVector(1);
vnl_vector_fixed< ScalarType, 3 > vnlDirection2 = vnl_cross_3d(right2.GetVnlVector(), up2.GetVnlVector());
Vector3D direction2;
direction2.SetVnlVector(vnlDirection2);
bool equal = true;
const ScalarType eps = 0.0001;
for (int i = 0; i < 3; ++i)
if ( fabs(direction1[i] - direction2[i]) > eps )
equal = false;
if (equal) // equal direction vectors
{
m_RelevantSNCs.push_back( *iter );
}
}
}
bool SlicesRotator::ExecuteAction(Action* action, StateEvent const* stateEvent)
{
const ScalarType ThreshHoldDistancePixels = 12.0;
bool ok = false;
switch ( action->GetActionId() )
{
case AcMOVE:
{
// just reach through
for (SNCVector::iterator iter = m_RelevantSNCs.begin(); iter != m_RelevantSNCs.end(); ++iter)
{
if ( !(*iter)->GetSliceLocked() )
{
(*iter)->ExecuteAction(action, stateEvent);
}
}
ok = true;
break;
}
case AcROTATE:
{
const DisplayPositionEvent* posEvent = dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
if (!posEvent) break;
Point3D cursor = posEvent->GetWorldPosition();
Vector3D toProjected = m_LastCursorPosition - m_CenterOfRotation;
Vector3D toCursor = cursor - m_CenterOfRotation;
// cross product: | A x B | = |A| * |B| * sin(angle)
Vector3D axisOfRotation;
vnl_vector_fixed< ScalarType, 3 > vnlDirection = vnl_cross_3d( toCursor.GetVnlVector(), toProjected.GetVnlVector() );
axisOfRotation.SetVnlVector(vnlDirection);
// scalar product: A * B = |A| * |B| * cos(angle)
// tan = sin / cos
ScalarType angle = - atan2( (double)(axisOfRotation.GetNorm()), (double)(toCursor * toProjected) );
angle *= 180.0 / vnl_math::pi;
m_LastCursorPosition = cursor;
// create RotationOperation and apply to all SNCs that should be rotated
RotationOperation op(OpROTATE, m_CenterOfRotation, axisOfRotation, angle);
// TEST
int i = 0;
for (SNCVector::iterator iter = m_SNCsToBeRotated.begin(); iter != m_SNCsToBeRotated.end(); ++iter)
{
BaseRenderer *renderer = (*iter)->GetRenderer();
if ( renderer == NULL )
{
continue;
}
DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
// MITK_INFO << i << ":" << std::endl;
Point2D point2DWorld, point2DDisplayPre, point2DDisplayPost;
displayGeometry->Map( m_CenterOfRotation, point2DWorld );
displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPre );
// MITK_INFO << " WorldPre: " << point2DWorld << " / DisplayPre: " << point2DDisplayPre << std::endl;
const Geometry3D* geometry3D = (*iter)->GetCreatedWorldGeometry();
const TimeSlicedGeometry* timeSlicedGeometry = dynamic_cast<const TimeSlicedGeometry*>(geometry3D);
if (!timeSlicedGeometry) continue;
const_cast<TimeSlicedGeometry*>(timeSlicedGeometry)->ExecuteOperation(&op);
//vtkLinearTransform *inverseTransformVtk =
// displayGeometry->GetVtkTransform()->GetLinearInverse();
//ScalarType pvtkCenterOfRotation[3];
//pvtkCenterOfRotation[0] = m_CenterOfRotation[0];
//pvtkCenterOfRotation[1] = m_CenterOfRotation[1];
//pvtkCenterOfRotation[2] = m_CenterOfRotation[2];
//ScalarType scaleFactorMMPerUnitX =
// displayGeometry->GetExtentInMM(0) / displayGeometry->GetExtent(0);
//ScalarType scaleFactorMMPerUnitY =
// displayGeometry->GetExtentInMM(1) / displayGeometry->GetExtent(1);
//ScalarType scaleFactorMMPerDisplayUnit = displayGeometry->GetScaleFactorMMPerDisplayUnit();
//Vector2D &originInMM = displayGeometry->GetOriginInMM();
////displayGeometry->Map( m_CenterOfRotation, point2DWorld );
//ScalarType pvtkDisplayPost[3];
//inverseTransformVtk->TransformPoint( pvtkCenterOfRotation, pvtkDisplayPost );
//pvtkDisplayPost[0] *= scaleFactorMMPerUnitX;
//pvtkDisplayPost[1] *= scaleFactorMMPerUnitY;
////displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPost );
//pvtkDisplayPost[0] -= originInMM[0];
//pvtkDisplayPost[1] -= originInMM[1];
//pvtkDisplayPost[0] /= scaleFactorMMPerDisplayUnit;
//pvtkDisplayPost[1] /= scaleFactorMMPerDisplayUnit;
//point2DDisplayPost[0] = pvtkDisplayPost[0];
//point2DDisplayPost[1] = pvtkDisplayPost[1];
displayGeometry->Map( m_CenterOfRotation, point2DWorld );
displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPost );
Vector2D vector2DDisplayDiff = point2DDisplayPost - point2DDisplayPre;
//Vector2D origin = displayGeometry->GetOriginInMM();
// MITK_INFO << " WorldPost: " << point2DWorld << " / DisplayPost: " << point2DDisplayPost << std::endl;
// MITK_INFO << " Diff - " << vector2DDisplayDiff << std::endl;
// MITK_INFO << " Origin - " << origin << std::endl;
++i;
displayGeometry->MoveBy( vector2DDisplayDiff );
(*iter)->SendCreatedWorldGeometryUpdate();
}
// MITK_INFO << "--------------------------------" << std::endl;
// TEST
//BaseRenderer* renderer = stateEvent->GetEvent()->GetSender(); // TODO this is NOT SNC-specific! Should be!
//
//DisplayGeometry* displayGeometry = renderer->GetDisplayGeometry();
//if (!displayGeometry) break;
//Point2D point2DWorld, point2DDisplay;
//displayGeometry->Map( m_CenterOfRotation, point2DWorld );
//displayGeometry->WorldToDisplay( point2DWorld, point2DDisplay );
//MITK_INFO << "RotationCenter: " << m_CenterOfRotation << std::endl;
//MITK_INFO << "PointWorld: " << point2DWorld << std::endl;
//MITK_INFO << "PointDisplay: " << point2DDisplay << std::endl;
//MITK_INFO << "--------------------------------------------" << std::endl;
RenderingManager::GetInstance()->RequestUpdateAll();
this->InvokeEvent( SliceRotationEvent() ); // notify listeners
ok = true;
break;
}
case AcCHECKPOINT:
{
// decide between moving and rotation
// Alle SNCs (Anzahl N) nach dem Abstand von posEvent->GetWorldPosition() zur aktuellen Ebene fragen.
// Anzahl der Ebenen zaehlen, die naeher als ein gewisser Schwellwertwert sind -> nNah.
// Wenn nNah == N
// Generiere ein PointEvent und schicke das an alle SNCs -> bewege den kreuz-mittelpunkt
// Wenn nNah == 2
// Streiche stateEvent->Sender aus der Liste der nahen Ebenen
// fuer die uebrigen generiere eine RotationOperation und fuehre die aus
// sonst
//
const DisplayPositionEvent* posEvent = dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
if (!posEvent) break;
Point3D cursor = posEvent->GetWorldPosition();
//m_LastCursorPosition = cursor;
unsigned int numNearPlanes = 0;
m_SNCsToBeRotated.clear();
Geometry2D* geometryToBeRotated = NULL; // this one is grabbed
Geometry2D* otherGeometry = NULL; // this is also visible (for calculation of intersection)
Geometry2D* clickedGeometry = NULL; // the event originates from this one
//SlicedGeometry3D* clickedSlicedGeometry;
for (SNCVector::iterator iter = m_RelevantSNCs.begin(); iter != m_RelevantSNCs.end(); ++iter)
{
unsigned int slice = (*iter)->GetSlice()->GetPos();
unsigned int time = (*iter)->GetTime()->GetPos();
const Geometry3D* geometry3D = (*iter)->GetCreatedWorldGeometry();
const TimeSlicedGeometry* timeSlicedGeometry = dynamic_cast<const TimeSlicedGeometry*>( geometry3D );
if (!timeSlicedGeometry) continue;
const SlicedGeometry3D* slicedGeometry = dynamic_cast<const SlicedGeometry3D*>( timeSlicedGeometry->GetGeometry3D(time) );
if (!slicedGeometry) continue;
Geometry2D* geometry2D = slicedGeometry->GetGeometry2D(slice);
if (!geometry2D) continue; // this is not necessary?
ScalarType distanceMM = geometry2D->Distance( cursor );
BaseRenderer* renderer = stateEvent->GetEvent()->GetSender(); // TODO this is NOT SNC-specific! Should be!
DisplayGeometry* displayGeometry = renderer->GetDisplayGeometry();
if (!displayGeometry) continue;
ScalarType distancePixels = distanceMM / displayGeometry->GetScaleFactorMMPerDisplayUnit();
if ( distancePixels <= ThreshHoldDistancePixels )
{
++numNearPlanes; // count this one as a plane near to the cursor
}
if ( *iter == renderer->GetSliceNavigationController() ) // don't rotate the one where the user clicked
{
clickedGeometry = geometry2D;
//clickedSlicedGeometry = const_cast<SlicedGeometry3D*>(slicedGeometry);
}
else
{
// @TODO here waits some bug to be found - maybe fixed by the || m_LinkPlanes in next line
if ( (distancePixels <= ThreshHoldDistancePixels)
&& !(*iter)->GetSliceRotationLocked()
&& (m_SNCsToBeRotated.empty() || m_LinkPlanes) )
{
// this one is behind the clicked "line"
m_SNCsToBeRotated.push_back(*iter);
geometryToBeRotated = geometry2D;
}
else
{
otherGeometry = geometry2D;
if ( m_LinkPlanes )
{
// All slices are rotated, i.e. the relative angles between
// slices remain fixed
m_SNCsToBeRotated.push_back(*iter);
}
}
}
}
bool move (true);
if ( geometryToBeRotated && otherGeometry && clickedGeometry
&& ( numNearPlanes == 2 ) )
{
// assure all three are valid, so calculation of center of rotation can be done
move = false;
}
StateEvent *newStateEvent(NULL);
// question in state machine is: "rotate?"
if (move)
{
// move all planes to posEvent->GetWorldPosition()
newStateEvent = new StateEvent(EIDNO, stateEvent->GetEvent());
}
else
{
// determine center of rotation TODO requires two plane geometries...
PlaneGeometry* planeGeometry = dynamic_cast<PlaneGeometry*>(clickedGeometry);
PlaneGeometry* planeGeometry1 = dynamic_cast<PlaneGeometry*>(geometryToBeRotated);
PlaneGeometry* planeGeometry2 = dynamic_cast<PlaneGeometry*>(otherGeometry);
if (!planeGeometry || !planeGeometry1 || !planeGeometry2) break;
Line3D intersection;
if (!planeGeometry->IntersectionLine( planeGeometry1, intersection )) break;
m_LastCursorPosition = intersection.Project(cursor);
if (!planeGeometry2->IntersectionPoint(intersection, m_CenterOfRotation)) break;
// everything's fine
newStateEvent = new StateEvent(EIDYES, stateEvent->GetEvent());
}
if (!newStateEvent) MITK_ERROR << "rotation would be nice but is impossible... " << std::endl;
this->HandleEvent( newStateEvent );
delete newStateEvent;
ok = true;
break;
}
case AcROTATESTART:
{
this->SetMouseCursor( rotate_cursor_xpm, 0, 0 );
this->InvokeEvent( SliceRotationEvent() ); // notify listeners
break;
}
case AcROTATEEND:
{
this->ResetMouseCursor();
this->InvokeEvent( SliceRotationEvent() ); // notify listeners
break;
}
default:
{
break;
}
}
return ok;
}
} // namespace
diff --git a/Core/Code/Controllers/mitkSlicesRotator.h b/Core/Code/Controllers/mitkSlicesRotator.h
index a707ebdf8b..cf02880eba 100644
--- a/Core/Code/Controllers/mitkSlicesRotator.h
+++ b/Core/Code/Controllers/mitkSlicesRotator.h
@@ -1,111 +1,110 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 SLICESROTATOR_H_HEADER_INCLUDED_C1C55A2F
#define SLICESROTATOR_H_HEADER_INCLUDED_C1C55A2F
#include <mitkSlicesCoordinator.h>
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
#include <mitkVector.h>
namespace mitk {
/**
* \brief Enables rotation of visible slices (for sliced geometries).
* \ingroup NavigationControl
*
* This class takes care of several SliceNavigationControllers and handles
* slice selection / slice rotation. It is added as listener to
* GlobalInteraction by QmitkStdMultiWidget.
*
* The SlicesRotator class adds the possibility of slice rotation to the
* "normal" behaviour of SliceNavigationControllers. This additional class
* is needed, because one has to be aware of several "visible slices"
* (selected Geometry2Ds of some SliceNavigationControllers) in order to
* choose between rotation and slice selection.
*
* Rotation is achieved by modifying (rotating) the generated
* TimeSlicedGeometry of the corresponding SliceNavigationController.
*
* With SlicesRotator, the rule to choose between slice rotation and
* selection is simple: For a mouse down event, count the number of visible
* planes, which are "near" the cursor. If this number equals 2 (one for the
* window, which currently holds the cursor, one for the intersection line of
* another visible slice), then initiate rotation, else select slices near
* the cursor. If "LinkPlanes" is set to true, the rotation is applied to the
* planes of all registered SNCs, not only of the one associated with the
* directly selected plane.
*
* In contrast to the situation without the SlicesRotator, the
* SliceNavigationControllers are now not directly registered as listeners to
* GlobalInteraction. SlicesRotator is registered as a listener and decides
* whether something should be rotated or whether another slice should be
* selected. In the latter case, a PositionEvent is just forwarded to the
* SliceNavigationController.
*
* \sa SlicesSwiveller
*/
class MITK_CORE_EXPORT SlicesRotator : public SlicesCoordinator
{
public:
mitkClassMacro(SlicesRotator, SlicesCoordinator);
static Pointer New();
/**
* @brief New Macro with one parameter for creating this object with static New(..) method
**/
mitkNewMacro1Param(Self, const char*);
virtual void SetGeometry(const itk::EventObject& EventObject);
virtual void RotateToPoint( SliceNavigationController *rotationPlaneSNC,
SliceNavigationController *rotatedPlaneSNC,
const Point3D &point, bool linked = false );
protected:
SlicesRotator(const char* machine);
// clear list of controllers
virtual ~SlicesRotator();
// check if the slices of this SliceNavigationController can be rotated (???) Possible
virtual void OnSliceControllerAdded(SliceNavigationController* snc);
virtual void OnSliceControllerRemoved(SliceNavigationController* snc);
virtual void UpdateRelevantSNCs();
virtual bool ExecuteAction(Action * action, StateEvent const* stateEvent);
SNCVector m_RelevantSNCs; /// all SNCs that currently have CreatedWorldGeometries, that can be rotated.
SNCVector m_SNCsToBeRotated; /// all SNCs that will be rotated
Point3D m_LastCursorPosition;
Point3D m_CenterOfRotation;
};
} // namespace
#endif
diff --git a/Core/Code/Controllers/mitkSlicesSwiveller.cpp b/Core/Code/Controllers/mitkSlicesSwiveller.cpp
index c3e7d82b74..d30873d6f0 100644
--- a/Core/Code/Controllers/mitkSlicesSwiveller.cpp
+++ b/Core/Code/Controllers/mitkSlicesSwiveller.cpp
@@ -1,407 +1,406 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 9252 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSlicesSwiveller.h"
#include "mitkSliceNavigationController.h"
#include "mitkStateEvent.h"
#include "mitkAction.h"
#include "mitkInteractionConst.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkRotationOperation.h"
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
#include "mitkLine.h"
#include "mitkGeometry3D.h"
#include "mitkGeometry2D.h"
#include "mitkPlaneGeometry.h"
#include "mitkDisplayGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include "mitkTimeSlicedGeometry.h"
#include <math.h>
namespace mitk {
SlicesSwiveller::Pointer SlicesSwiveller::New()
{
return SlicesSwiveller::New("slices-rotator");
}
SlicesSwiveller::SlicesSwiveller(const char* machine)
: SlicesCoordinator(machine),
m_PreviousRotationAngle( 0.0 )
{
}
SlicesSwiveller::~SlicesSwiveller()
{
}
// check if the slices of this SliceNavigationController can be rotated (???) Possible
void SlicesSwiveller::OnSliceControllerAdded(SliceNavigationController* snc)
{
if (!snc) return;
// connects creation of new world geometry to Self::SetGeometry
snc->ConnectGeometrySendEvent(this);
}
void SlicesSwiveller::OnSliceControllerRemoved(SliceNavigationController* snc)
{
if (!snc) return;
// nothing to do
}
/// Is called whenever a SliceNavigationController invokes an event. Will
// update the list of SliceNavigationControllers that can handle rotation
void SlicesSwiveller::SetGeometry(const itk::EventObject& /*EventObject*/)
{
// there is no way to determine the sender?
// ==> update whole list of SNCs
UpdateRelevantSNCs();
}
/// Updates the list of SliceNavigationControllers that can handle rotation
void SlicesSwiveller::UpdateRelevantSNCs()
{
m_RelevantSNCs.clear();
SNCVector::iterator iter;
for ( iter = m_SliceNavigationControllers.begin();
iter != m_SliceNavigationControllers.end();
++iter)
{
const Geometry3D* geometry3D = (*iter)->GetCreatedWorldGeometry();
const TimeSlicedGeometry* timeSlicedGeometry =
dynamic_cast<const TimeSlicedGeometry*>( geometry3D );
if (!timeSlicedGeometry) continue;
const SlicedGeometry3D* slicedGeometry =
dynamic_cast<const SlicedGeometry3D*>(
timeSlicedGeometry->GetGeometry3D(0) );
if (!slicedGeometry) continue;
Geometry2D *firstSlice( NULL );
//Geometry2D *secondSlice( NULL );
if (slicedGeometry->IsValidSlice(0))
{
firstSlice = slicedGeometry->GetGeometry2D(0);
}
// if (slicedGeometry->IsValidSlice(1))
// {
// secondSlice = slicedGeometry->GetGeometry2D(1);
// }
// If the direction vector of these two slices is the same, then accept
// this slice stack as rotatable
Vector3D right1 = firstSlice->GetAxisVector(0);
Vector3D up1 = firstSlice->GetAxisVector(1);
vnl_vector_fixed< ScalarType, 3 > vnlDirection1 =
vnl_cross_3d(right1.GetVnlVector(), up1.GetVnlVector());
Vector3D direction1;
direction1.SetVnlVector(vnlDirection1);
Vector3D right2 = firstSlice->GetAxisVector(0);
Vector3D up2 = firstSlice->GetAxisVector(1);
vnl_vector_fixed< ScalarType, 3 > vnlDirection2 =
vnl_cross_3d(right2.GetVnlVector(), up2.GetVnlVector());
Vector3D direction2;
direction2.SetVnlVector(vnlDirection2);
bool equal = true;
const ScalarType eps = 0.0001;
for (int i = 0; i < 3; ++i)
{
if ( fabs(direction1[i] - direction2[i]) > eps )
{
equal = false;
}
}
if (equal) // equal direction vectors
{
m_RelevantSNCs.push_back( *iter );
}
}
}
bool SlicesSwiveller
::ExecuteAction(Action* action, StateEvent const* stateEvent)
{
const ScalarType ThresholdDistancePixels = 6.0;
bool ok = false;
switch ( action->GetActionId() )
{
case AcMOVE:
{
// just reach through
SNCVector::iterator iter;
for ( iter = m_RelevantSNCs.begin();
iter != m_RelevantSNCs.end();
++iter )
{
if ( !(*iter)->GetSliceRotationLocked() )
{
(*iter)->ExecuteAction(action, stateEvent);
}
}
ok = true;
break;
}
case AcROTATE:
{
const DisplayPositionEvent *posEvent =
dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
if (!posEvent) break;
// Determine relative mouse movement projected onto world space
Point2D cursor = posEvent->GetDisplayPosition();
Vector2D relativeCursor = cursor - m_ReferenceCursor;
Vector3D relativeCursorAxis =
m_RotationPlaneXVector * relativeCursor[0]
+ m_RotationPlaneYVector * relativeCursor[1];
// Determine rotation axis (perpendicular to rotation plane and cursor
// movement)
Vector3D rotationAxis = itk::CrossProduct(
m_RotationPlaneNormal, relativeCursorAxis );
ScalarType rotationAngle = relativeCursor.GetNorm() / 2.0;
// Restore the initial plane pose by undoing the previous rotation
// operation
RotationOperation op( OpROTATE, m_CenterOfRotation,
m_PreviousRotationAxis, -m_PreviousRotationAngle );
SNCVector::iterator iter;
for ( iter = m_SNCsToBeRotated.begin();
iter != m_SNCsToBeRotated.end();
++iter )
{
if ( !(*iter)->GetSliceRotationLocked() )
{
const Geometry3D* geometry3D = (*iter)->GetCreatedWorldGeometry();
const TimeSlicedGeometry* timeSlicedGeometry =
dynamic_cast<const TimeSlicedGeometry*>(geometry3D);
if (!timeSlicedGeometry) continue;
const_cast<TimeSlicedGeometry*>(timeSlicedGeometry)
->ExecuteOperation(&op);
(*iter)->SendCreatedWorldGeometryUpdate();
}
}
// Apply new rotation operation to all relevant SNCs
RotationOperation op2( OpROTATE, m_CenterOfRotation,
rotationAxis, rotationAngle );
for ( iter = m_SNCsToBeRotated.begin();
iter != m_SNCsToBeRotated.end();
++iter)
{
if ( !(*iter)->GetSliceRotationLocked() )
{
//// Map rotation center onto display geometry (will be used as
//// pre-rotation vector for compensating a visual shift of the
//// rotation center)
//BaseRenderer *renderer = (*iter)->GetRenderer();
//DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
//Point2D point2DWorld, point2DDisplayPre, point2DDisplayPost;
//displayGeometry->Map( m_CenterOfRotation, point2DWorld );
//displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPre );
// Retrieve the TimeSlicedGeometry of this SliceNavigationController
const Geometry3D* geometry3D = (*iter)->GetCreatedWorldGeometry();
const TimeSlicedGeometry* timeSlicedGeometry =
dynamic_cast<const TimeSlicedGeometry*>(geometry3D);
if (!timeSlicedGeometry) continue;
// Execute the new rotation
const_cast<TimeSlicedGeometry*>(timeSlicedGeometry)
->ExecuteOperation(&op2);
//// After rotation: map rotation center onto new display geometry...
//displayGeometry->Map( m_CenterOfRotation, point2DWorld );
//displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPost );
//Vector2D vector2DDisplayDiff = point2DDisplayPost - point2DDisplayPre;
//// And use the difference between pre- and post-rotation vectors to
//// compensate for display geometry shift:
//Vector2D origin = displayGeometry->GetOriginInMM();
//displayGeometry->MoveBy( vector2DDisplayDiff );
// Notify listeners
(*iter)->SendCreatedWorldGeometryUpdate();
}
}
m_PreviousRotationAxis = rotationAxis;
m_PreviousRotationAngle = rotationAngle;
RenderingManager::GetInstance()->RequestUpdateAll();
this->InvokeEvent( SliceRotationEvent() ); // notify listeners
ok = true;
break;
}
case AcCHECKPOINT:
{
// Decide between moving and rotation: if we're close to the crossing
// point of the planes, moving mode is entered, otherwise
// rotation/swivel mode
const DisplayPositionEvent *posEvent =
dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
BaseRenderer *renderer = stateEvent->GetEvent()->GetSender();
if ( !posEvent || !renderer )
{
break;
}
const Point3D &cursor = posEvent->GetWorldPosition();
m_SNCsToBeRotated.clear();
const PlaneGeometry *clickedGeometry( NULL );
const PlaneGeometry *otherGeometry1( NULL );
const PlaneGeometry *otherGeometry2( NULL );
SNCVector::iterator iter;
for ( iter = m_RelevantSNCs.begin(); iter != m_RelevantSNCs.end(); ++iter )
{
//unsigned int slice = (*iter)->GetSlice()->GetPos();
//unsigned int time = (*iter)->GetTime()->GetPos();
const PlaneGeometry *planeGeometry = (*iter)->GetCurrentPlaneGeometry();
if ( !planeGeometry ) continue;
if ( *iter == renderer->GetSliceNavigationController() )
{
clickedGeometry = planeGeometry;
m_SNCsToBeRotated.push_back(*iter);
}
else
{
if ( otherGeometry1 == NULL )
{
otherGeometry1 = planeGeometry;
}
else
{
otherGeometry2 = planeGeometry;
}
if ( m_LinkPlanes )
{
// If planes are linked, apply rotation to all planes
m_SNCsToBeRotated.push_back(*iter);
}
}
}
StateEvent *newStateEvent( NULL );
mitk::Line3D line;
mitk::Point3D point;
if ( (clickedGeometry != NULL) && (otherGeometry1 != NULL)
&& (otherGeometry2 != NULL)
&& clickedGeometry->IntersectionLine( otherGeometry1, line )
&& otherGeometry2->IntersectionPoint( line, point ))
{
m_CenterOfRotation = point;
if ( m_CenterOfRotation.EuclideanDistanceTo( cursor )
< ThresholdDistancePixels )
{
newStateEvent = new StateEvent(EIDNO, stateEvent->GetEvent());
}
else
{
m_ReferenceCursor = posEvent->GetDisplayPosition();
// Get main axes of rotation plane and store it for rotation step
m_RotationPlaneNormal = clickedGeometry->GetNormal();
ScalarType xVector[] = { 1.0, 0.0, 0.0 };
ScalarType yVector[] = { 0.0, 1.0, 0.0 };
clickedGeometry->Geometry3D::IndexToWorld(
Vector3D( xVector), m_RotationPlaneXVector );
clickedGeometry->Geometry3D::IndexToWorld(
Vector3D( yVector), m_RotationPlaneYVector );
m_RotationPlaneNormal.Normalize();
m_RotationPlaneXVector.Normalize();
m_RotationPlaneYVector.Normalize();
m_PreviousRotationAxis.Fill( 0.0 );
m_PreviousRotationAxis[2] = 1.0;
m_PreviousRotationAngle = 0.0;
newStateEvent = new StateEvent(EIDYES, stateEvent->GetEvent());
}
}
else
{
newStateEvent = new StateEvent(EIDNO, stateEvent->GetEvent());
}
this->HandleEvent( newStateEvent );
delete newStateEvent;
ok = true;
break;
}
case AcROTATESTART:
{
this->InvokeEvent( SliceRotationEvent() ); // notify listeners
break;
}
case AcROTATEEND:
{
this->InvokeEvent( SliceRotationEvent() ); // notify listeners
break;
}
default:
{
break;
}
}
return ok;
}
} // namespace
diff --git a/Core/Code/Controllers/mitkSlicesSwiveller.h b/Core/Code/Controllers/mitkSlicesSwiveller.h
index 08f4e983f5..314fc12879 100644
--- a/Core/Code/Controllers/mitkSlicesSwiveller.h
+++ b/Core/Code/Controllers/mitkSlicesSwiveller.h
@@ -1,120 +1,119 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 7707 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 SLICESSWIVELLER_H_HEADER_INCLUDED
#define SLICESSWIVELLER_H_HEADER_INCLUDED
#include <mitkSlicesCoordinator.h>
#include <mitkVector.h>
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
namespace mitk {
/**
* \brief Enables arbitrary rotation of visible slices around a swivel point
* (for sliced geometries).
* \ingroup NavigationControl
*
* This class takes care of several SliceNavigationControllers and handles
* slice selection / slice rotation. It is added as listener to
* GlobalInteraction by QmitkStdMultiWidget.
*
* The SlicesSwiveller class adds the possibility of slice rotation to the
* "normal" behaviour of SliceNavigationControllers. This additional class
* is needed, because one has to be aware of several "visible slices"
* (selected Geometry2Ds of some SliceNavigationControllers) in order to
* choose between rotation and slice selection.
*
* Rotation is achieved by modifying (rotating) the generated
* TimeSlicedGeometry of the corresponding SliceNavigationController.
*
* With SlicesSwiveller, slice rotation works as follows: the user clicks onto
* a 2D view (2D plane) and drags the mouse; the relative direction and angle
* of the dragged mouse movement directly effects the rotation axis and
* angle. If "LinkPlanes" is set to true, the rotation is applied to the
* planes of all registered SNCs, not only of the one associated with the
* plane clicked on.
*
* In contrast to the situation without the SlicesRotator, the
* SliceNavigationControllers are now not directly registered as listeners to
* GlobalInteraction. SlicesRotator is registered as a listener and decides
* whether something should be rotated or whether another slice should be
* selected. In the latter case, a PositionEvent is just forwarded to the
* SliceNavigationController.
*
* \sa SlicesRotator
*/
class MITK_CORE_EXPORT SlicesSwiveller : public SlicesCoordinator
{
public:
mitkClassMacro(SlicesSwiveller, SlicesCoordinator);
static Pointer New();
/**
* @brief New Macro with one parameter for creating this object with static New(..) method
**/
mitkNewMacro1Param(Self, const char*);
virtual void SetGeometry(const itk::EventObject& EventObject);
protected:
SlicesSwiveller(const char* machine);
// clear list of controllers
virtual ~SlicesSwiveller();
// check if the slices of this SliceNavigationController can be rotated (???) Possible
virtual void OnSliceControllerAdded(SliceNavigationController* snc);
virtual void OnSliceControllerRemoved(SliceNavigationController* snc);
virtual void UpdateRelevantSNCs();
virtual bool ExecuteAction(Action * action, StateEvent const* stateEvent);
/** All SNCs that currently have CreatedWorldGeometries, that can be rotated */
SNCVector m_RelevantSNCs;
/** SNCs that will be rotated (clicked plane + all relevant others, if linked) */
SNCVector m_SNCsToBeRotated;
Point3D m_LastCursorPosition;
Point3D m_CenterOfRotation;
Point2D m_ReferenceCursor;
Vector3D m_RotationPlaneNormal;
Vector3D m_RotationPlaneXVector;
Vector3D m_RotationPlaneYVector;
Vector3D m_PreviousRotationAxis;
ScalarType m_PreviousRotationAngle;
};
} // namespace
#endif
diff --git a/Core/Code/Controllers/mitkStatusBar.cpp b/Core/Code/Controllers/mitkStatusBar.cpp
index 2edcee1b53..995baa45d7 100755
--- a/Core/Code/Controllers/mitkStatusBar.cpp
+++ b/Core/Code/Controllers/mitkStatusBar.cpp
@@ -1,122 +1,121 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStatusBar.h"
#include <itkObjectFactory.h>
#include <itkOutputWindow.h>
namespace mitk {
StatusBarImplementation* StatusBar::m_Implementation = NULL;
StatusBar* StatusBar::m_Instance = NULL;
/**
* Display the text in the statusbar of the applikation
*/
void StatusBar::DisplayText(const char* t)
{
if (m_Implementation != NULL)
m_Implementation->DisplayText(t);
}
/**
* Display the text in the statusbar of the applikation for ms seconds
*/
void StatusBar::DisplayText(const char* t, int ms)
{
if (m_Implementation != NULL)
m_Implementation->DisplayText(t, ms);
}
void StatusBar::DisplayErrorText(const char *t)
{
if (m_Implementation != NULL)
m_Implementation->DisplayErrorText(t);
}
void StatusBar::DisplayWarningText(const char *t)
{
if (m_Implementation != NULL)
m_Implementation->DisplayWarningText(t);
}
void StatusBar::DisplayWarningText(const char *t, int ms)
{
if (m_Implementation != NULL)
m_Implementation->DisplayWarningText(t, ms);
}
void StatusBar::DisplayGenericOutputText(const char *t)
{
if (m_Implementation != NULL)
m_Implementation->DisplayGenericOutputText(t);
}
void StatusBar::DisplayDebugText(const char *t)
{
if (m_Implementation != NULL)
m_Implementation->DisplayDebugText(t);
}
void StatusBar::DisplayGreyValueText(const char *t)
{
if (m_Implementation != NULL)
m_Implementation->DisplayGreyValueText(t);
}
void StatusBar::Clear()
{
if ( m_Implementation != NULL)
m_Implementation->Clear();
}
void StatusBar::SetSizeGripEnabled(bool enable)
{
if (m_Implementation != NULL)
{
m_Implementation->SetSizeGripEnabled(enable);
}
}
/**
* Get the instance of this StatusBar
*/
StatusBar* StatusBar::GetInstance()
{
if (m_Instance == NULL)//if not set, then send a errormessage on OutputWindow
{
m_Instance = new StatusBar();
}
return m_Instance;
}
/**
* Set an instance of this; application must do this!See Header!
*/
void StatusBar::SetImplementation(StatusBarImplementation* implementation)
{
if ( m_Implementation == implementation )
{
return;
}
m_Implementation = implementation;
}
StatusBar::StatusBar()
{
}
StatusBar::~StatusBar()
{
}
}//end namespace mitk
diff --git a/Core/Code/Controllers/mitkStatusBar.h b/Core/Code/Controllers/mitkStatusBar.h
index b078d5e7e8..29cc8981e0 100755
--- a/Core/Code/Controllers/mitkStatusBar.h
+++ b/Core/Code/Controllers/mitkStatusBar.h
@@ -1,85 +1,84 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSTATUSBAR_H
#define MITKSTATUSBAR_H
#include <itkObject.h>
#include <MitkExports.h>
#include "mitkStatusBarImplementation.h"
namespace mitk {
//##Documentation
//## @brief Sending a message to the applications StatusBar
//##
//## Holds a GUI dependent StatusBarImplementation and sends the text further.
//## nearly equal to itk::OutputWindow,
//## no Window, but one line of text and a delay for clear.
//## all mitk-classes use this class to display text on GUI-StatusBar.
//## The mainapplication has to set the internal held StatusBarImplementation with SetInstance(..).
//## @ingroup Interaction
class MITK_CORE_EXPORT StatusBar : public itk::Object
{
public:
itkTypeMacro(StatusBar, itk::Object);
//##Documentation
//## @brief static method to get the GUI dependent StatusBar-instance
//## so the methods DisplayText, etc. can be called
//## No reference counting, cause of decentral static use!
static StatusBar* GetInstance();
//##Documentation
//## @brief Supply a GUI- dependent StatusBar. Has to be set by the application
//## to connect the application dependent subclass of mitkStatusBar
//## if you create an instance, then call ->Delete() on the supplied
//## instance after setting it.
static void SetImplementation(StatusBarImplementation* instance);
//##Documentation
//## @brief Send a string to the applications StatusBar
void DisplayText(const char* t);
//##Documentation
//## @brief Send a string with a time delay to the applications StatusBar
void DisplayText(const char* t, int ms);
void DisplayErrorText(const char *t);
void DisplayWarningText(const char *t);
void DisplayWarningText(const char *t, int ms);
void DisplayGenericOutputText(const char *t);
void DisplayDebugText(const char *t);
void DisplayGreyValueText(const char *t);
//##Documentation
//## @brief removes any temporary message being shown.
void Clear();
//##Documentation
//## @brief Set the SizeGrip of the window
//## (the triangle in the lower right Windowcorner for changing the size)
//## to enabled or disabled
void SetSizeGripEnabled(bool enable);
protected:
StatusBar();
virtual ~StatusBar();
static StatusBarImplementation* m_Implementation;
static StatusBar* m_Instance;
};
}// end namespace mitk
#endif /* define MITKSTATUSBAR_H */
diff --git a/Core/Code/Controllers/mitkStatusBarImplementation.h b/Core/Code/Controllers/mitkStatusBarImplementation.h
index dd3c62d19c..52d35df790 100644
--- a/Core/Code/Controllers/mitkStatusBarImplementation.h
+++ b/Core/Code/Controllers/mitkStatusBarImplementation.h
@@ -1,63 +1,62 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSTATUSBARIMPLEMENTATION_H
#define MITKSTATUSBARIMPLEMENTATION_H
#include <MitkExports.h>
namespace mitk {
//##Documentation
//## @brief GUI indepentent Interface for all Gui depentent implementations of a StatusBar.
class MITK_CORE_EXPORT StatusBarImplementation
{
public:
//##Documentation
//## @brief Constructor
StatusBarImplementation(){};
//##Documentation
//## @brief Destructor
virtual ~StatusBarImplementation(){};
//##Documentation
//## @brief Send a string to the applications StatusBar
virtual void DisplayText(const char* t)=0;
//##Documentation
//## @brief Send a string with a time delay to the applications StatusBar
virtual void DisplayText(const char* t, int ms) = 0;
virtual void DisplayErrorText(const char *t) = 0;
virtual void DisplayWarningText(const char *t) = 0;
virtual void DisplayWarningText(const char *t, int ms) = 0;
virtual void DisplayGenericOutputText(const char *t) = 0;
virtual void DisplayDebugText(const char *t) = 0;
virtual void DisplayGreyValueText(const char *t) = 0;
//##Documentation
//## @brief removes any temporary message being shown.
virtual void Clear() = 0;
//##Documentation
//## @brief Set the SizeGrip of the window
//## (the triangle in the lower right Windowcorner for changing the size)
//## to enabled or disabled
virtual void SetSizeGripEnabled(bool enable) = 0;
};
}// end namespace mitk
#endif /* define MITKSTATUSBARIMPLEMENTATION_H */
diff --git a/Core/Code/Controllers/mitkStepper.cpp b/Core/Code/Controllers/mitkStepper.cpp
index 65f2ebfd76..080e96bb4d 100644
--- a/Core/Code/Controllers/mitkStepper.cpp
+++ b/Core/Code/Controllers/mitkStepper.cpp
@@ -1,219 +1,218 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStepper.h"
mitk::Stepper
::Stepper()
: m_Pos( 0 ),
m_Steps( 0 ),
m_AutoRepeat( false ),
m_PingPong( false ),
m_InverseDirection( false ),
m_RangeMin( 0.0 ),
m_RangeMax( -1.0 ),
m_RangeValid( false ),
m_HasRange( false ),
m_HasUnitName( false )
{
}
mitk::Stepper
::~Stepper()
{
}
void
mitk::Stepper
::SetRange( ScalarType min, ScalarType max )
{
m_RangeMin = min;
m_RangeMax = max;
m_HasRange = true;
m_RangeValid = true;
this->Modified();
}
void
mitk::Stepper
::InvalidateRange()
{
m_HasRange = true;
m_RangeValid = false;
this->Modified();
}
mitk::ScalarType
mitk::Stepper
::GetRangeMin() const
{
return m_RangeMin;
}
mitk::ScalarType
mitk::Stepper
::GetRangeMax() const
{
return m_RangeMax;
}
void
mitk::Stepper
::RemoveRange()
{
m_HasRange = false;
this->Modified();
}
bool
mitk::Stepper
::HasValidRange() const
{
return (m_HasRange && m_RangeValid);
}
bool
mitk::Stepper
::HasRange() const
{
return m_HasRange;
}
void
mitk::Stepper
::SetUnitName( const char *unitName )
{
m_UnitName = std::string( unitName );
m_HasUnitName = true;
this->Modified();
}
const char *
mitk::Stepper
::GetUnitName() const
{
return m_UnitName.c_str();
}
void
mitk::Stepper
::RemoveUnitName()
{
m_HasUnitName = false;
this->Modified();
}
bool
mitk::Stepper
::HasUnitName() const
{
return m_HasUnitName;
}
void
mitk::Stepper
::Increase()
{
if (this->GetPos() < this->GetSteps() - 1)
{
this->SetPos(this->GetPos() + 1);
}
else if (m_AutoRepeat)
{
if (!m_PingPong)
{
this->SetPos(0);
}
else
{
m_InverseDirection = true;
if (this->GetPos() > 0)
{
this->SetPos(this->GetPos() - 1);
}
}
}
}
void
mitk::Stepper
::Decrease()
{
if (this->GetPos() > 0)
{
this->SetPos(this->GetPos() - 1);
}
else if (m_AutoRepeat)
{
if (!m_PingPong)
{
this->SetPos(this->GetSteps() - 1);
}
else
{
m_InverseDirection = false;
if (this->GetPos() < this->GetSteps() - 1)
{
this->SetPos(this->GetPos() + 1);
}
}
}
}
void
mitk::Stepper
::Next()
{
if (!m_InverseDirection)
{
this->Increase();
}
else
{
this->Decrease();
}
}
void
mitk::Stepper
::Previous()
{
if (!m_InverseDirection)
{
this->Decrease();
}
else
{
this->Increase();
}
}
void
mitk::Stepper
::First()
{
this->SetPos(0);
}
void
mitk::Stepper
::Last()
{
this->SetPos(this->GetSteps() - 1);
}
diff --git a/Core/Code/Controllers/mitkStepper.h b/Core/Code/Controllers/mitkStepper.h
index f9ec3c2734..9db4e8816c 100644
--- a/Core/Code/Controllers/mitkStepper.h
+++ b/Core/Code/Controllers/mitkStepper.h
@@ -1,152 +1,151 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 STEPPER_H_HEADER_INCLUDED_C1E77191
#define STEPPER_H_HEADER_INCLUDED_C1E77191
#include <MitkExports.h>
#include <mitkCommon.h>
#include "mitkVector.h"
#include <itkObject.h>
#include <itkObjectFactory.h>
#include <string>
namespace mitk {
/**
* \brief Helper class to step through a list
*
* A helper class to step through a list. Does not contain the list, just the
* position in the list (between 0 and GetSteps()). Provides methods like
* First (go to the first element), Next (go to the next one), etc.
*
* Besides the actual number of steps, the stepper can also hold a stepping
* range, indicating the scalar values corresponding to the covered steps.
* For example, steppers are generally used to slice a dataset with a plane;
* Hereby, Steps indicates the total number of steps (positions) available for
* the plane, Pos indicates the current step, and Range indicates the physical
* minimum and maximum values for the plane, in this case a value in mm.
*
* The range can also be supplied with a unit name (a string) which can be
* used by classes providing information about the stepping (e.g. graphical
* sliders).
*
* \ingroup NavigationControl
*/
class MITK_CORE_EXPORT Stepper : public itk::Object
{
public:
mitkClassMacro(Stepper, itk::Object);
itkNewMacro(Self);
itkGetMacro(Pos, unsigned int);
virtual void SetPos(unsigned int pos)
{
// copied from itkMacro.h, itkSetClampMacro(...)
unsigned int newPos;
if ( m_Steps != 0 )
{
newPos = (pos > m_Steps-1 ? m_Steps-1 : pos);
}
else
{
newPos = 0;
}
if (this->m_Pos != newPos )
{
this->m_Pos = newPos ;
this->Modified();
}
}
itkGetMacro(Steps, unsigned int);
itkSetMacro(Steps, unsigned int);
itkGetMacro(AutoRepeat, bool);
itkSetMacro(AutoRepeat, bool);
itkBooleanMacro(AutoRepeat);
/** Causes the stepper to shift direction when the boundary is reached */
itkSetMacro(PingPong, bool);
itkGetMacro(PingPong, bool);
itkBooleanMacro(PingPong);
/** If set to true, the Next() decreases the stepper and Previous()
* decreases it */
itkSetMacro(InverseDirection, bool);
itkGetMacro(InverseDirection, bool);
itkBooleanMacro(InverseDirection);
void SetRange( ScalarType min, ScalarType max );
void InvalidateRange();
ScalarType GetRangeMin() const;
ScalarType GetRangeMax() const;
bool HasValidRange() const;
void RemoveRange();
bool HasRange() const;
void SetUnitName( const char *unitName );
const char *GetUnitName() const;
void RemoveUnitName();
bool HasUnitName() const;
virtual void Next();
virtual void Previous();
virtual void First();
virtual void Last();
protected:
Stepper();
virtual ~Stepper();
void Increase();
void Decrease();
unsigned int m_Pos;
unsigned int m_Steps;
bool m_AutoRepeat;
bool m_PingPong;
bool m_InverseDirection;
ScalarType m_RangeMin;
ScalarType m_RangeMax;
bool m_RangeValid;
bool m_HasRange;
std::string m_UnitName;
bool m_HasUnitName;
};
} // namespace mitk
#endif /* STEPPER_H_HEADER_INCLUDED_C1E77191 */
diff --git a/Core/Code/Controllers/mitkTestManager.cpp b/Core/Code/Controllers/mitkTestManager.cpp
index 81306607cb..492ff22084 100644
--- a/Core/Code/Controllers/mitkTestManager.cpp
+++ b/Core/Code/Controllers/mitkTestManager.cpp
@@ -1,41 +1,40 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 12626 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkTestManager.h"
mitk::TestManager* mitk::TestManager::GetInstance() {
static mitk::TestManager instance;
return &instance;
}
void mitk::TestManager::Initialize() {
m_FailedTests = 0;
m_PassedTests = 0;
}
int mitk::TestManager::NumberOfFailedTests() {
return m_FailedTests;
}
int mitk::TestManager::NumberOfPassedTests() {
return m_PassedTests;
}
void mitk::TestManager::TestFailed() {
m_FailedTests++;
}
void mitk::TestManager::TestPassed() {
m_PassedTests++;
}
diff --git a/Core/Code/Controllers/mitkTestManager.h b/Core/Code/Controllers/mitkTestManager.h
index 83d239f79b..e983039a25 100644
--- a/Core/Code/Controllers/mitkTestManager.h
+++ b/Core/Code/Controllers/mitkTestManager.h
@@ -1,45 +1,44 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 12626 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 MITK_TESTMANAGER_H_INCLUDED
#define MITK_TESTMANAGER_H_INCLUDED
#include <MitkExports.h>
namespace mitk {
class MITK_CORE_EXPORT TestManager {
public:
TestManager() : m_FailedTests(0), m_PassedTests(0) {}
static TestManager* GetInstance();
/** \brief Must be called at the beginning of a test run. */
void Initialize();
int NumberOfFailedTests();
int NumberOfPassedTests();
/** \brief Tell manager a subtest failed */
void TestFailed();
/** \brief Tell manager a subtest passed */
void TestPassed();
virtual ~TestManager() {}
protected:
int m_FailedTests;
int m_PassedTests;
};
}
#endif // MITK_TESTMANAGER_H_INCLUDED
diff --git a/Core/Code/Controllers/mitkTestingMacros.h b/Core/Code/Controllers/mitkTestingMacros.h
index f5bfd23c37..b698b9e283 100644
--- a/Core/Code/Controllers/mitkTestingMacros.h
+++ b/Core/Code/Controllers/mitkTestingMacros.h
@@ -1,140 +1,139 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <exception>
#include <string>
#include <iostream>
#include <itkExceptionObject.h>
#include <mitkTestManager.h>
namespace mitk {
/** \brief Indicate a failed test. */
class TestFailedException : public std::exception {
public:
TestFailedException() {}
};
}
/**
*
* \brief Output some text without generating a terminating newline. Include
*
* */
#define MITK_TEST_OUTPUT_NO_ENDL(x) \
std::cout x ;
/** \brief Output some text. */
#define MITK_TEST_OUTPUT(x) \
MITK_TEST_OUTPUT_NO_ENDL(x << "\n")
/** \brief Do some general test preparations. Must be called first in the
main test function. */
#define MITK_TEST_BEGIN(testName) \
std::string mitkTestName(#testName); \
mitk::TestManager::GetInstance()->Initialize(); \
try {
/** \brief Fail and finish test with message MSG */
#define MITK_TEST_FAILED_MSG(MSG) \
MITK_TEST_OUTPUT(MSG) \
throw mitk::TestFailedException();
/** \brief Must be called last in the main test function. */
#define MITK_TEST_END() \
} catch (mitk::TestFailedException ex) { \
MITK_TEST_OUTPUT(<< "Further test execution skipped.") \
mitk::TestManager::GetInstance()->TestFailed(); \
} catch (std::exception ex) { \
MITK_TEST_OUTPUT(<< "std::exception occured " << ex.what()) \
mitk::TestManager::GetInstance()->TestFailed(); \
} \
if (mitk::TestManager::GetInstance()->NumberOfFailedTests() > 0) { \
MITK_TEST_OUTPUT(<< mitkTestName << ": [DONE FAILED] , subtests passed: " << \
mitk::TestManager::GetInstance()->NumberOfPassedTests() << " failed: " << \
mitk::TestManager::GetInstance()->NumberOfFailedTests() ) \
return EXIT_FAILURE; \
} else { \
MITK_TEST_OUTPUT(<< mitkTestName << ": " \
<< mitk::TestManager::GetInstance()->NumberOfPassedTests() \
<< " tests [DONE PASSED]") \
return EXIT_SUCCESS; \
} \
#define MITK_TEST_CONDITION(COND,MSG) \
MITK_TEST_OUTPUT_NO_ENDL(<< MSG) \
if ( ! (COND) ) { \
mitk::TestManager::GetInstance()->TestFailed(); \
MITK_TEST_OUTPUT(<< " [FAILED]\n" << "In " << __FILE__ \
<< ", line " << __LINE__ \
<< ": " #COND " : [FAILED]") \
} else { \
MITK_TEST_OUTPUT(<< " [PASSED]") \
mitk::TestManager::GetInstance()->TestPassed(); \
}
#define MITK_TEST_CONDITION_REQUIRED(COND,MSG) \
MITK_TEST_OUTPUT_NO_ENDL(<< MSG) \
if ( ! (COND) ) { \
MITK_TEST_FAILED_MSG(<< " [FAILED]\n" << " +--> in " << __FILE__ \
<< ", line " << __LINE__ \
<< ", expression is false: \"" #COND "\"") \
} else { \
MITK_TEST_OUTPUT(<< " [PASSED]") \
mitk::TestManager::GetInstance()->TestPassed(); \
}
/**
* \brief Begin block which should be checked for exceptions
*
* This macro, together with MITK_TEST_FOR_EXCEPTION_END, can be used
* to test whether a code block throws an expected exception. The test FAILS if the
* exception is NOT thrown. A simple example:
*
MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ImageFileReaderException)
typedef itk::ImageFileReader< itk::Image<unsigned char,2> > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName("/tmp/not-existing");
reader->Update();
MITK_TEST_FOR_EXCEPTION_END(itk::ImageFileReaderException)
*
*/
#define MITK_TEST_FOR_EXCEPTION_BEGIN(EXCEPTIONCLASS) \
try {
#define MITK_TEST_FOR_EXCEPTION_END(EXCEPTIONCLASS) \
mitk::TestManager::GetInstance()->TestFailed(); \
MITK_TEST_OUTPUT( << "Expected an '" << #EXCEPTIONCLASS << "' exception. [FAILED]") \
} \
catch (EXCEPTIONCLASS) { \
MITK_TEST_OUTPUT( << "Caught an expected '" << #EXCEPTIONCLASS \
<< "' exception. [PASSED]") \
mitk::TestManager::GetInstance()->TestPassed(); \
}
/**
* \brief Simplified version of MITK_TEST_FOR_EXCEPTION_BEGIN / END for
* a single statement
*/
#define MITK_TEST_FOR_EXCEPTION(EXCEPTIONCLASS, STATEMENT) \
MITK_TEST_FOR_EXCEPTION_BEGIN(EXCEPTIONCLASS) \
STATEMENT ; \
MITK_TEST_FOR_EXCEPTION_END(EXCEPTIONCLASS)
diff --git a/Core/Code/Controllers/mitkUndoController.cpp b/Core/Code/Controllers/mitkUndoController.cpp
index dfa4376a66..b0888feaf4 100644
--- a/Core/Code/Controllers/mitkUndoController.cpp
+++ b/Core/Code/Controllers/mitkUndoController.cpp
@@ -1,222 +1,221 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkUndoController.h"
#include "mitkLimitedLinearUndo.h"
#include "mitkVerboseLimitedLinearUndo.h"
#include "mitkInteractionConst.h"
#include "mitkRenderingManager.h"
//static member-variables init.
mitk::UndoModel::Pointer mitk::UndoController::m_CurUndoModel;
mitk::UndoController::UndoModelMap mitk::UndoController::m_UndoModelList;
mitk::UndoController::UndoType mitk::UndoController::m_CurUndoType;
//const mitk::UndoController::UndoType mitk::UndoController::DEFAULTUNDOMODEL = LIMITEDLINEARUNDO;
const mitk::UndoController::UndoType mitk::UndoController::DEFAULTUNDOMODEL = VERBOSE_LIMITEDLINEARUNDO;
mitk::UndoController::UndoController(UndoType undoType)
{
if (SwitchUndoModel(undoType)==false) //existiert noch nicht in static-Liste
{
switch (undoType)
{
case LIMITEDLINEARUNDO:
m_CurUndoModel = mitk::LimitedLinearUndo::New();
m_CurUndoType = undoType;
m_UndoModelList.insert(UndoModelMap::value_type(undoType, m_CurUndoModel));
break;
case VERBOSE_LIMITEDLINEARUNDO:
m_CurUndoModel = mitk::VerboseLimitedLinearUndo::New();
m_CurUndoType = undoType;
m_UndoModelList.insert(UndoModelMap::value_type(undoType, m_CurUndoModel));
break;
//case ###
//insert here, in add- and RemoveUndoModel new sets of UndoModels!
//break;
default :
m_CurUndoModel = VerboseLimitedLinearUndo::New();
m_CurUndoType = undoType;
m_UndoModelList.insert(UndoModelMap::value_type(undoType, m_CurUndoModel));
}
}
}
mitk::UndoController::~UndoController()
{
}
bool mitk::UndoController::SetOperationEvent(UndoStackItem* operationEvent)
{
m_CurUndoModel->SetOperationEvent(operationEvent);
return true;
}
bool mitk::UndoController::Undo()
{
return this->Undo(true);
}
bool mitk::UndoController::Undo(bool fine)
{
bool ret = m_CurUndoModel->Undo(fine);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return ret;
}
bool mitk::UndoController::Redo()
{
return this->Redo(true);
}
bool mitk::UndoController::Redo(bool fine)
{
bool ret = m_CurUndoModel->Redo(fine);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return ret;
}
void mitk::UndoController::Clear()
{
m_CurUndoModel->Clear();
}
void mitk::UndoController::ClearRedoList()
{
m_CurUndoModel->ClearRedoList();
}
bool mitk::UndoController::RedoListEmpty()
{
return m_CurUndoModel->RedoListEmpty();
}
//##Documentation
//##Switches the UndoModel to the given Type
//##if there is no equal Type in List, then return false
bool mitk::UndoController::SwitchUndoModel(UndoType undoType)
{
if (m_CurUndoType == undoType)
{
return true;//already switched, don't need to be switched!
}
UndoModelMapIter undoModelIter = m_UndoModelList.find(undoType);
if (undoModelIter == m_UndoModelList.end())
{//undoType not found in List
return false;
}
//found-> switch to UndoModel
m_CurUndoModel = (undoModelIter)->second;
m_CurUndoType = (undoModelIter)->first;
return true;
}
//##Documentation
//##adds a new kind of UndoModel to the set of UndoModels
//##and switches to that UndoModel
//##if the UndoModel exists already in the List, then nothing is done
bool mitk::UndoController::AddUndoModel(UndoType undoType)
{
if (m_UndoModelList.find(undoType) != m_UndoModelList.end())
{ //UndoModel already exists
return false;
}
//doesn't already exist in list
switch (undoType)
{
case LIMITEDLINEARUNDO:
m_CurUndoModel = LimitedLinearUndo::New();
m_CurUndoType = undoType;
m_UndoModelList.insert(UndoModelMap::value_type(undoType, m_CurUndoModel));
break;
case VERBOSE_LIMITEDLINEARUNDO:
m_CurUndoModel = VerboseLimitedLinearUndo::New();
m_CurUndoType = undoType;
m_UndoModelList.insert(UndoModelMap::value_type(undoType, m_CurUndoModel));
break;
default:
//that undoType is not implemented!
return false;
}
return true;
}
//##Documentation
//##Removes an UndoModel from the set of UndoModels
//##If that UndoModel is currently selected, then the DefaultUndoModel(const) is set.
//##If the default is not in List, then the first UndoModel is set.
//##UndoList may not be empty, so if the UndoType is the last, then return false;
bool mitk::UndoController::RemoveUndoModel(UndoType undoType)
{
if (m_UndoModelList.size() < 2)
{//for no empty m_UndoModelList
return false;
}
//try deleting Element
int ok = m_UndoModelList.erase(undoType);
if (ok == 0)
{//delete unsucessful; Element of undoType not found
return false;
}
//if m_CurUndoModel is the one removed, then change it to default or to the next or first
if (m_CurUndoType == undoType)
{//we have to change m_CurUndoModel and m_CurUndoType to an existing Model
//if defaultUndoModel exists, then set to default
UndoModelMapIter undoModelIter = m_UndoModelList.find(DEFAULTUNDOMODEL);
if (undoModelIter == m_UndoModelList.end())
{//DefaultUndoModel does not exists in m_CurUndoModelList
undoModelIter = m_UndoModelList.begin();
}
m_CurUndoModel = (undoModelIter)->second;
m_CurUndoType = (undoModelIter)->first;
return true;
}
//m_CurUndoType was not undoType and is not changed
return true;
}
int mitk::UndoController::GetLastObjectEventIdInList()
{
return m_CurUndoModel->GetLastObjectEventIdInList();
}
int mitk::UndoController::GetLastGroupEventIdInList()
{
return m_CurUndoModel->GetLastGroupEventIdInList();
}
mitk::OperationEvent* mitk::UndoController::GetLastOfType(OperationActor* destination, OperationType opType)
{
return m_CurUndoModel->GetLastOfType(destination, opType);
}
mitk::UndoModel* mitk::UndoController::GetCurrentUndoModel()
{
return m_CurUndoModel;
}
diff --git a/Core/Code/Controllers/mitkUndoController.h b/Core/Code/Controllers/mitkUndoController.h
index e4647e6158..fd188f1722 100644
--- a/Core/Code/Controllers/mitkUndoController.h
+++ b/Core/Code/Controllers/mitkUndoController.h
@@ -1,135 +1,134 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 UNDOCONTROLLER_H_HEADER_INCLUDED_C16EFF79
#define UNDOCONTROLLER_H_HEADER_INCLUDED_C16EFF79
#include <MitkExports.h>
#include "mitkUndoModel.h"
#include "mitkOperationEvent.h"
#include <map>
namespace mitk {
//## @ingroup Undo
class MITK_CORE_EXPORT UndoController
{
public:
//different UndoModels:
enum UndoType{LIMITEDLINEARUNDO=10, VERBOSE_LIMITEDLINEARUNDO=11, TREEUNDO=20};
typedef std::map<UndoType, UndoModel::Pointer> UndoModelMap;
typedef std::map<UndoType, UndoModel::Pointer>::iterator UndoModelMapIter;
//##Documentation
//## @brief Default UndoModel to use.
static const UndoType DEFAULTUNDOMODEL;
//##Documentation
//## Constructor; Adds the new UndoType or if undoType exists ,
//## switches it to undoType; for UndoTypes see definitionmitkInteractionConst.h
UndoController(UndoType undoType = DEFAULTUNDOMODEL);
virtual ~UndoController();
bool SetOperationEvent(UndoStackItem* operationEvent);
//##Documentation
//## @brief calls the UndoMechanism to undo the last change
bool Undo();
//##Documentation
//## @brief calls the UndoMechanism to undo the last change
//##
//## the UndoMechanism has the possibility to undo the last changes in two different ways:
//## first it can Undo a group of operations done at last (e.g. build up a new object; Undo leads to deleting that object);
//## or it can Undo a set of operations, that belong together(statechange with Action),
//## that way it is possible recall the last set point after you have finished to build up a new object
//## @param fine: if set to true, then undo all operations with the same objectEventId
//## if set to false, then undo all operations with the same GroupEventId
bool Undo(bool fine);
//##Documentation
//## @brief calls the RedoMechanism to redo the operations undone
//##
//## read the Documentation of Undo!
bool Redo();
//##Documentation
//## @brief calls the RedoMechanism to redo the operations undone
//##
//## read the Documentation of Undo!
//## only with the possibility to fine redo, like fine undo
bool Redo(bool fine);
//##Documentation
//## @brief Clears the Undo and the RedoList
void Clear();
//##Documentation
//## @brief Clears the RedoList
void ClearRedoList();
//##Documentation
//## @brief returns true, if the RedoList is empty
bool RedoListEmpty();
bool SwitchUndoModel(UndoType undoType);
bool AddUndoModel(UndoType undoType);
bool RemoveUndoModel(UndoType undoType);
//##Documentation
//## @brief returns the ObjectEventId of the
//## top Element in the OperationHistory of the selected
//## UndoModel
int GetLastObjectEventIdInList();
//##Documentation
//## @brief returns the GroupEventId of the
//## top Element in the OperationHistory of the selected
//## UndoModel
int GetLastGroupEventIdInList();
//##Documentation
//## @brief returns the last specified OperationEvent in Undo-list
//## corresponding to the given value; if nothing found, then returns NULL
OperationEvent* GetLastOfType(OperationActor* destination, OperationType opType);
//##Documentation
//## @brief gives access to the currently used UndoModel
//## Introduced to access special functions of more specific UndoModels,
//## especially to retrieve text descriptions of the undo/redo stack
static UndoModel* GetCurrentUndoModel();
private:
//##Documentation
//## current selected UndoModel
static UndoModel::Pointer m_CurUndoModel;
//##Documentation
//## current selected Type of m_CurUndoModel
static UndoType m_CurUndoType;
//##Documentation
//## different UndoModels to select and activate
static UndoModelMap m_UndoModelList;
};
}//namespace mitk
#endif /* UNDOCONTROLLER_H_HEADER_INCLUDED_C16EFF79 */
diff --git a/Core/Code/Controllers/mitkUndoModel.h b/Core/Code/Controllers/mitkUndoModel.h
index 692e465ba1..87fcd062b6 100644
--- a/Core/Code/Controllers/mitkUndoModel.h
+++ b/Core/Code/Controllers/mitkUndoModel.h
@@ -1,93 +1,92 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 UNDOMODEL_H_HEADER_INCLUDED_C16ED098
#define UNDOMODEL_H_HEADER_INCLUDED_C16ED098
#include "mitkCommon.h"
#include "mitkOperation.h"
#include <itkObject.h>
#include <itkObjectFactory.h>
namespace mitk {
class UndoStackItem;
class OperationEvent;
class OperationActor;
//##Documentation
//## @brief superclass for all UndoModels
//##
//## all necessary operations, that all UndoModels share.
//## @ingroup Undo
class MITK_CORE_EXPORT UndoModel : public itk::Object
{
public:
mitkClassMacro(UndoModel, itk::Object);
// no New Macro because this is an abstract class!
virtual bool SetOperationEvent(UndoStackItem* stackItem) = 0;
virtual bool Undo() = 0;
virtual bool Undo(bool fine) = 0;
virtual bool Redo() = 0;
virtual bool Redo(bool fine) = 0;
//##Documentation
//## @brief clears undo and Redolist
virtual void Clear() = 0;
//##Documentation
//## @brief clears the RedoList
virtual void ClearRedoList() = 0;
//##Documentation
//## @brief true if RedoList is empty
virtual bool RedoListEmpty() = 0;
//##Documentation
//## @brief returns the ObjectEventId of the
//## top Element in the OperationHistory of the selected
//## UndoModel
virtual int GetLastObjectEventIdInList() = 0;
//##Documentation
//## @brief returns the GroupEventId of the
//## top Element in the OperationHistory of the selected
//## UndoModel
virtual int GetLastGroupEventIdInList() = 0;
//##Documentation
//## @brief returns the last specified OperationEvent in Undo-list
//## corresponding to the given values; if nothing found, then returns NULL
//##
//## needed to get the old Position of an Element for declaring an UndoOperation
virtual OperationEvent* GetLastOfType(OperationActor* destination, OperationType opType) = 0;
protected:
UndoModel(){};
virtual ~UndoModel(){};
};
}// namespace mitk
#endif /* UNDOMODEL_H_HEADER_INCLUDED_C16ED098 */
diff --git a/Core/Code/Controllers/mitkVerboseLimitedLinearUndo.cpp b/Core/Code/Controllers/mitkVerboseLimitedLinearUndo.cpp
index a9b29f60ac..055ace2daf 100644
--- a/Core/Code/Controllers/mitkVerboseLimitedLinearUndo.cpp
+++ b/Core/Code/Controllers/mitkVerboseLimitedLinearUndo.cpp
@@ -1,181 +1,180 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVerboseLimitedLinearUndo.h"
#include "mitkOperationEvent.h"
mitk::VerboseLimitedLinearUndo::VerboseLimitedLinearUndo()
{
}
mitk::VerboseLimitedLinearUndo::~VerboseLimitedLinearUndo()
{
}
bool mitk::VerboseLimitedLinearUndo::SetOperationEvent(UndoStackItem* undoStackItem)
{
if (!undoStackItem) return false;
// clear the redolist, if a new operation is saved
if (!m_RedoList.empty())
{
this->ClearList(&m_RedoList);
InvokeEvent( RedoEmptyEvent() );
}
m_UndoList.push_back(undoStackItem);
InvokeEvent( UndoNotEmptyEvent() );
return true;
}
mitk::VerboseLimitedLinearUndo::StackDescription mitk::VerboseLimitedLinearUndo::GetUndoDescriptions()
{
mitk::VerboseLimitedLinearUndo::StackDescription descriptions;
if(m_UndoList.empty()) return descriptions;
int oeid = m_UndoList.back()->GetObjectEventId(); // ObjectEventID of current group
std::string currentDescription; // description of current group
int currentDescriptionCount(0); // counter, how many items of the current group gave descriptions
bool niceDescriptionFound(false); // have we yet seen a plain descriptive entry (not OperationEvent)?
std::string lastDescription; // stores the last description to inhibit entries like "name AND name AND name..." if name is always the same
for ( std::vector<UndoStackItem*>::reverse_iterator iter = m_UndoList.rbegin(); iter != m_UndoList.rend(); ++iter )
{
if ( oeid != (*iter)->GetObjectEventId() )
{
// current description complete, append to list
if ( currentDescription.empty() )
currentDescription = "Some unnamed action"; // set a default description
descriptions.push_back( StackDescriptionItem(oeid,currentDescription) );
currentDescription = ""; // prepare for next group
currentDescriptionCount = 0;
niceDescriptionFound = false;
oeid = (*iter)->GetObjectEventId();
}
if ( !(*iter)->GetDescription().empty() ) // if there is a description
{
if (!dynamic_cast<OperationEvent*>(*iter))
{
// anything but an OperationEvent overrides the collected descriptions
currentDescription = (*iter)->GetDescription();
niceDescriptionFound = true;
}
else if (!niceDescriptionFound) // mere descriptive items override OperationEvents' descriptions
{
if ( currentDescriptionCount ) // if we have already seen another description
{
if (lastDescription != (*iter)->GetDescription())
{
//currentDescription += '\n'; // concatenate descriptions with newline
currentDescription += " AND "; // this has to wait until the popup can process multiline items
currentDescription += (*iter)->GetDescription();
}
}
else
{
currentDescription += (*iter)->GetDescription();
}
}
lastDescription = (*iter)->GetDescription();
++currentDescriptionCount;
}
} // for
// add last description to list
if ( currentDescription.empty() )
currentDescription = "Some unnamed action";
descriptions.push_back( StackDescriptionItem( oeid, currentDescription) );
return descriptions; // list ready
}
mitk::VerboseLimitedLinearUndo::StackDescription mitk::VerboseLimitedLinearUndo::GetRedoDescriptions()
{
mitk::VerboseLimitedLinearUndo::StackDescription descriptions;
if(m_RedoList.empty()) return descriptions;
int oeid = m_RedoList.back()->GetObjectEventId(); // ObjectEventID of current group
std::string currentDescription; // description of current group
int currentDescriptionCount(0); // counter, how many items of the current group gave descriptions
bool niceDescriptionFound(false); // have we yet seen a plain descriptive entry (not OperationEvent)?
std::string lastDescription; // stores the last description to inhibit entries like "name AND name AND name..." if name is always the same
for ( std::vector<UndoStackItem*>::reverse_iterator iter = m_RedoList.rbegin(); iter != m_RedoList.rend(); ++iter )
{
if ( oeid != (*iter)->GetObjectEventId() )
{
// current description complete, append to list
if ( currentDescription.empty() )
currentDescription = "Some unnamed action"; // set a default description
descriptions.push_back( StackDescriptionItem( oeid, currentDescription) );
currentDescription = ""; // prepare for next group
currentDescriptionCount = 0;
niceDescriptionFound = false;
oeid = (*iter)->GetObjectEventId();
}
if ( !(*iter)->GetDescription().empty() ) // if there is a description
{
if (!dynamic_cast<OperationEvent*>(*iter))
{
// anything but an OperationEvent overrides the collected descriptions
currentDescription = (*iter)->GetDescription();
niceDescriptionFound = true;
}
else if (!niceDescriptionFound) // mere descriptive items override OperationEvents' descriptions
{
if ( currentDescriptionCount ) // if we have already seen another description
{
if (lastDescription != (*iter)->GetDescription())
{
//currentDescription += '\n'; // concatenate descriptions with newline
currentDescription += " AND "; // this has to wait until the popup can process multiline items
currentDescription += (*iter)->GetDescription();
}
}
else
{
currentDescription += (*iter)->GetDescription();
}
}
lastDescription = (*iter)->GetDescription();
++currentDescriptionCount;
}
} // for
// add last description to list
if ( currentDescription.empty() )
currentDescription = "Some unnamed action";
descriptions.push_back( StackDescriptionItem( oeid, currentDescription) );
return descriptions; // list ready
}
diff --git a/Core/Code/Controllers/mitkVerboseLimitedLinearUndo.h b/Core/Code/Controllers/mitkVerboseLimitedLinearUndo.h
index 17e647d153..394a36fd71 100644
--- a/Core/Code/Controllers/mitkVerboseLimitedLinearUndo.h
+++ b/Core/Code/Controllers/mitkVerboseLimitedLinearUndo.h
@@ -1,63 +1,62 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 VERBOSELIMITEDLINEARUNDO_H_HEADER_INCLUDED_C16E96
#define VERBOSELIMITEDLINEARUNDO_H_HEADER_INCLUDED_C16E96
// MITK header
#include <MitkExports.h>
#include "mitkLimitedLinearUndo.h"
// STL header
#include <vector>
#include <list>
#include <utility>
#include <string>
namespace mitk {
class UndoStackItem;
/**
* @brief A limited linear undo model providing GUI elements with stack status information.
*
* Basically does the same, as LimitedLinearUndo class, but it allows you to retrieve a string list, which describes
* the undo stack or the redo stack. This can be used for display by GUI elements.
*/
class MITK_CORE_EXPORT VerboseLimitedLinearUndo : public LimitedLinearUndo
{
public:
mitkClassMacro(VerboseLimitedLinearUndo, LimitedLinearUndo);
itkNewMacro(Self);
typedef std::pair<int,std::string> StackDescriptionItem;
typedef std::vector<StackDescriptionItem> StackDescription; /// a list of pairs (int,string), representing a stack with ObjectEventIDs and descriptions
virtual bool SetOperationEvent(UndoStackItem* undoStackItem);
virtual StackDescription GetUndoDescriptions();
virtual StackDescription GetRedoDescriptions();
protected:
VerboseLimitedLinearUndo();
virtual ~VerboseLimitedLinearUndo();
};
} // namespace mitk
#endif /* VERBOSELIMITEDLINEARUNDO_H_HEADER_INCLUDED_C16E96 */
diff --git a/Core/Code/Controllers/mitkVtkInteractorCameraController.cpp b/Core/Code/Controllers/mitkVtkInteractorCameraController.cpp
index bd535d960a..c8235cfb5e 100644
--- a/Core/Code/Controllers/mitkVtkInteractorCameraController.cpp
+++ b/Core/Code/Controllers/mitkVtkInteractorCameraController.cpp
@@ -1,196 +1,195 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkVtkInteractorCameraController.h"
#include "mitkInteractionConst.h"
#include <vtkInteractorStyleSwitch.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCommand.h>
#include "mitkAction.h"
#include "mitkVtkPropRenderer.h"
mitk::VtkInteractorCameraController::VtkInteractorCameraController(const char* type) : CameraController(type), m_VtkInteractor(NULL)
{
//m_VtkInteractor = vtkRenderWindowInteractor::New();
}
mitk::VtkInteractorCameraController::~VtkInteractorCameraController()
{
if(m_VtkInteractor!=NULL)
{
m_VtkInteractor->SetRenderWindow(NULL);
m_VtkInteractor->Delete();
m_VtkInteractor = NULL;
}
}
void mitk::VtkInteractorCameraController::Resize(int w, int h)
{
if(m_VtkInteractor)
m_VtkInteractor->SetSize(w, h);
}
void mitk::VtkInteractorCameraController::MousePressEvent(mitk::MouseEvent *me)
{
MITK_INFO<<"Called MousePressEvent() in VtkInteractorCameraController. Seems to be obsolete after QVTK restructuring (bug #1503, bug #954)"<<std::endl;
if(m_VtkInteractor)
{
if (!m_VtkInteractor->GetEnabled())
{
return;
}
int ctrl = me->GetButtonState() & BS_ControlButton;
int shift = me->GetButtonState() & BS_ShiftButton;
int xp = (int)me->GetDisplayPosition()[0];
int yp = (int)me->GetDisplayPosition()[1];
m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);
switch (me->GetButton())
{
case BS_LeftButton:
m_VtkInteractor->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
break;
case BS_MidButton:
m_VtkInteractor->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL);
break;
case BS_RightButton:
m_VtkInteractor->InvokeEvent(vtkCommand::RightButtonPressEvent,NULL);
break;
default:
return;
}
}
}
void mitk::VtkInteractorCameraController::MouseReleaseEvent(mitk::MouseEvent *me)
{
MITK_INFO<<"Called MouseReleaseEvent() in VtkInteractorCameraController. Seems to be obsolete after QVTK restructuring (bug #1503, bug #954)"<<std::endl;
if(m_VtkInteractor)
{
if (!m_VtkInteractor->GetEnabled())
{
return;
}
int ctrl = me->GetButtonState() & BS_ControlButton;
int shift = me->GetButtonState() & BS_ShiftButton;
int xp = (int)me->GetDisplayPosition()[0];
int yp = (int)me->GetDisplayPosition()[1];
m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);
switch (me->GetButton())
{
case BS_LeftButton:
m_VtkInteractor->InvokeEvent(vtkCommand::LeftButtonReleaseEvent,NULL);
break;
case BS_MidButton:
m_VtkInteractor->InvokeEvent(vtkCommand::MiddleButtonReleaseEvent,NULL);
break;
case BS_RightButton:
m_VtkInteractor->InvokeEvent(vtkCommand::RightButtonReleaseEvent,NULL);
break;
default:
return;
}
}
}
void mitk::VtkInteractorCameraController::MouseMoveEvent(mitk::MouseEvent *me)
{
MITK_INFO<<"Called MouseMoveEvent() in VtkInteractorCameraController. Seems to be obsolete after QVTK restructuring (bug #1503, bug #954)"<<std::endl;
if(m_VtkInteractor)
{
if (!m_VtkInteractor->GetEnabled())
{
return;
}
int ctrl = me->GetButtonState() & BS_ControlButton;
int shift = me->GetButtonState() & BS_ShiftButton;
int xp = (int)me->GetDisplayPosition()[0];
int yp = (int)me->GetDisplayPosition()[1];
m_VtkInteractor->SetEventInformationFlipY(xp, yp, ctrl, shift);
m_VtkInteractor->InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
}
}
void mitk::VtkInteractorCameraController::KeyPressEvent(mitk::KeyEvent *ke)
{
MITK_INFO<<"Called KeyPressEvent() in VtkInteractorCameraController. Seems to be obsolete after QVTK restructuring (bug #1503, bug #954)"<<std::endl;
if(m_VtkInteractor)
{
if (!m_VtkInteractor->GetEnabled())
{
return;
}
int ctrl = ke->GetButtonState() & BS_ControlButton;
int shift = ke->GetButtonState() & BS_ShiftButton;
Point2D p(ke->GetDisplayPosition());
m_VtkInteractor->SetEventInformationFlipY(p[0], p[1], ctrl, shift, tolower(ke->GetText()[0]), 1, ke->GetText());
m_VtkInteractor->InvokeEvent(vtkCommand::KeyPressEvent, NULL);
m_VtkInteractor->InvokeEvent(vtkCommand::CharEvent, NULL);
}
}
void mitk::VtkInteractorCameraController::SetRenderer(const mitk::BaseRenderer* renderer)
{
Superclass::SetRenderer(renderer);
if (renderer)
{
// CHG 11-07: QVTK-Widget comes along with vtkRenderWindow and vtkRenWinInteractor, therefore do not
// generate a new one any more
m_VtkInteractor = renderer->GetVtkRenderer()->GetRenderWindow()->GetInteractor();
m_VtkInteractor->SetRenderWindow(renderer->GetVtkRenderer()->GetRenderWindow());
// Enable possibility to (mouse-)interact with the renderer
m_VtkInteractor->Enable();
m_VtkInteractor->Register(NULL);
}
/* VtkRenderWindowInteractor* windowInteractor =
dynamic_cast<VtkRenderWindowInteractor*>(m_VtkInteractor);
if (windowInteractor == NULL)
{
itkWarningMacro(<< "renderwindow is not an mitk::VtkRenderWindow");
}
else
{
windowInteractor->SetMitkRenderer(const_cast<mitk::BaseRenderer*>(this->GetRenderer()));
}
m_VtkInteractor->Initialize();
m_VtkInteractor->SetRenderWindow(renderer->GetVtkRenderWindow());
}
else
{
m_VtkInteractor->SetRenderWindow(NULL);
m_VtkInteractor->Delete();
m_VtkInteractor = NULL;
}*/
}
vtkRenderWindowInteractor* mitk::VtkInteractorCameraController::GetVtkInteractor()
{
return m_VtkInteractor;
}
///*
//bool mitk::VtkInteractorCameraController::ExecuteAction(Action*, mitk::StateEvent const * /*stateEvent*/
//{
// return false;
//}
//*/
diff --git a/Core/Code/Controllers/mitkVtkInteractorCameraController.h b/Core/Code/Controllers/mitkVtkInteractorCameraController.h
index c908ac3ac9..da9de00524 100644
--- a/Core/Code/Controllers/mitkVtkInteractorCameraController.h
+++ b/Core/Code/Controllers/mitkVtkInteractorCameraController.h
@@ -1,71 +1,70 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKVTKINTERACTORCAMERACONTROLLER_H_HEADER_INCLUDED_C1C53722
#define MITKVTKINTERACTORCAMERACONTROLLER_H_HEADER_INCLUDED_C1C53722
#include <MitkExports.h>
#include "mitkCameraController.h"
#include "vtkRenderWindowInteractor.h"
class vtkRenderWindow;
namespace mitk {
//##Documentation
//## @brief vtk-based camera controller
//## @ingroup NavigationControl
class MITK_CORE_EXPORT VtkInteractorCameraController : public CameraController
{
public:
mitkClassMacro(VtkInteractorCameraController, CameraController);
itkNewMacro(Self);
//##Documentation
//## @brief Returns the vtkRenderWindowInteractor used internally by this CameraController
vtkRenderWindowInteractor* GetVtkInteractor();
virtual void Resize(int w, int h);
virtual void MousePressEvent(mitk::MouseEvent*);
virtual void MouseReleaseEvent(mitk::MouseEvent*);
virtual void MouseMoveEvent(mitk::MouseEvent*);
virtual void KeyPressEvent(mitk::KeyEvent*);
//##Documentation
//## @brief Set the BaseRenderer to be controlled by this vtk-based camera controller
virtual void SetRenderer(const mitk::BaseRenderer* renderer);
protected:
/**
* @brief Default Constructor
**/
VtkInteractorCameraController(const char* type = NULL);
/**
* @brief Default Destructor
**/
virtual ~VtkInteractorCameraController();
// virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
vtkRenderWindowInteractor* m_VtkInteractor;
};
} // namespace mitk
#endif /* MITKVTKINTERACTORCAMERACONTROLLER_H_HEADER_INCLUDED_C1C53722 */
diff --git a/Core/Code/Controllers/mitkVtkLayerController.cpp b/Core/Code/Controllers/mitkVtkLayerController.cpp
index ed1c22176b..43677f9b96 100644
--- a/Core/Code/Controllers/mitkVtkLayerController.cpp
+++ b/Core/Code/Controllers/mitkVtkLayerController.cpp
@@ -1,343 +1,342 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkVtkLayerController.h"
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkObjectFactory.h>
#include <vtkRendererCollection.h>
#include <algorithm>
mitk::VtkLayerController::vtkLayerControllerMapType mitk::VtkLayerController::s_LayerControllerMap;
mitk::VtkLayerController * mitk::VtkLayerController::GetInstance(vtkRenderWindow* renWin)
{
for(vtkLayerControllerMapType::iterator mapit = s_LayerControllerMap.begin();
mapit != s_LayerControllerMap.end(); mapit++)
{
if( (*mapit).first == renWin)
return (*mapit).second;
}
return NULL;
}
void mitk::VtkLayerController::AddInstance(vtkRenderWindow* renWin, vtkRenderer * mitkSceneRenderer)
{
// ensure that no vtkRenderWindow is managed twice
mitk::VtkLayerController::RemoveInstance(renWin);
// instanciate controller, add it to the map
mitk::VtkLayerController* ControllerInstance = new mitk::VtkLayerController(renWin);
ControllerInstance->InsertSceneRenderer(mitkSceneRenderer);
s_LayerControllerMap.insert(vtkLayerControllerMapType::value_type(renWin,ControllerInstance));
}
void mitk::VtkLayerController::RemoveInstance(vtkRenderWindow* renWin)
{
vtkLayerControllerMapType::iterator mapit = s_LayerControllerMap.find(renWin);
if(mapit != s_LayerControllerMap.end())
{
delete mapit->second;
s_LayerControllerMap.erase( mapit );
}
}
mitk::VtkLayerController::VtkLayerController(vtkRenderWindow* renderWindow)
{
m_RenderWindow = renderWindow;
m_RenderWindow->Register( NULL );
m_BackgroundRenderers.clear();
m_ForegroundRenderers.clear();
m_SceneRenderers.clear();
}
mitk::VtkLayerController::~VtkLayerController()
{
if ( m_RenderWindow != NULL )
{
m_RenderWindow->UnRegister( NULL );
}
}
/**
* Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the background.
* With forceAbsoluteBackground set true a renderer can be placed at the absolute background of the scene.
* Multiple calls with forceAbsoluteBackground set true will set the latest registered renderer as background.
*/
void mitk::VtkLayerController::InsertBackgroundRenderer(vtkRenderer* renderer, bool forceAbsoluteBackground)
{
if(renderer == NULL)
return;
// Remove renderer if it already exists
RemoveRenderer(renderer);
if(forceAbsoluteBackground)
{
RendererVectorType::iterator it = m_BackgroundRenderers.begin();
m_BackgroundRenderers.insert(it,renderer);
}
else
m_BackgroundRenderers.push_back(renderer);
UpdateLayers();
}
/**
* Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the foreground.
* With forceAbsoluteBackground set true a renderer can be placed at the absolute foreground of the scene.
* Multiple calls with forceAbsoluteForeground set true will set the latest registered renderer as foreground.
*/
void mitk::VtkLayerController::InsertForegroundRenderer(vtkRenderer* renderer, bool forceAbsoluteForeground)
{
if(renderer == NULL)
return;
// Remove renderer if it already exists
RemoveRenderer(renderer);
if(forceAbsoluteForeground)
{
RendererVectorType::iterator it = m_ForegroundRenderers.begin();
m_ForegroundRenderers.insert(it,renderer);
}
else
m_ForegroundRenderers.push_back(renderer);
UpdateLayers();
}
/**
* Returns the Scene Renderer
*/
vtkRenderer* mitk::VtkLayerController::GetSceneRenderer()
{
if(m_SceneRenderers.size() > 0)
{
RendererVectorType::iterator it = m_SceneRenderers.begin();
return (*it);
}
else
return NULL;
}
/**
* Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered between background renderers and
* foreground renderers.
*/
void mitk::VtkLayerController::InsertSceneRenderer(vtkRenderer* renderer)
{
if(renderer == NULL)
return;
// Remove renderer if it already exists
RemoveRenderer(renderer);
m_SceneRenderers.push_back(renderer);
UpdateLayers();
}
/**
* A renderer which has been inserted via a insert... function can be removed from the vtkRenderWindow with
* RemoveRenderer.
*/
void mitk::VtkLayerController::RemoveRenderer(vtkRenderer* renderer)
{
RendererVectorType::iterator it;
// background layers
if(m_BackgroundRenderers.size() > 0)
{
it = std::find(m_BackgroundRenderers.begin(),m_BackgroundRenderers.end(),renderer);
if(it != m_BackgroundRenderers.end())
{
m_BackgroundRenderers.erase(it);
UpdateLayers();
return;
}
}
// scene layers
if(m_SceneRenderers.size() > 0)
{
it = std::find(m_SceneRenderers.begin(),m_SceneRenderers.end(),renderer);
if(it != m_SceneRenderers.end())
{
m_SceneRenderers.erase(it);
UpdateLayers();
return;
}
}
// foreground layers
if(m_ForegroundRenderers.size() > 0 )
{
it = std::find(m_ForegroundRenderers.begin(),m_ForegroundRenderers.end(),renderer);
if(it != m_ForegroundRenderers.end())
{
m_ForegroundRenderers.erase(it);
UpdateLayers();
return;
}
}
}
/**
* Connects a VtkRenderWindow with the layer controller.
*/
void mitk::VtkLayerController::SetRenderWindow(vtkRenderWindow* renwin)
{
if(renwin != NULL)
{
RendererVectorType::iterator it;
// Tell all renderers that there is a new renderwindow
for(it = m_BackgroundRenderers.begin(); it != m_BackgroundRenderers.end(); it++)
{
(*it)->SetRenderWindow(renwin);
}
for(it = m_SceneRenderers.begin(); it != m_SceneRenderers.end(); it++)
{
(*it)->SetRenderWindow(renwin);
}
for(it = m_ForegroundRenderers.begin(); it != m_ForegroundRenderers.end(); it++)
{
(*it)->SetRenderWindow(renwin);
}
// Set the new RenderWindow
m_RenderWindow = renwin;
}
// Now sort renderers and add them to the renderwindow
UpdateLayers();
}
/**
* Returns true if a renderer has been inserted
*/
bool mitk::VtkLayerController::IsRendererInserted(vtkRenderer* renderer)
{
RendererVectorType::iterator it;
// background layers
if(m_BackgroundRenderers.size() > 0)
{
it = std::find(m_BackgroundRenderers.begin(),m_BackgroundRenderers.end(),renderer);
if ( it != m_BackgroundRenderers.end() )
{
return true;
}
}
// scene layers
if(m_SceneRenderers.size() > 0)
{
it = std::find(m_SceneRenderers.begin(),m_SceneRenderers.end(),renderer);
if ( it != m_SceneRenderers.end() )
{
return true;
}
}
// foreground layers
if(m_ForegroundRenderers.size() > 0 )
{
it = std::find(m_ForegroundRenderers.begin(),m_ForegroundRenderers.end(),renderer);
if ( it != m_ForegroundRenderers.end() )
{
return true;
}
}
return false;
}
/**
* Internally used to sort all registered renderers and to connect the with the vtkRenderWindow.
* Mention that VTK Version 5 and above is rendering higher numbers in the background and VTK
* Verison < 5 in the foreground.
*/
void mitk::VtkLayerController::UpdateLayers()
{
// Remove all Renderers from renderwindow
vtkRendererCollection* v = m_RenderWindow->GetRenderers();
v->RemoveAllItems();
unsigned int numberOfLayers = static_cast<unsigned int>(m_BackgroundRenderers.size() + m_SceneRenderers.size() + m_ForegroundRenderers.size());
int currentLayerNumber;
bool traverseUpwards;
currentLayerNumber = 0;
traverseUpwards = true;
m_RenderWindow->SetNumberOfLayers(numberOfLayers);
RendererVectorType::iterator it;
// assign a layer number for the backround renderers
for(it = m_BackgroundRenderers.begin(); it != m_BackgroundRenderers.end(); it++)
{
(*it)->SetRenderWindow(m_RenderWindow);
(*it)->SetLayer(currentLayerNumber);
m_RenderWindow->AddRenderer((*it));
if(traverseUpwards)
currentLayerNumber++;
else
currentLayerNumber--;
}
// assign a layer number for the scene renderers
for(it = m_SceneRenderers.begin(); it != m_SceneRenderers.end(); it++)
{
(*it)->SetRenderWindow(m_RenderWindow);
(*it)->SetLayer(currentLayerNumber);
m_RenderWindow->AddRenderer((*it));
if(traverseUpwards)
currentLayerNumber++;
else
currentLayerNumber--;
}
// assign a layer number for the foreground renderers
for(it = m_ForegroundRenderers.begin(); it != m_ForegroundRenderers.end(); it++)
{
(*it)->SetRenderWindow(m_RenderWindow);
(*it)->SetLayer(currentLayerNumber);
m_RenderWindow->AddRenderer((*it));
if(traverseUpwards)
currentLayerNumber++;
else
currentLayerNumber--;
}
}
/**
* Returns the number of renderers in the renderwindow.
*/
unsigned int mitk::VtkLayerController::GetNumberOfRenderers()
{
return static_cast<unsigned int>(m_BackgroundRenderers.size() + m_SceneRenderers.size() + m_ForegroundRenderers.size());
}
void mitk::VtkLayerController::SetEraseForAllRenderers(int i)
{
this->m_RenderWindow->SetErase(i);
RendererVectorType::iterator it;
for(it = m_BackgroundRenderers.begin(); it != m_BackgroundRenderers.end(); it++)
(*it)->SetErase(i);
for(it = m_SceneRenderers.begin(); it != m_SceneRenderers.end(); it++)
(*it)->SetErase(i);
for(it = m_ForegroundRenderers.begin(); it != m_ForegroundRenderers.end(); it++)
(*it)->SetErase(i);
}
diff --git a/Core/Code/Controllers/mitkVtkLayerController.h b/Core/Code/Controllers/mitkVtkLayerController.h
index c2b8d33d24..08b0e76bcc 100644
--- a/Core/Code/Controllers/mitkVtkLayerController.h
+++ b/Core/Code/Controllers/mitkVtkLayerController.h
@@ -1,135 +1,134 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D
#define MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D
#include <vector>
#include <map>
#include <MitkExports.h>
class vtkRenderWindow;
class vtkRenderer;
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4251)
#endif
/**
* Manages the VTK layer hierarchy
* of a vtkRenderWindow.
* For simple access the layers are divided into three
* main groups: background, scene and foreground layers.
* Renderers can be registered via the insert... functions and
* removed via the RemoveRenderer function.
*/
class MITK_CORE_EXPORT VtkLayerController
{
public:
static VtkLayerController* GetInstance(vtkRenderWindow* renWin);
static void AddInstance(vtkRenderWindow* renWin, vtkRenderer * mitkSceneRenderer);
static void RemoveInstance(vtkRenderWindow* renWin);
VtkLayerController(vtkRenderWindow* renderWindow);
virtual ~VtkLayerController();
/**
* Returns the current vtkRenderer of the Scene
*/
vtkRenderer* GetSceneRenderer();
/**
* Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the background.
* With forceAbsoluteBackground set true a renderer can be placed at the absolute background of the scene.
* Multiple calls with forceAbsoluteBackground set true will set the latest registered renderer as background.
*/
void InsertBackgroundRenderer(vtkRenderer* renderer, bool forceAbsoluteBackground);
/**
* Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the foreground.
* With forceAbsoluteBackground set true a renderer can be placed at the absolute foreground of the scene.
* Multiple calls with forceAbsoluteForeground set true will set the latest registered renderer as foreground.
*/
void InsertForegroundRenderer(vtkRenderer* renderer, bool forceAbsoluteForeground);
/**
* Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered between background renderers and
* foreground renderers.
*/
void InsertSceneRenderer(vtkRenderer* renderer);
/**
* Connects a VtkRenderWindow with the layer controller.
*/
void SetRenderWindow(vtkRenderWindow* renwin);
/**
* A renderer which has been inserted via a insert... function can be removed from the vtkRenderWindow with
* RemoveRenderer.
*/
void RemoveRenderer(vtkRenderer* renderer);
/**
* Returns true if a renderer has been inserted
*/
bool IsRendererInserted(vtkRenderer* renderer);
/**
* Returns the number of renderers in the renderwindow.
*/
unsigned int GetNumberOfRenderers();
void SetEraseForAllRenderers(int i);
protected:
vtkRenderWindow* m_RenderWindow;
private:
/**
* Internally used to sort all registered renderers and to connect the with the vtkRenderWindow.
* Mention that VTK Version 5 and above is rendering higher numbers in the background and VTK
* Verison < 5 in the foreground.
*/
void UpdateLayers();
// Layer Management
typedef std::vector<vtkRenderer*> RendererVectorType;
RendererVectorType m_BackgroundRenderers;
RendererVectorType m_SceneRenderers;
RendererVectorType m_ForegroundRenderers;
typedef std::map<const vtkRenderWindow*,mitk::VtkLayerController*> vtkLayerControllerMapType;
static vtkLayerControllerMapType s_LayerControllerMap;
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // Namespace MITK
#endif /* MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D */
diff --git a/Core/Code/DataManagement/itkVtkAbstractTransform.h b/Core/Code/DataManagement/itkVtkAbstractTransform.h
index 300fb95961..9add5bb56d 100644
--- a/Core/Code/DataManagement/itkVtkAbstractTransform.h
+++ b/Core/Code/DataManagement/itkVtkAbstractTransform.h
@@ -1,95 +1,94 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKVTKABSTRACTTRANSFORM_H_HEADER_INCLUDED_C1C68A2C
#define MITKVTKABSTRACTTRANSFORM_H_HEADER_INCLUDED_C1C68A2C
#include <MitkExports.h>
#include "itkTransform.h"
class vtkAbstractTransform;
namespace itk {
//##Documentation
//## @brief Adapter from vtkAbstractTransform to itk::Transform<TScalarType, 3, 3>
//## @ingroup Geometry
template <class TScalarType>
class VtkAbstractTransform : public itk::Transform<TScalarType, 3, 3>
{
public:
typedef VtkAbstractTransform Self;
typedef Transform< TScalarType, 3, 3 > Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
typedef typename Superclass::OutputPointType OutputPointType;
typedef typename Superclass::OutputVectorType OutputVectorType;
typedef typename Superclass::OutputVnlVectorType OutputVnlVectorType;
typedef typename Superclass::OutputCovariantVectorType OutputCovariantVectorType;
typedef typename Superclass::InputPointType InputPointType;
typedef typename Superclass::InputVectorType InputVectorType;
typedef typename Superclass::InputVnlVectorType InputVnlVectorType;
typedef typename Superclass::InputCovariantVectorType InputCovariantVectorType;
itkNewMacro(Self);
//##Documentation
//## @brief Get the vtkAbstractTransform (stored in m_VtkAbstractTransform)
virtual vtkAbstractTransform* GetVtkAbstractTransform() const;
//##Documentation
//## @brief Get the inverse vtkAbstractTransform (stored in m_InverseVtkAbstractTransform)
virtual vtkAbstractTransform* GetInverseVtkAbstractTransform() const;
//##Documentation
//## @brief Set the vtkAbstractTransform (stored in m_VtkAbstractTransform)
virtual void SetVtkAbstractTransform(vtkAbstractTransform* aVtkAbstractTransform);
virtual OutputPointType TransformPoint(const InputPointType & ) const;
virtual OutputVectorType TransformVector(const InputVectorType &) const;
virtual OutputVnlVectorType TransformVector(const InputVnlVectorType &) const;
virtual OutputCovariantVectorType TransformCovariantVector(const InputCovariantVectorType &) const;
virtual InputPointType BackTransform(const OutputPointType &point ) const;
virtual InputVectorType BackTransform(const OutputVectorType &vector) const;
virtual InputVnlVectorType BackTransform(const OutputVnlVectorType &vector) const;
virtual InputCovariantVectorType BackTransform(const OutputCovariantVectorType &vector) const;
virtual unsigned long GetMTime() const;
protected:
VtkAbstractTransform();
virtual ~VtkAbstractTransform();
//##Documentation
//## @brief Instance of the vtkAbstractTransform
vtkAbstractTransform* m_VtkAbstractTransform;
//##Documentation
//## @brief Instance of the vtkAbstractTransform
vtkAbstractTransform* m_InverseVtkAbstractTransform;
mutable unsigned long m_LastVtkAbstractTransformTimeStamp;
};
} // namespace itk
#ifndef MITK_MANUAL_INSTANTIATION
#include "itkVtkAbstractTransform.txx"
#endif
#endif /* MITKVTKABSTRACTTRANSFORM_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Core/Code/DataManagement/itkVtkAbstractTransform.txx b/Core/Code/DataManagement/itkVtkAbstractTransform.txx
index 26fa14010f..0e9cd36b76 100644
--- a/Core/Code/DataManagement/itkVtkAbstractTransform.txx
+++ b/Core/Code/DataManagement/itkVtkAbstractTransform.txx
@@ -1,228 +1,227 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "itkVtkAbstractTransform.h"
#include <vtkAbstractTransform.h>
#include <mitkVector.h>
namespace itk {
template <class TScalarType>
itk::VtkAbstractTransform<TScalarType>::VtkAbstractTransform() :
Superclass(3, 0),
m_VtkAbstractTransform(NULL), m_InverseVtkAbstractTransform(NULL),
m_LastVtkAbstractTransformTimeStamp(0)
{
}
template <class TScalarType>
itk::VtkAbstractTransform<TScalarType>::~VtkAbstractTransform()
{
if(m_VtkAbstractTransform!=NULL)
m_VtkAbstractTransform->UnRegister(NULL);
}
template <class TScalarType>
vtkAbstractTransform* itk::VtkAbstractTransform<TScalarType>::GetVtkAbstractTransform() const
{
return m_VtkAbstractTransform;
}
template <class TScalarType>
vtkAbstractTransform* itk::VtkAbstractTransform<TScalarType>::GetInverseVtkAbstractTransform() const
{
return m_InverseVtkAbstractTransform;
}
template <class TScalarType>
void itk::VtkAbstractTransform<TScalarType>::SetVtkAbstractTransform(vtkAbstractTransform* aVtkAbstractTransform)
{
if(m_VtkAbstractTransform==aVtkAbstractTransform)
return;
if(m_VtkAbstractTransform!=NULL)
m_VtkAbstractTransform->UnRegister(NULL);
m_VtkAbstractTransform=aVtkAbstractTransform;
if(m_VtkAbstractTransform!=NULL)
{
m_VtkAbstractTransform->Register(NULL);
m_InverseVtkAbstractTransform=m_VtkAbstractTransform->GetInverse(); // memory managed by m_VtkAbstractTransform
}
m_LastVtkAbstractTransformTimeStamp = m_VtkAbstractTransform->GetMTime();
this->Modified();
}
// Transform a point
template<class TScalarType>
typename itk::VtkAbstractTransform<TScalarType>::OutputPointType
itk::VtkAbstractTransform<TScalarType>::
TransformPoint(const InputPointType &point) const
{
assert(m_VtkAbstractTransform!=NULL);
OutputPointType outputpoint;
vnl_vector<TScalarType> vnl_vec;
float vtkpt[3];
mitk::itk2vtk(point, vtkpt);
m_VtkAbstractTransform->TransformPoint(vtkpt, vtkpt);
mitk::vtk2itk(vtkpt, outputpoint);
return outputpoint;
}
// Transform a vector
template<class TScalarType>
typename itk::VtkAbstractTransform<TScalarType>::OutputVectorType
itk::VtkAbstractTransform<TScalarType>::
TransformVector(const InputVectorType &vect) const
{
assert(m_VtkAbstractTransform!=NULL);
OutputVectorType outputvector;
vnl_vector<TScalarType> vnl_vec;
float vtkpt[3]={0,0,0};
float vtkvec[3];
mitk::vnl2vtk<TScalarType, float>(vect.Get_vnl_vector(), vtkvec);
m_VtkAbstractTransform->TransformVectorAtPoint(vtkpt, vtkvec, vtkvec);
mitk::vtk2itk(vtkvec, outputvector);
return outputvector;
}
// Transform a vnl_vector_fixed
template<class TScalarType>
typename itk::VtkAbstractTransform<TScalarType>::OutputVnlVectorType
itk::VtkAbstractTransform<TScalarType>::
TransformVector(const InputVnlVectorType &vect) const
{
assert(m_VtkAbstractTransform!=NULL);
OutputVnlVectorType outputvector;
float vtkpt[3]={0,0,0};
float vtkvec[3];
mitk::vnl2vtk<TScalarType, float>(vect, vtkvec);
m_VtkAbstractTransform->TransformVectorAtPoint(vtkpt, vtkvec, vtkvec);
mitk::vtk2itk(vtkvec, outputvector);
return outputvector;
}
// Transform a CovariantVector
template<class TScalarType>
typename itk::VtkAbstractTransform<TScalarType>::OutputCovariantVectorType
itk::VtkAbstractTransform<TScalarType>::
TransformCovariantVector(const InputCovariantVectorType &/*vec*/) const
{
itkExceptionMacro( << "implement before using!" );
OutputCovariantVectorType result; // Converted vector
// for (unsigned int i = 0; i < NDimensions; i++)
// {
// result[i] = NumericTraits<ScalarType>::Zero;
// for (unsigned int j = 0; j < NDimensions; j++)
// {
// result[i] += m_Inverse[j][i]*vec[j]; // Inverse transposed
// }
// }
return result;
}
// Back transform a point
template<class TScalarType>
typename VtkAbstractTransform<TScalarType>::InputPointType
itk::VtkAbstractTransform<TScalarType>::
BackTransform(const OutputPointType &point) const
{
assert(m_VtkAbstractTransform!=NULL);
OutputPointType outputpoint;
float vtkpt[3];
mitk::itk2vtk(point, vtkpt);
m_InverseVtkAbstractTransform->TransformPoint(vtkpt, vtkpt);
mitk::vtk2itk(vtkpt, outputpoint);
return outputpoint;
}
// Back transform a vector
template<class TScalarType>
typename VtkAbstractTransform<TScalarType>::InputVectorType
itk::VtkAbstractTransform<TScalarType>::
BackTransform(const OutputVectorType &vect ) const
{
assert(m_VtkAbstractTransform!=NULL);
OutputVectorType outputvector;
float vtkpt[3]={0,0,0};
float vtkvec[3];
mitk::itk2vtk(vect, vtkvec);
m_InverseVtkAbstractTransform->TransformVectorAtPoint(vtkpt, vtkvec, vtkvec);
mitk::vtk2itk(vtkvec, outputvector);
return outputvector;
}
// Back transform a vnl_vector
template<class TScalarType>
typename VtkAbstractTransform<TScalarType>::InputVnlVectorType
itk::VtkAbstractTransform<TScalarType>::
BackTransform(const OutputVnlVectorType &vect ) const
{
assert(m_InverseVtkAbstractTransform!=NULL);
OutputVnlVectorType outputvector;
float vtkpt[3]={0,0,0};
float vtkvec[3];
mitk::itk2vtk(vect, vtkvec);
m_InverseVtkAbstractTransform->TransformVectorAtPoint(vtkpt, vtkvec, vtkvec);
mitk::vtk2itk(vtkvec, outputvector);
return outputvector;
}
// Back Transform a CovariantVector
template<class TScalarType>
typename VtkAbstractTransform<TScalarType>::InputCovariantVectorType
itk::VtkAbstractTransform<TScalarType>::
BackTransform(const OutputCovariantVectorType &vec) const
{
itkExceptionMacro( << "implement before using!" );
// for (unsigned int i = 0; i < NDimensions; i++)
// {
// result[i] = NumericTraits<ScalarType>::Zero;
// for (unsigned int j = 0; j < NDimensions; j++)
// {
// result[i] += m_Matrix[j][i]*vec[j]; // Direct matrix transposed
// }
// }
return vec;
}
template<class TScalarType>
unsigned long
itk::VtkAbstractTransform<TScalarType>::GetMTime() const
{
if((m_VtkAbstractTransform != NULL) && (m_LastVtkAbstractTransformTimeStamp < m_VtkAbstractTransform->GetMTime()))
{
m_LastVtkAbstractTransformTimeStamp=m_VtkAbstractTransform->GetMTime();
this->Modified();
}
return Superclass::GetMTime();
}
} // namespace itk
diff --git a/Core/Code/DataManagement/mitkAbstractTransformGeometry.cpp b/Core/Code/DataManagement/mitkAbstractTransformGeometry.cpp
index 1c611ef8a2..f7032e131b 100644
--- a/Core/Code/DataManagement/mitkAbstractTransformGeometry.cpp
+++ b/Core/Code/DataManagement/mitkAbstractTransformGeometry.cpp
@@ -1,263 +1,262 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkAbstractTransformGeometry.h"
#include <vtkAbstractTransform.h>
mitk::AbstractTransformGeometry::AbstractTransformGeometry() : m_Plane(NULL), m_FrameGeometry(NULL)
{
Initialize();
}
mitk::AbstractTransformGeometry::AbstractTransformGeometry(const AbstractTransformGeometry& other) : Superclass(other)
{
if(other.m_ParametricBoundingBox.IsNotNull())
{
this->SetParametricBounds(m_ParametricBoundingBox->GetBounds());
}
this->SetPlane(other.m_Plane);
this->SetFrameGeometry(other.m_FrameGeometry);
}
mitk::AbstractTransformGeometry::~AbstractTransformGeometry()
{
}
void mitk::AbstractTransformGeometry::Initialize()
{
Superclass::Initialize();
m_ItkVtkAbstractTransform = itk::VtkAbstractTransform<ScalarType>::New();
}
vtkAbstractTransform* mitk::AbstractTransformGeometry::GetVtkAbstractTransform() const
{
return m_ItkVtkAbstractTransform->GetVtkAbstractTransform();
}
mitk::ScalarType mitk::AbstractTransformGeometry::GetParametricExtentInMM(int direction) const
{
if(m_Plane.IsNull())
{
itkExceptionMacro(<<"m_Plane is NULL.");
}
return m_Plane->GetExtentInMM(direction);
}
const mitk::Transform3D* mitk::AbstractTransformGeometry::GetParametricTransform() const
{
return m_ItkVtkAbstractTransform;
}
bool mitk::AbstractTransformGeometry::Project(const mitk::Point3D &pt3d_mm, mitk::Point3D &projectedPt3d_mm) const
{
assert(m_BoundingBox.IsNotNull());
mitk::Point2D pt2d_mm;
bool isInside;
isInside = Map(pt3d_mm, pt2d_mm);
Map(pt2d_mm, projectedPt3d_mm);
return isInside;
//Point3D pt3d_units;
//pt3d_units = m_ItkVtkAbstractTransform->BackTransform(pt3d_mm);
//pt3d_units[2] = 0;
//projectedPt3d_mm = m_ItkVtkAbstractTransform->TransformPoint(pt3d_units);
//return const_cast<BoundingBox*>(m_BoundingBox.GetPointer())->IsInside(pt3d_units);
}
bool mitk::AbstractTransformGeometry::Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
{
assert((m_ItkVtkAbstractTransform.IsNotNull()) && (m_Plane.IsNotNull()));
Point3D pt3d_units;
pt3d_units = m_ItkVtkAbstractTransform->BackTransform(pt3d_mm);
return m_Plane->Map(pt3d_units, pt2d_mm);
}
void mitk::AbstractTransformGeometry::Map(const mitk::Point2D &pt2d_mm, mitk::Point3D &pt3d_mm) const
{
assert((m_ItkVtkAbstractTransform.IsNotNull()) && (m_Plane.IsNotNull()));
m_Plane->Map(pt2d_mm, pt3d_mm);
pt3d_mm = m_ItkVtkAbstractTransform->TransformPoint(pt3d_mm);
}
bool mitk::AbstractTransformGeometry::Project(const mitk::Point3D & atPt3d_mm, const mitk::Vector3D &vec3d_mm, mitk::Vector3D &projectedVec3d_mm) const
{
itkExceptionMacro("not implemented yet - replace GetIndexToWorldTransform by m_ItkVtkAbstractTransform->GetInverseVtkAbstractTransform()");
assert(m_BoundingBox.IsNotNull());
Vector3D vec3d_units;
vec3d_units = GetIndexToWorldTransform()->BackTransform(vec3d_mm);
vec3d_units[2] = 0;
projectedVec3d_mm = GetIndexToWorldTransform()->TransformVector(vec3d_units);
Point3D pt3d_units;
pt3d_units = GetIndexToWorldTransform()->BackTransformPoint(atPt3d_mm);
return const_cast<BoundingBox*>(m_BoundingBox.GetPointer())->IsInside(pt3d_units);
}
bool mitk::AbstractTransformGeometry::Map(const mitk::Point3D & atPt3d_mm, const mitk::Vector3D &vec3d_mm, mitk::Vector2D &vec2d_mm) const
{
assert((m_ItkVtkAbstractTransform.IsNotNull()) && (m_Plane.IsNotNull()));
float vtkpt[3], vtkvec[3];
itk2vtk(atPt3d_mm, vtkpt);
itk2vtk(vec3d_mm, vtkvec);
m_ItkVtkAbstractTransform->GetInverseVtkAbstractTransform()->TransformVectorAtPoint(vtkpt, vtkvec, vtkvec);
mitk::Vector3D vec3d_units;
vtk2itk(vtkvec, vec3d_units);
return m_Plane->Map(atPt3d_mm, vec3d_units, vec2d_mm);
}
void mitk::AbstractTransformGeometry::Map(const mitk::Point2D & atPt2d_mm, const mitk::Vector2D &vec2d_mm, mitk::Vector3D &vec3d_mm) const
{
m_Plane->Map(atPt2d_mm, vec2d_mm, vec3d_mm);
Point3D atPt3d_mm;
Map(atPt2d_mm, atPt3d_mm);
float vtkpt[3], vtkvec[3];
itk2vtk(atPt3d_mm, vtkpt);
itk2vtk(vec3d_mm, vtkvec);
m_ItkVtkAbstractTransform->GetVtkAbstractTransform()->TransformVectorAtPoint(vtkpt, vtkvec, vtkvec);
vtk2itk(vtkvec, vec3d_mm);
}
void mitk::AbstractTransformGeometry::IndexToWorld(const mitk::Point2D &pt_units, mitk::Point2D &pt_mm) const
{
m_Plane->IndexToWorld(pt_units, pt_mm);
}
void mitk::AbstractTransformGeometry::WorldToIndex(const mitk::Point2D &pt_mm, mitk::Point2D &pt_units) const
{
m_Plane->WorldToIndex(pt_mm, pt_units);
}
void mitk::AbstractTransformGeometry::IndexToWorld(const mitk::Point2D & /*atPt2d_units*/, const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const
{
MITK_WARN<<"Warning! Call of the deprecated function AbstractTransformGeometry::IndexToWorld(point, vec, vec). Use AbstractTransformGeometry::IndexToWorld(vec, vec) instead!";
this->IndexToWorld(vec_units, vec_mm);
}
void mitk::AbstractTransformGeometry::IndexToWorld(const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const
{
m_Plane->IndexToWorld(vec_units, vec_mm);
}
void mitk::AbstractTransformGeometry::WorldToIndex(const mitk::Point2D & /*atPt2d_mm*/, const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const
{
MITK_WARN<<"Warning! Call of the deprecated function AbstractTransformGeometry::WorldToIndex(point, vec, vec). Use AbstractTransformGeometry::WorldToIndex(vec, vec) instead!";
this->WorldToIndex(vec_mm, vec_units);
}
void mitk::AbstractTransformGeometry::WorldToIndex(const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const
{
m_Plane->WorldToIndex(vec_mm, vec_units);
}
bool mitk::AbstractTransformGeometry::IsAbove(const mitk::Point3D& pt3d_mm) const
{
assert((m_ItkVtkAbstractTransform.IsNotNull()) && (m_Plane.IsNotNull()));
Point3D pt3d_ParametricWorld;
pt3d_ParametricWorld = m_ItkVtkAbstractTransform->BackTransform(pt3d_mm);
Point3D pt3d_ParametricUnits;
((Geometry3D*)m_Plane)->WorldToIndex(pt3d_ParametricWorld, pt3d_ParametricUnits);
return (pt3d_ParametricUnits[2] > m_ParametricBoundingBox->GetBounds()[4]);
}
void mitk::AbstractTransformGeometry::SetVtkAbstractTransform(vtkAbstractTransform* aVtkAbstractTransform)
{
m_ItkVtkAbstractTransform->SetVtkAbstractTransform(aVtkAbstractTransform);
}
void mitk::AbstractTransformGeometry::SetPlane(const mitk::PlaneGeometry* aPlane)
{
if(aPlane!=NULL)
{
m_Plane = static_cast<mitk::PlaneGeometry*>(aPlane->Clone().GetPointer());
BoundingBox::BoundsArrayType b=m_Plane->GetBoundingBox()->GetBounds();
SetParametricBounds(b);
CalculateFrameGeometry();
}
else
{
if(m_Plane.IsNull())
return;
m_Plane=NULL;
}
Modified();
}
void mitk::AbstractTransformGeometry::CalculateFrameGeometry()
{
if((m_Plane.IsNull()) || (m_FrameGeometry.IsNotNull()))
return;
//@warning affine-transforms and bounding-box should be set by specific sub-classes!
SetBounds(m_Plane->GetBoundingBox()->GetBounds());
}
void mitk::AbstractTransformGeometry::SetFrameGeometry(const mitk::Geometry3D* frameGeometry)
{
if((frameGeometry != NULL) && (frameGeometry->IsValid()))
{
m_FrameGeometry = static_cast<mitk::Geometry3D*>(frameGeometry->Clone().GetPointer());
SetIndexToWorldTransform(m_FrameGeometry->GetIndexToWorldTransform());
SetBounds(m_FrameGeometry->GetBounds());
}
else
{
m_FrameGeometry = NULL;
}
}
unsigned long mitk::AbstractTransformGeometry::GetMTime() const
{
if(Superclass::GetMTime()<m_ItkVtkAbstractTransform->GetMTime())
return m_ItkVtkAbstractTransform->GetMTime();
return Superclass::GetMTime();
}
void mitk::AbstractTransformGeometry::SetOversampling(float oversampling)
{
if(m_Plane.IsNull())
{
itkExceptionMacro(<< "m_Plane is not set.");
}
mitk::BoundingBox::BoundsArrayType bounds = m_Plane->GetBounds();
bounds[1]*=oversampling; bounds[3]*=oversampling; bounds[5]*=oversampling;
SetParametricBounds(bounds);
}
mitk::AffineGeometryFrame3D::Pointer mitk::AbstractTransformGeometry::Clone() const
{
Self::Pointer newGeometry = new AbstractTransformGeometry(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
diff --git a/Core/Code/DataManagement/mitkAbstractTransformGeometry.h b/Core/Code/DataManagement/mitkAbstractTransformGeometry.h
index e04caf4e1f..cfe723f524 100644
--- a/Core/Code/DataManagement/mitkAbstractTransformGeometry.h
+++ b/Core/Code/DataManagement/mitkAbstractTransformGeometry.h
@@ -1,180 +1,179 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKVTKABSTRACTTRANSFORMPLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#define MITKVTKABSTRACTTRANSFORMPLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#include <MitkExports.h>
#include "mitkGeometry2D.h"
#include "mitkPlaneGeometry.h"
#include "itkVtkAbstractTransform.h"
class vtkAbstractTransform;
namespace mitk {
//##Documentation
//## @brief Describes a geometry defined by an vtkAbstractTransform and a plane
//##
//## vtkAbstractTransform is the most general transform in vtk (superclass for
//## all vtk geometric transformations). It defines an arbitrary 3D transformation,
//## i.e., a transformation of 3D space into 3D space. In contrast,
//## AbstractTransformGeometry (since it is a subclass of Geometry2D) describes a
//## 2D manifold in 3D space. The 2D manifold is defined as the manifold that results
//## from transforming a rectangle (given in m_Plane as a PlaneGeometry) by the
//## vtkAbstractTransform (given in m_VtkAbstractTransform).
//## The PlaneGeometry m_Plane is used to define the parameter space. 2D coordinates are
//## first mapped by the PlaneGeometry and the resulting 3D coordinates are put into
//## the vtkAbstractTransform.
//## @note This class is the superclass of concrete geometries. Since there is no
//## write access to the vtkAbstractTransform and m_Plane, this class is somehow
//## abstract. For full write access from extern, use ExternAbstractTransformGeometry.
//## @note The bounds of the PlaneGeometry are used as the parametric bounds.
//## @sa ExternAbstractTransformGeometry
//## @ingroup Geometry
class MITK_CORE_EXPORT AbstractTransformGeometry : public Geometry2D
{
public:
mitkClassMacro(AbstractTransformGeometry, Geometry2D);
itkNewMacro(Self);
//##Documentation
//## @brief Get the vtkAbstractTransform (stored in m_VtkAbstractTransform)
virtual vtkAbstractTransform* GetVtkAbstractTransform() const;
virtual unsigned long GetMTime() const;
//##Documentation
//## @brief Get the rectangular area that is used for transformation by
//## m_VtkAbstractTransform and therewith defines the 2D manifold described by
//## AbstractTransformGeometry
itkGetConstObjectMacro(Plane, PlaneGeometry);
virtual bool Project(const mitk::Point3D &pt3d_mm, mitk::Point3D &projectedPt3d_mm) const;
virtual bool Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const;
virtual void Map(const mitk::Point2D &pt2d_mm, mitk::Point3D &pt3d_mm) const;
virtual bool Project(const mitk::Point3D & atPt3d_mm, const mitk::Vector3D &vec3d_mm, mitk::Vector3D &projectedVec3d_mm) const;
virtual bool Map(const mitk::Point3D & atPt3d_mm, const mitk::Vector3D &vec3d_mm, mitk::Vector2D &vec2d_mm) const;
virtual void Map(const mitk::Point2D & atPt2d_mm, const mitk::Vector2D &vec2d_mm, mitk::Vector3D &vec3d_mm) const;
virtual void IndexToWorld(const mitk::Point2D &pt_units, mitk::Point2D &pt_mm) const;
virtual void WorldToIndex(const mitk::Point2D &pt_mm, mitk::Point2D &pt_units) const;
//##Documentation
//## @brief Convert (continuous or discrete) index coordinates of a \em vector
//## \a vec_units to world coordinates (in mm)
//## @deprecated First parameter (Point2D) is not used. If possible, please use void IndexToWorld(const mitk::Vector2D& vec_units, mitk::Vector2D& vec_mm) const.
//## For further information about coordinates types, please see the Geometry documentation
virtual void IndexToWorld(const mitk::Point2D &atPt2d_units, const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const;
//##Documentation
//## @brief Convert (continuous or discrete) index coordinates of a \em vector
//## \a vec_units to world coordinates (in mm)
//## For further information about coordinates types, please see the Geometry documentation
virtual void IndexToWorld(const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const;
//##Documentation
//## @brief Convert world coordinates (in mm) of a \em vector
//## \a vec_mm to (continuous!) index coordinates.
//## @deprecated First parameter (Point2D) is not used. If possible, please use void WorldToIndex(const mitk::Vector2D& vec_mm, mitk::Vector2D& vec_units) const.
//## For further information about coordinates types, please see the Geometry documentation
virtual void WorldToIndex(const mitk::Point2D &atPt2d_mm, const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const;
//##Documentation
//## @brief Convert world coordinates (in mm) of a \em vector
//## \a vec_mm to (continuous!) index coordinates.
//## For further information about coordinates types, please see the Geometry documentation
virtual void WorldToIndex(const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const;
virtual bool IsAbove(const Point3D& pt3d_mm) const;
virtual mitk::ScalarType GetParametricExtentInMM(int direction) const;
virtual const Transform3D* GetParametricTransform() const;
//##Documentation
//## @brief Change the parametric bounds to @a oversampling times
//## the bounds of m_Plane.
//##
//## The change is done once (immediately). Later changes of the bounds
//## of m_Plane will not influence the parametric bounds. (Consequently,
//## there is no method to get the oversampling.)
virtual void SetOversampling(float oversampling);
virtual void Initialize();
//##Documentation
//## @brief Calculates the standard part of a Geometry3D
//## (IndexToWorldTransform and bounding box) around the
//## curved geometry. Has to be implemented in subclasses.
//##
//## \sa SetFrameGeometry
virtual void CalculateFrameGeometry();
//##Documentation
//## @brief Set the frame geometry which is used as the standard
//## part of an Geometry3D (IndexToWorldTransform and bounding box)
//##
//## Maybe used as a hint within which the interpolation shall occur
//## by concrete sub-classes.
//## \sa CalculateFrameGeometry
virtual void SetFrameGeometry(const mitk::Geometry3D* frameGeometry);
virtual AffineGeometryFrame3D::Pointer Clone() const;
protected:
AbstractTransformGeometry();
AbstractTransformGeometry(const AbstractTransformGeometry& other);
virtual ~AbstractTransformGeometry();
//##Documentation
//## @brief Set the vtkAbstractTransform (stored in m_VtkAbstractTransform)
//##
//## Protected in this class, made public in ExternAbstractTransformGeometry.
virtual void SetVtkAbstractTransform(vtkAbstractTransform* aVtkAbstractTransform);
//##Documentation
//## @brief Set the rectangular area that is used for transformation by
//## m_VtkAbstractTransform and therewith defines the 2D manifold described by
//## ExternAbstractTransformGeometry
//##
//## Protected in this class, made public in ExternAbstractTransformGeometry.
//## @note The bounds of the PlaneGeometry are used as the parametric bounds.
//## @note The PlaneGeometry is cloned, @em not linked/referenced.
virtual void SetPlane(const mitk::PlaneGeometry* aPlane);
//##Documentation
//## @brief The rectangular area that is used for transformation by
//## m_VtkAbstractTransform and therewith defines the 2D manifold described by
//## AbstractTransformGeometry.
mitk::PlaneGeometry::Pointer m_Plane;
itk::VtkAbstractTransform<ScalarType>::Pointer m_ItkVtkAbstractTransform;
mitk::Geometry3D::Pointer m_FrameGeometry;
};
} // namespace mitk
#endif /* MITKVTKABSTRACTTRANSFORMPLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Core/Code/DataManagement/mitkAnnotationProperty.cpp b/Core/Code/DataManagement/mitkAnnotationProperty.cpp
index 6fd1622acc..c4948ce019 100644
--- a/Core/Code/DataManagement/mitkAnnotationProperty.cpp
+++ b/Core/Code/DataManagement/mitkAnnotationProperty.cpp
@@ -1,107 +1,106 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $
-Version: $Revision: 14081 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkAnnotationProperty.h"
mitk::AnnotationProperty::AnnotationProperty()
{
}
mitk::AnnotationProperty::AnnotationProperty(
const char *label, const Point3D &position )
: m_Label( "" ),
m_Position( position )
{
if ( label != NULL )
{
m_Label = label;
}
}
mitk::AnnotationProperty::AnnotationProperty(
const std::string &label, const Point3D &position )
: m_Label( label ),
m_Position( position )
{
}
mitk::AnnotationProperty::AnnotationProperty(
const char *label, ScalarType x, ScalarType y, ScalarType z )
: m_Label( "" )
{
if ( label != NULL )
{
m_Label = label;
}
m_Position[0] = x;
m_Position[1] = y;
m_Position[2] = z;
}
mitk::AnnotationProperty::AnnotationProperty(
const std::string &label, ScalarType x, ScalarType y, ScalarType z )
: m_Label( label )
{
m_Position[0] = x;
m_Position[1] = y;
m_Position[2] = z;
}
const mitk::Point3D &mitk::AnnotationProperty::GetPosition() const
{
return m_Position;
}
void mitk::AnnotationProperty::SetPosition( const mitk::Point3D &position )
{
if (m_Position != position)
{
m_Position = position;
this->Modified();
}
}
bool mitk::AnnotationProperty::IsEqual( const BaseProperty &property ) const
{
return ( (this->m_Label == static_cast<const Self&>(property).m_Label )
&& (this->m_Position == static_cast<const Self&>(property).m_Position ) );
}
bool mitk::AnnotationProperty::Assign( const BaseProperty &property )
{
this->m_Label = static_cast<const Self&>(property).m_Label;
this->m_Position = static_cast<const Self&>(property).m_Position;
return true;
}
std::string mitk::AnnotationProperty::GetValueAsString() const
{
std::stringstream myStr;
myStr << this->GetLabel() << this->GetPosition();
return myStr.str();
}
diff --git a/Core/Code/DataManagement/mitkAnnotationProperty.h b/Core/Code/DataManagement/mitkAnnotationProperty.h
index 82c9de37b2..4a414d9bee 100644
--- a/Core/Code/DataManagement/mitkAnnotationProperty.h
+++ b/Core/Code/DataManagement/mitkAnnotationProperty.h
@@ -1,87 +1,86 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $
-Version: $Revision: 14081 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKANNOTATIONPROPERTY_H_HEADER_INCLUDED
#define MITKANNOTATIONPROPERTY_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkBaseProperty.h"
#include "mitkVector.h"
#include <itkConfigure.h>
#include <string>
namespace mitk {
/**
* \brief Property for annotations
* \ingroup DataManagement
*/
class MITK_CORE_EXPORT AnnotationProperty : public BaseProperty
{
public:
mitkClassMacro(AnnotationProperty, BaseProperty);
typedef std::string ValueType;
itkNewMacro( AnnotationProperty );
mitkNewMacro2Param( AnnotationProperty,
const char *, const Point3D & );
mitkNewMacro2Param( AnnotationProperty,
const std::string &, const Point3D & );
mitkNewMacro4Param( AnnotationProperty,
const char *, ScalarType, ScalarType, ScalarType );
mitkNewMacro4Param( AnnotationProperty,
const std::string &, ScalarType, ScalarType, ScalarType );
itkGetStringMacro( Label );
itkSetStringMacro( Label );
const Point3D &GetPosition() const;
void SetPosition( const Point3D &position );
virtual std::string GetValueAsString() const;
virtual BaseProperty& operator=(const BaseProperty& other) { return Superclass::operator=(other); } \
protected:
std::string m_Label;
Point3D m_Position;
AnnotationProperty();
AnnotationProperty( const char *label, const Point3D &position );
AnnotationProperty( const std::string &label, const Point3D &position );
AnnotationProperty( const char *label, ScalarType x, ScalarType y, ScalarType z );
AnnotationProperty( const std::string &label, ScalarType x, ScalarType y, ScalarType z );
private:
// purposely not implemented
AnnotationProperty(const AnnotationProperty&);
AnnotationProperty& operator=(const AnnotationProperty&);
virtual bool IsEqual(const BaseProperty& property) const;
virtual bool Assign(const BaseProperty & property);
};
} // namespace mitk
#endif /* MITKANNOTATIONPROPERTY_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkApplicationCursor.cpp b/Core/Code/DataManagement/mitkApplicationCursor.cpp
index 5a7d2d85f8..2af3f89555 100644
--- a/Core/Code/DataManagement/mitkApplicationCursor.cpp
+++ b/Core/Code/DataManagement/mitkApplicationCursor.cpp
@@ -1,100 +1,99 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkApplicationCursor.h"
#include <mitkLogMacros.h>
#include <iostream>
mitk::ApplicationCursorImplementation* mitk::ApplicationCursor::m_Implementation = NULL;
namespace mitk {
ApplicationCursor::ApplicationCursor()
{
}
ApplicationCursor* ApplicationCursor::GetInstance()
{
static ApplicationCursor* m_Instance = NULL;
if (!m_Instance)
{
m_Instance = new ApplicationCursor();
}
return m_Instance;
}
void ApplicationCursor::RegisterImplementation(ApplicationCursorImplementation* implementation)
{
m_Implementation = implementation;
}
void ApplicationCursor::PushCursor(const char* XPM[], int hotspotX, int hotspotY)
{
if (m_Implementation)
{
m_Implementation->PushCursor(XPM, hotspotX, hotspotY);
}
else
{
MITK_ERROR << "in mitk::ApplicationCursor::PushCursor(): no implementation registered." << std::endl;
throw std::logic_error("No implementation registered for mitk::ApplicationCursor.");
}
}
void ApplicationCursor::PopCursor()
{
if (m_Implementation)
{
m_Implementation->PopCursor();
}
else
{
MITK_ERROR << "in mitk::ApplicationCursor::PopCursor(): no implementation registered." << std::endl;
throw std::logic_error("No implementation registered for mitk::ApplicationCursor.");
}
}
const Point2I ApplicationCursor::GetCursorPosition()
{
if (m_Implementation)
{
return m_Implementation->GetCursorPosition();
}
else
{
MITK_ERROR << "in mitk::ApplicationCursor::GetCursorPosition(): no implementation registered." << std::endl;
throw std::logic_error("No implementation registered for mitk::ApplicationCursor.");
}
}
void ApplicationCursor::SetCursorPosition(const Point2I& p)
{
if (m_Implementation)
{
m_Implementation->SetCursorPosition(p);
}
else
{
MITK_ERROR << "in mitk::ApplicationCursor::SetCursorPosition(): no implementation registered." << std::endl;
throw std::logic_error("No implementation registered for mitk::ApplicationCursor.");
}
}
} // namespace
diff --git a/Core/Code/DataManagement/mitkApplicationCursor.h b/Core/Code/DataManagement/mitkApplicationCursor.h
index d69283ab14..ee9940c027 100644
--- a/Core/Code/DataManagement/mitkApplicationCursor.h
+++ b/Core/Code/DataManagement/mitkApplicationCursor.h
@@ -1,104 +1,103 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 MITK_APPLICATION_CURSOR_H_DEFINED_AND_ALL_IS_GOOD
#define MITK_APPLICATION_CURSOR_H_DEFINED_AND_ALL_IS_GOOD
#include <MitkExports.h>
#include "mitkVector.h"
namespace mitk
{
/*!
\brief Toolkit specific implementation of mitk::ApplicationCursor
For any toolkit, this class has to be sub-classed. One instance of that sub-class has to
be registered with mitk::ApplicationCursor. See the (very simple) implmentation of
QmitkApplicationCursor for an example.
*/
class MITK_CORE_EXPORT ApplicationCursorImplementation
{
public:
/// Change the current application cursor
virtual void PushCursor(const char* XPM[], int hotspotX, int hotspotY) = 0;
/// Restore the previous cursor
virtual void PopCursor() = 0;
/// Get absolute mouse position on screen
virtual const Point2I GetCursorPosition() = 0;
/// Set absolute mouse position on screen
virtual void SetCursorPosition(const Point2I&) = 0;
virtual ~ApplicationCursorImplementation() {};
protected:
private:
};
/*!
\brief Allows to override the application's cursor.
Base class for classes that allow to override the applications cursor with context dependent
cursors. Accepts cursors in the XPM format.
The behaviour is stack-like. You can push your cursor on top of the stack and later pop it to
reset the cursor to its former state. This is mimicking Qt's Application::setOverrideCuror()
behaviour, but should be ok for most cases where you want to switch a cursor.
*/
class MITK_CORE_EXPORT ApplicationCursor
{
public:
/// This class is a singleton.
static ApplicationCursor* GetInstance();
/// To be called by a toolkit specific ApplicationCursorImplementation.
static void RegisterImplementation(ApplicationCursorImplementation* implementation);
/// Change the current application cursor
void PushCursor(const char* XPM[], int hotspotX = -1, int hotspotY = -1);
/// Restore the previous cursor
void PopCursor();
/// Get absolute mouse position on screen
/// \return (-1, -1) if querying mouse position is not possible
const Point2I GetCursorPosition();
/// Set absolute mouse position on screen
void SetCursorPosition(const Point2I&);
protected:
/// Purposely hidden - singleton
ApplicationCursor();
private:
static ApplicationCursorImplementation* m_Implementation;
};
} // namespace
#endif
diff --git a/Core/Code/DataManagement/mitkBaseData.cpp b/Core/Code/DataManagement/mitkBaseData.cpp
index f7da7c69a6..915c856888 100644
--- a/Core/Code/DataManagement/mitkBaseData.cpp
+++ b/Core/Code/DataManagement/mitkBaseData.cpp
@@ -1,363 +1,362 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkBaseData.h"
#include <itkObjectFactoryBase.h>
#define MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
mitk::BaseData::BaseData() :
m_RequestedRegionInitialized(false), m_SmartSourcePointer(NULL),
m_SourceOutputIndexDuplicate(0), m_Initialized(true),
m_Unregistering(false), m_CalculatingExternalReferenceCount(false),
m_ExternalReferenceCount(-1)
{
m_TimeSlicedGeometry = TimeSlicedGeometry::New();
m_PropertyList = PropertyList::New();
}
mitk::BaseData::BaseData( const BaseData &other ):
itk::DataObject(), mitk::OperationActor(),
m_RequestedRegionInitialized(other.m_RequestedRegionInitialized),
m_SmartSourcePointer(other.m_SmartSourcePointer),
m_SourceOutputIndexDuplicate(other.m_SourceOutputIndexDuplicate),
m_Initialized(other.m_Initialized), m_Unregistering(other.m_Unregistering),
m_CalculatingExternalReferenceCount(other.m_CalculatingExternalReferenceCount),
m_ExternalReferenceCount(other.m_ExternalReferenceCount)
{
m_TimeSlicedGeometry = dynamic_cast<mitk::TimeSlicedGeometry*>(other.m_TimeSlicedGeometry->Clone().GetPointer());
m_PropertyList = other.m_PropertyList->Clone();
}
mitk::BaseData::~BaseData()
{
m_SmartSourcePointer = NULL;
}
void mitk::BaseData::InitializeTimeSlicedGeometry(unsigned int timeSteps)
{
mitk::TimeSlicedGeometry::Pointer timeGeometry = this->GetTimeSlicedGeometry();
mitk::Geometry3D::Pointer g3d = mitk::Geometry3D::New();
g3d->Initialize();
if ( timeSteps > 1 )
{
mitk::ScalarType timeBounds[] = {0.0, 1.0};
g3d->SetTimeBounds( timeBounds );
}
// The geometry is propagated automatically to the other items,
// if EvenlyTimed is true...
timeGeometry->InitializeEvenlyTimed( g3d.GetPointer(), timeSteps );
}
void mitk::BaseData::UpdateOutputInformation()
{
if ( this->GetSource() )
{
this->GetSource()->UpdateOutputInformation();
}
if(m_TimeSlicedGeometry.IsNotNull())
m_TimeSlicedGeometry->UpdateInformation();
}
const mitk::TimeSlicedGeometry* mitk::BaseData::GetUpdatedTimeSlicedGeometry()
{
SetRequestedRegionToLargestPossibleRegion();
UpdateOutputInformation();
return GetTimeSlicedGeometry();
}
void mitk::BaseData::Expand( unsigned int timeSteps )
{
if( m_TimeSlicedGeometry.IsNotNull() )
m_TimeSlicedGeometry->ExpandToNumberOfTimeSteps( timeSteps );
}
const mitk::Geometry3D* mitk::BaseData::GetUpdatedGeometry(int t)
{
SetRequestedRegionToLargestPossibleRegion();
UpdateOutputInformation();
return GetGeometry(t);
}
void mitk::BaseData::SetGeometry(Geometry3D* aGeometry3D)
{
if(aGeometry3D!=NULL)
{
TimeSlicedGeometry::Pointer timeSlicedGeometry = dynamic_cast<TimeSlicedGeometry*>(aGeometry3D);
if ( timeSlicedGeometry.IsNotNull() )
m_TimeSlicedGeometry = timeSlicedGeometry;
else
{
timeSlicedGeometry = TimeSlicedGeometry::New();
m_TimeSlicedGeometry = timeSlicedGeometry;
timeSlicedGeometry->InitializeEvenlyTimed(aGeometry3D, 1);
}
Modified();
}
else if( m_TimeSlicedGeometry.IsNotNull() )
{
m_TimeSlicedGeometry = NULL;
Modified();
}
return;
}
void mitk::BaseData::SetClonedGeometry(const Geometry3D* aGeometry3D)
{
SetGeometry(static_cast<mitk::Geometry3D*>(aGeometry3D->Clone().GetPointer()));
}
void mitk::BaseData::SetClonedGeometry(const Geometry3D* aGeometry3D, unsigned int time)
{
if (m_TimeSlicedGeometry)
{
m_TimeSlicedGeometry->SetGeometry3D(static_cast<mitk::Geometry3D*>(aGeometry3D->Clone().GetPointer()), time);
}
}
bool mitk::BaseData::IsEmptyTimeStep(unsigned int) const
{
return IsInitialized() == false;
}
bool mitk::BaseData::IsEmpty() const
{
if(IsInitialized() == false)
return true;
const TimeSlicedGeometry* timeGeometry = const_cast<BaseData*>(this)->GetUpdatedTimeSlicedGeometry();
if(timeGeometry == NULL)
return true;
unsigned int timeSteps = timeGeometry->GetTimeSteps();
for ( unsigned int t = 0 ; t < timeSteps ; ++t )
{
if(IsEmptyTimeStep(t) == false)
return false;
}
return true;
}
itk::SmartPointer<mitk::BaseProcess> mitk::BaseData::GetSource() const
{
return static_cast<mitk::BaseProcess*>(Superclass::GetSource().GetPointer());
}
int mitk::BaseData::GetExternalReferenceCount() const
{
if(m_CalculatingExternalReferenceCount==false) //this is only needed because a smart-pointer to m_Outputs (private!!) must be created by calling GetOutputs.
{
m_CalculatingExternalReferenceCount = true;
m_ExternalReferenceCount = -1;
int realReferenceCount = GetReferenceCount();
if(GetSource().IsNull())
{
m_ExternalReferenceCount = realReferenceCount;
m_CalculatingExternalReferenceCount = false;
return m_ExternalReferenceCount;
}
mitk::BaseProcess::DataObjectPointerArray outputs = m_SmartSourcePointer->GetOutputs();
unsigned int idx;
for (idx = 0; idx < outputs.size(); ++idx)
{
//references of outputs that are not referenced from someone else (reference additional to the reference from this BaseProcess object) are interpreted as non-existent
if(outputs[idx]==this)
--realReferenceCount;
}
m_ExternalReferenceCount = realReferenceCount;
if(m_ExternalReferenceCount<0)
m_ExternalReferenceCount=0;
m_CalculatingExternalReferenceCount = false;
}
else
return -1;
return m_ExternalReferenceCount;
}
void mitk::BaseData::UnRegister() const
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
if(GetReferenceCount()>1)
{
Superclass::UnRegister();
if((m_Unregistering==false) && (m_SmartSourcePointer.IsNotNull()))
{
m_Unregistering=true;
// the order of the following boolean statement is important:
// this->GetSource() returns a SmartPointer,
// which increases and afterwards decreases the reference count,
// which may result in an ExternalReferenceCount of 0, causing
// BaseProcess::UnRegister() to destroy us (also we already
// about to do that).
if((this->m_SmartSourcePointer->GetExternalReferenceCount()==0) || (this->GetSource().IsNull()))
m_SmartSourcePointer=NULL; // now the reference count is zero and this object has been destroyed; thus nothing may be done after this line!!
else
m_Unregistering=false;
}
}
else
#endif
Superclass::UnRegister(); // now the reference count is zero and this object has been destroyed; thus nothing may be done after this line!!
}
void mitk::BaseData::ConnectSource(itk::ProcessObject *arg, unsigned int idx) const
{
#ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED
itkDebugMacro( "connecting source " << arg
<< ", source output index " << idx);
if ( GetSource().GetPointer() != arg || m_SourceOutputIndexDuplicate != idx)
{
m_SmartSourcePointer = dynamic_cast<mitk::BaseProcess*>(arg);
m_SourceOutputIndexDuplicate = idx;
Modified();
}
#endif
}
mitk::PropertyList::Pointer mitk::BaseData::GetPropertyList() const
{
return m_PropertyList;
}
mitk::BaseProperty::Pointer mitk::BaseData::GetProperty(const char *propertyKey) const
{
return m_PropertyList->GetProperty(propertyKey);
}
void mitk::BaseData::SetProperty(const char *propertyKey,
BaseProperty* propertyValue)
{
m_PropertyList->SetProperty(propertyKey, propertyValue);
}
void mitk::BaseData::SetPropertyList(PropertyList *pList)
{
m_PropertyList = pList;
}
void mitk::BaseData::SetOrigin(const mitk::Point3D& origin)
{
mitk::TimeSlicedGeometry* timeSlicedGeometry = GetTimeSlicedGeometry();
assert(timeSlicedGeometry!=NULL);
mitk::Geometry3D* geometry;
unsigned int steps = timeSlicedGeometry->GetTimeSteps();
for(unsigned int timestep = 0; timestep < steps; ++timestep)
{
geometry = GetGeometry(timestep);
if(geometry != NULL)
{
geometry->SetOrigin(origin);
}
if(GetTimeSlicedGeometry()->GetEvenlyTimed())
{
GetTimeSlicedGeometry()->InitializeEvenlyTimed(geometry, steps);
break;
}
}
}
unsigned long mitk::BaseData::GetMTime() const
{
unsigned long time = Superclass::GetMTime();
if(m_TimeSlicedGeometry.IsNotNull())
{
if((time < m_TimeSlicedGeometry->GetMTime()))
{
Modified();
return Superclass::GetMTime();
}
//unsigned long geometryTime = m_TimeSlicedGeometry->GetMTime();
//if(time < geometryTime)
//{
// return geometryTime;
//}
}
return time;
}
void mitk::BaseData::CopyInformation( const itk::DataObject* data )
{
const Self* bd = dynamic_cast<const Self*>(data);
if (bd != NULL)
{
m_TimeSlicedGeometry = dynamic_cast<TimeSlicedGeometry*>(bd->GetTimeSlicedGeometry()->Clone().GetPointer());
m_PropertyList = bd->GetPropertyList()->Clone();
}
else
{
// pointer could not be cast back down; this can be the case if your filters input
// and output objects differ in type; then you have to write your own GenerateOutputInformation method
itkExceptionMacro(<< "mitk::BaseData::CopyInformation() cannot cast "
<< typeid(data).name() << " to "
<< typeid(Self*).name() );
}
}
bool mitk::BaseData::IsInitialized() const
{
return m_Initialized;
}
void mitk::BaseData::Clear()
{
this->ClearData();
this->InitializeEmpty();
}
void mitk::BaseData::ClearData()
{
if(m_Initialized)
{
ReleaseData();
m_Initialized = false;
}
}
void mitk::BaseData::ExecuteOperation(mitk::Operation* /*operation*/)
{
//empty by default. override if needed!
}
void mitk::BaseData::PrintSelf(std::ostream& os, itk::Indent indent) const
{
os << std::endl;
os << indent << " TimeSlicedGeometry: ";
if(GetTimeSlicedGeometry() == NULL)
os << "NULL" << std::endl;
else
GetTimeSlicedGeometry()->Print(os, indent);
}
diff --git a/Core/Code/DataManagement/mitkBaseData.h b/Core/Code/DataManagement/mitkBaseData.h
index 199772253b..19e3f2fc8f 100644
--- a/Core/Code/DataManagement/mitkBaseData.h
+++ b/Core/Code/DataManagement/mitkBaseData.h
@@ -1,389 +1,388 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 BASEDATA_H_HEADER_INCLUDED_C1EBB6FA
#define BASEDATA_H_HEADER_INCLUDED_C1EBB6FA
#include <itkDataObject.h>
#include "mitkBaseProcess.h"
#include "mitkTimeSlicedGeometry.h"
#include <MitkExports.h>
#include "mitkOperationActor.h"
#include "mitkPropertyList.h"
namespace mitk {
//class BaseProcess;
//##Documentation
//## @brief Base of all data objects
//##
//## Base of all data objects, e.g., images, contours, surfaces etc. Inherits
//## from itk::DataObject and thus can be included in a pipeline.
//## Inherits also from OperationActor and can be used as a destination for Undo
//## @ingroup Data
class MITK_CORE_EXPORT BaseData : public itk::DataObject, public OperationActor
{
public:
mitkClassMacro(BaseData,itk::DataObject);
//##Documentation
//## @brief Return the TimeSlicedGeometry of the data as const pointer.
//##
//## \warning No update will be called. Use GetUpdatedGeometry() if you cannot
//## be sure that the geometry is up-to-date.
//##
//## Normally used in GenerateOutputInformation of subclasses of BaseProcess.
const mitk::TimeSlicedGeometry* GetTimeSlicedGeometry() const
{
return m_TimeSlicedGeometry.GetPointer();
}
//##Documentation
//## @brief Return the TimeSlicedGeometry of the data as pointer.
//##
//## \warning No update will be called. Use GetUpdatedGeometry() if you cannot
//## be sure that the geometry is up-to-date.
//##
//## Normally used in GenerateOutputInformation of subclasses of BaseProcess.
mitk::TimeSlicedGeometry* GetTimeSlicedGeometry()
{
return m_TimeSlicedGeometry.GetPointer();
}
//##Documentation
//## @brief Return the Geometry3D of the data.
//##
//## The method does not simply return the value of the m_TimeSlicedGeometry
//## member. Before doing this, it makes sure that the TimeSlicedGeometry
//## is up-to-date (by setting the update extent to largest possible and
//## calling UpdateOutputInformation).
const mitk::TimeSlicedGeometry* GetUpdatedTimeSlicedGeometry();
//##Documentation
//## @brief Expands the TimeSlicedGeometry to a number of TimeSteps.
//##
//## The method expands the TimeSlicedGeometry to the given number of TimeSteps,
//## filling newly created elements with empty geometries. Sub-classes should override
//## this method to handle the elongation of their data vectors, too.
//## Note that a shrinking is neither possible nor intended.
virtual void Expand( unsigned int timeSteps );
//##Documentation
//## @brief Return the Geometry3D of the data at time \a t.
//##
//## The method does not simply return
//## m_TimeSlicedGeometry->GetGeometry(t).
//## Before doing this, it makes sure that the Geometry3D is up-to-date
//## (by setting the update extent appropriately and calling
//## UpdateOutputInformation).
//##
//## @todo Appropriate setting of the update extent is missing.
const mitk::Geometry3D* GetUpdatedGeometry(int t=0);
//##Documentation
//## @brief Return the geometry, which is a TimeSlicedGeometry, of the data
//## as non-const pointer.
//##
//## \warning No update will be called. Use GetUpdatedGeometry() if you cannot
//## be sure that the geometry is up-to-date.
//##
//## Normally used in GenerateOutputInformation of subclasses of BaseProcess.
mitk::Geometry3D* GetGeometry(int t=0) const
{
if(m_TimeSlicedGeometry.IsNull())
return NULL;
return m_TimeSlicedGeometry->GetGeometry3D(t);
}
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
virtual void UnRegister() const;
//##Documentation
//## @brief for internal use only. Helps to deal with the
//## weak-pointer-problem.
virtual int GetExternalReferenceCount() const;
//##Documentation
//## @brief Update the information for this BaseData (the geometry in particular)
//## so that it can be used as an output of a BaseProcess.
//##
//## This method is used in the pipeline mechanism to propagate information and
//## initialize the meta data associated with a BaseData. Any implementation
//## of this method in a derived class is assumed to call its source's
//## BaseProcess::UpdateOutputInformation() which determines modified
//## times, LargestPossibleRegions, and any extra meta data like spacing,
//## origin, etc. Default implementation simply call's it's source's
//## UpdateOutputInformation().
//## \note Implementations of this methods in derived classes must take care
//## that the geometry is updated by calling
//## GetTimeSlicedGeometry()->UpdateInformation()
//## \em after calling its source's BaseProcess::UpdateOutputInformation().
void UpdateOutputInformation();
//##Documentation
//## @brief Set the RequestedRegion to the LargestPossibleRegion.
//##
//## This forces a filter to produce all of the output in one execution
//## (i.e. not streaming) on the next call to Update().
void SetRequestedRegionToLargestPossibleRegion()=0;
//##Documentation
//## @brief Determine whether the RequestedRegion is outside of the BufferedRegion.
//##
//## This method returns true if the RequestedRegion
//## is outside the BufferedRegion (true if at least one pixel is
//## outside). This is used by the pipeline mechanism to determine
//## whether a filter needs to re-execute in order to satisfy the
//## current request. If the current RequestedRegion is already
//## inside the BufferedRegion from the previous execution (and the
//## current filter is up to date), then a given filter does not need
//## to re-execute
bool RequestedRegionIsOutsideOfTheBufferedRegion()=0;
//##Documentation
//## @brief Verify that the RequestedRegion is within the LargestPossibleRegion.
//##
//## If the RequestedRegion is not within the LargestPossibleRegion,
//## then the filter cannot possibly satisfy the request. This method
//## returns true if the request can be satisfied (even if it will be
//## necessary to process the entire LargestPossibleRegion) and
//## returns false otherwise. This method is used by
//## PropagateRequestedRegion(). PropagateRequestedRegion() throws a
//## InvalidRequestedRegionError exception if the requested region is
//## not within the LargestPossibleRegion.
virtual bool VerifyRequestedRegion() = 0;
//##Documentation
//## @brief Copy information from the specified data set.
//##
//## This method is part of the pipeline execution model. By default, a
//## BaseProcess will copy meta-data from the first input to all of its
//## outputs. See ProcessObject::GenerateOutputInformation(). Each
//## subclass of DataObject is responsible for being able to copy
//## whatever meta-data it needs from another DataObject.
//## The default implementation of this method copies the time sliced geometry
//## and the property list of an object. If a subclass overrides this
//## method, it should always call its superclass' version.
void CopyInformation(const itk::DataObject* data);
//##Documentation
//## @brief Check whether the data has been initialized, i.e.,
//## at least the Geometry and other header data has been set
//##
//## \warning Set to \a true by default for compatibility reasons.
//## Set m_Initialized=false in constructors of sub-classes that
//## support distinction between initialized and uninitialized state.
virtual bool IsInitialized() const;
//##Documentation
//## @brief Calls ClearData() and InitializeEmpty();
//## \warning Only use in subclasses that reimplemented these methods.
//## Just calling Clear from BaseData will reset an object to a not initialized,
//## invalid state.
virtual void Clear();
//##Documentation
//## @brief Check whether object contains data (at
//## a specified time), e.g., a set of points may be empty
//##
//## \warning Returns IsInitialized()==false by default for
//## compatibility reasons. Override in sub-classes that
//## support distinction between empty/non-empty state.
virtual bool IsEmptyTimeStep(unsigned int t) const;
//##Documentation
//## @brief Check whether object contains data (at
//## least at one point in time), e.g., a set of points
//## may be empty
//##
//## \warning Returns IsInitialized()==false by default for
//## compatibility reasons. Override in sub-classes that
//## support distinction between empty/non-empty state.
virtual bool IsEmpty() const;
//##Documentation
//## @brief Set the requested region from this data object to match the requested
//## region of the data object passed in as a parameter.
//##
//## This method is implemented in the concrete subclasses of BaseData.
void SetRequestedRegion(itk::DataObject *data)=0;
//##Documentation
//##@brief overwrite if the Data can be called by an Interactor (StateMachine).
//##
//## Empty by default. Overwrite and implement all the necessary operations here
//## and get the necessary information from the parameter operation.
void ExecuteOperation(Operation* operation);
//##Documentation
//## @brief Set the Geometry3D of the data, which will be referenced (not copied!).
//## Assumes the data object has only 1 time step ( is a 3D object ).
//##
//## For convenience (and historic) reasons, it is also possible to set a complete
//## mitk::TimeSlicedGeometry*, which will be referenced (not copied!).
//##
//## @warning This method will normally be called internally by the sub-class of BaseData
//## during initialization.
//## \sa SetClonedGeometry
virtual void SetGeometry(Geometry3D* aGeometry3D);
//##Documentation
//## @brief Set a clone of the provided geometry as Geometry3D of the data.
//## Assumes the data object has only 1 time step ( is a 3D object )
//##
//## \sa SetGeometry
virtual void SetClonedGeometry(const Geometry3D* aGeometry3D);
//##Documentation
//## @brief Set a clone of the provided geometry as Geometry3D of a given time step.
//##
//## \sa SetGeometry
virtual void SetClonedGeometry(const Geometry3D* aGeometry3D, unsigned int time);
//##Documentation
//## @brief Get the data's property list
//## @sa GetProperty
//## @sa m_PropertyList
mitk::PropertyList::Pointer GetPropertyList() const;
//##Documentation
//## @brief Set the data's property list
//## @sa SetProperty
//## @sa m_PropertyList
void SetPropertyList(PropertyList* propertyList);
//##Documentation
//## @brief Get the property (instance of BaseProperty) with key @a propertyKey from the PropertyList,
//## and set it to this, respectively;
//## @sa GetPropertyList
//## @sa m_PropertyList
//## @sa m_MapOfPropertyLists
mitk::BaseProperty::Pointer GetProperty(const char *propertyKey) const;
void SetProperty(const char *propertyKey, BaseProperty* property);
//##Documentation
//## @brief Convenience method for setting the origin of
//## the Geometry3D instances of all time steps
//##
//## \warning Geometries contained in the Geometry3D will
//## \em not be changed, e.g. in case the Geometry3D is a
//## SlicedGeometry3D the origin will \em not be propagated
//## to the contained slices. The sub-class SlicedData
//## does this for the case that the SlicedGeometry3D is
//## evenly spaced.
virtual void SetOrigin(const Point3D& origin);
/** \brief Get the process object that generated this data object.
*
* If there is no process object, then the data object has
* been disconnected from the pipeline, or the data object
* was created manually. (Note: we cannot use the GetObjectMacro()
* defined in itkMacro because the mutual dependency of
* DataObject and ProcessObject causes compile problems. Also,
* a forward reference smart pointer is returned, not a smart pointer,
* because of the circular dependency between the process and data object.)
*
* GetSource() returns a SmartPointer and not a WeakPointer
* because it is assumed the code calling GetSource() wants to hold a
* long term reference to the source. */
itk::SmartPointer<mitk::BaseProcess> GetSource() const;
//##Documentation
//## @brief Get the number of time steps from the Timeslicedgeometry
//## As the base data has not a data vector given by itself, the number
//## of time steps is defined over the time sliced geometry. In sub classes,
//## a better implementation could be over the length of the data vector.
unsigned int GetTimeSteps() const
{
return m_TimeSlicedGeometry->GetTimeSteps();
};
//##Documentation
//## @brief Get the modified time of the last change of the contents
//## this data object or its geometry.
virtual unsigned long GetMTime() const;
protected:
BaseData();
BaseData(const BaseData &other);
~BaseData();
//##Documentation
//## @brief Initialize the TimeSlicedGeometry for a number of time steps.
//## The TimeSlicedGeometry is initialized empty and evenly timed.
//## In many cases it will be necessary to overwrite this in sub-classes.
virtual void InitializeTimeSlicedGeometry( unsigned int timeSteps = 1 );
//##Documentation
//## @brief reset to non-initialized state, release memory
virtual void ClearData();
//##Documentation
//## @brief Pure virtual; Must be used in subclasses to get a data object to a
//## valid state. Should at least create one empty object and call
//## Superclass::InitializeTimeSlicedGeometry() to ensure an existing valid geometry
virtual void InitializeEmpty(){};
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
bool m_RequestedRegionInitialized;
bool m_LastRequestedRegionWasOutsideOfTheBufferedRegion;
mutable itk::SmartPointer<mitk::BaseProcess> m_SmartSourcePointer;
mutable unsigned int m_SourceOutputIndexDuplicate;
//##Documentation
//## @brief for internal use only. Helps to deal with the
//## weak-pointer-problem.
virtual void ConnectSource(itk::ProcessObject *arg, unsigned int idx) const;
bool m_Initialized;
private:
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
mutable bool m_Unregistering;
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
mutable bool m_CalculatingExternalReferenceCount;
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
mutable int m_ExternalReferenceCount;
//##Documentation
//## @brief PropertyList, f.e. to hold pic-tags, tracking-data,..
//##
PropertyList::Pointer m_PropertyList;
TimeSlicedGeometry::Pointer m_TimeSlicedGeometry;
//##Documentation
//## @brief Helps to deal with the weak-pointer-problem.
friend class mitk::BaseProcess;
};
} // namespace mitk
#endif /* BASEDATA_H_HEADER_INCLUDED_C1EBB6FA */
diff --git a/Core/Code/DataManagement/mitkBaseDataTestImplementation.h b/Core/Code/DataManagement/mitkBaseDataTestImplementation.h
index 4d397391f0..e3a24e0ac4 100644
--- a/Core/Code/DataManagement/mitkBaseDataTestImplementation.h
+++ b/Core/Code/DataManagement/mitkBaseDataTestImplementation.h
@@ -1,60 +1,59 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 18127 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 BASEDATAIMPLEMENTATION_H_HEADER_INCLUDED
#define BASEDATAIMPLEMENTATION_H_HEADER_INCLUDED
#include "mitkBaseData.h"
namespace mitk {
//##Documentation
//## @brief Implementation of BaseData (for testing)
//##
//## As BaseData is an abstract class, we need an implementation for testing its methods
//## @ingroup Data
class BaseDataTestImplementation : public BaseData
{
public:
mitkClassMacro(BaseDataTestImplementation, BaseData);
itkNewMacro(Self);
mitkCloneMacro(BaseDataTestImplementation);
virtual void InitializeTimeSlicedGeometry( unsigned int timeSteps /* = 1 */ )
{
Superclass::InitializeTimeSlicedGeometry(timeSteps);
}
protected:
virtual bool VerifyRequestedRegion(){return false;};
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(){return false;};
virtual void SetRequestedRegionToLargestPossibleRegion(){};
virtual void SetRequestedRegion(itk::DataObject * /*data*/){};
BaseDataTestImplementation(){};
virtual ~BaseDataTestImplementation(){};
};
} // namespace
#endif // BASEDATA_H_HEADER_INCLUDED
\ No newline at end of file
diff --git a/Core/Code/DataManagement/mitkBaseProperty.cpp b/Core/Code/DataManagement/mitkBaseProperty.cpp
index da02b1cd3a..8478b814c6 100644
--- a/Core/Code/DataManagement/mitkBaseProperty.cpp
+++ b/Core/Code/DataManagement/mitkBaseProperty.cpp
@@ -1,62 +1,61 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkBaseProperty.h"
mitk::BaseProperty::BaseProperty()
{
}
mitk::BaseProperty::~BaseProperty()
{
}
std::string mitk::BaseProperty::GetValueAsString() const
{
return std::string("n/a");
}
mitk::BaseProperty& mitk::BaseProperty::operator=(const BaseProperty& rhs)
{
AssignProperty(rhs);
return *this;
}
bool mitk::BaseProperty::AssignProperty(const BaseProperty& rhs)
{
if (this == &rhs) return true; // no self assignment
const char* t1 = typeid(this).name();
const char* t2 = typeid(&rhs).name();
std::string s1(t1);
std::string s2(t2);
if (typeid(*this) == typeid(rhs) && Assign(rhs))
{
this->Modified();
return true;
}
return false;
}
bool mitk::BaseProperty::operator==(const BaseProperty& property) const
{
return (typeid(*this) == typeid(property) && IsEqual(property));
}
diff --git a/Core/Code/DataManagement/mitkBaseProperty.h b/Core/Code/DataManagement/mitkBaseProperty.h
index c0365ec1e0..3e019e4b0c 100644
--- a/Core/Code/DataManagement/mitkBaseProperty.h
+++ b/Core/Code/DataManagement/mitkBaseProperty.h
@@ -1,102 +1,101 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 BASEPROPERTY_H_HEADER_INCLUDED_C1F4DF54
#define BASEPROPERTY_H_HEADER_INCLUDED_C1F4DF54
#include <string>
#include <itkObjectFactory.h>
#include <MitkExports.h>
#include <mitkCommon.h>
namespace mitk {
/*! \brief Abstract base class for properties
\ingroup DataManagement
Base class for properties. Properties are arbitrary additional information
(to define a new type of information you have to define a subclass of
BaseProperty) that can be added to a PropertyList.
Concrete subclasses of BaseProperty should define Set-/Get-methods to assess
the property value, which should be stored by value (not by reference).
Subclasses must implement an operator==(const BaseProperty& property), which
is used by PropertyList to check whether a property has been changed.
*/
class MITK_CORE_EXPORT BaseProperty : public itk::Object
{
public:
mitkClassMacro(BaseProperty,itk::Object);
/*! @brief Subclasses must implement IsEqual(const BaseProperty&) to support comparison.
operator== which is used by PropertyList to check whether a property has been changed.
*/
bool operator==(const BaseProperty& property) const;
/*! @brief Assigns property to this BaseProperty instance.
Subclasses must implement Assign(const BaseProperty&) and call the superclass
Assign method for proper handling of polymorphic assignments. The assignment
operator of the subclass should be disabled and the baseclass operator should
be made visible using "using" statements.
*/
BaseProperty& operator=(const BaseProperty& property);
/*! @brief Assigns property to this BaseProperty instance.
This method is identical to the assignment operator, except for the return type.
It allows to directly check if the assignemnt was successfull.
*/
bool AssignProperty(const BaseProperty & property);
virtual std::string GetValueAsString() const;
protected:
BaseProperty();
virtual ~BaseProperty();
private:
/*!
Override this method in subclasses to implement a meaningful comparison. The property
argument is guaranteed to be castable to the type of the implementing subclass.
*/
virtual bool IsEqual(const BaseProperty& property) const = 0;
/*!
Override this method in subclasses to implement a meaningful assignment. The property
argument is guaranteed to be castable to the type of the implementing subclass.
@warning This is not yet exception aware/safe and if this method returns false,
this property's state might be undefined.
@return True if the argument could be assigned to this property.
*/
virtual bool Assign(const BaseProperty& ) = 0;
};
} // namespace mitk
#endif /* BASEPROPERTY_H_HEADER_INCLUDED_C1F4DF54 */
diff --git a/Core/Code/DataManagement/mitkChannelDescriptor.h b/Core/Code/DataManagement/mitkChannelDescriptor.h
index e2e8421f34..7a73184182 100644
--- a/Core/Code/DataManagement/mitkChannelDescriptor.h
+++ b/Core/Code/DataManagement/mitkChannelDescriptor.h
@@ -1,93 +1,92 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKCHANNELDESCRIPTOR_H
#define MITKCHANNELDESCRIPTOR_H
#include "mitkPixelType.h"
#include <string>
namespace mitk
{
/** \brief An object which holds all essential information about a single channel of an Image.
The channel descriptor is designed to be used only as a part of the ImageDescriptor. A consequence
to this is that the ChannelDescriptor does not hold the geometry information, only the PixelType.
The pixel type is the single information that can differ among an image with multiple channels.
*/
class MITK_CORE_EXPORT ChannelDescriptor
{
public:
ChannelDescriptor(mitk::PixelType type, size_t numOfElements, bool allocate = false);
~ChannelDescriptor(){}
/** \brief Get the type of channel's elements */
PixelType GetPixelType() const
{ return *m_PixelType; }
/** \brief Get the size in bytes of the channel */
size_t GetSize() const
{ return m_Size; }
/** \brief Get the pointer to the actual data of the channel
\warning Such access to the image's data is not safe and will be replaced
\todo new memory management design
*/
unsigned char* GetData() const
{ return m_Data; }
protected:
friend class Image;
void SetData( void* dataPtr )
{
if(dataPtr == NULL)
{
m_Data = (unsigned char*) dataPtr;
}
}
void AllocateData();
/** Name of the channel */
std::string m_Name;
/** The type of each element of the channel
\sa PixelType */
PixelType *m_PixelType;
/** Size of the channel in bytes */
size_t m_Size;
/** Pointer to the data of the channel
\warning Not safe
\todo Replace in new memory management design
*/
unsigned char* m_Data;
};
} // end namespace mitk
#endif // MITKCHANNELDESCRIPTOR_H
diff --git a/Core/Code/DataManagement/mitkClippingProperty.cpp b/Core/Code/DataManagement/mitkClippingProperty.cpp
index 779d0502b0..2884fe2a2f 100644
--- a/Core/Code/DataManagement/mitkClippingProperty.cpp
+++ b/Core/Code/DataManagement/mitkClippingProperty.cpp
@@ -1,112 +1,111 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $
-Version: $Revision: 14081 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkClippingProperty.h"
namespace mitk
{
ClippingProperty::ClippingProperty()
: m_ClippingEnabled( false )
{
}
ClippingProperty::ClippingProperty(
const Point3D &origin, const Vector3D &normal )
: m_ClippingEnabled( true ),
m_Origin( origin ),
m_Normal( normal )
{
}
bool ClippingProperty::GetClippingEnabled() const
{
return m_ClippingEnabled;
}
void ClippingProperty::SetClippingEnabled( bool enabled )
{
if (m_ClippingEnabled != enabled)
{
m_ClippingEnabled = enabled;
this->Modified();
}
}
const Point3D &ClippingProperty::GetOrigin() const
{
return m_Origin;
}
void ClippingProperty::SetOrigin( const Point3D &origin )
{
if (m_Origin != origin)
{
m_Origin = origin;
this->Modified();
}
}
const Vector3D &ClippingProperty::GetNormal() const
{
return m_Normal;
}
void ClippingProperty::SetNormal( const Vector3D &normal )
{
if (m_Normal != normal)
{
m_Normal = normal;
this->Modified();
}
}
bool ClippingProperty::IsEqual( const BaseProperty &property ) const
{
return ((this->m_ClippingEnabled == static_cast<const Self&>(property).m_ClippingEnabled) &&
(this->m_Origin == static_cast<const Self&>(property).m_Origin ) &&
(this->m_Normal == static_cast<const Self&>(property).m_Normal ) );
}
bool ClippingProperty::Assign( const BaseProperty &property )
{
this->m_ClippingEnabled = static_cast<const Self&>(property).m_ClippingEnabled;
this->m_Origin = static_cast<const Self&>(property).m_Origin;
this->m_Normal = static_cast<const Self&>(property).m_Normal;
return true;
}
std::string ClippingProperty::GetValueAsString() const
{
std::stringstream myStr;
myStr << this->GetClippingEnabled() << this->GetOrigin() << this->GetNormal();
return myStr.str();
}
} // namespace
diff --git a/Core/Code/DataManagement/mitkClippingProperty.h b/Core/Code/DataManagement/mitkClippingProperty.h
index 4e5a1b540b..a1583b4c90 100644
--- a/Core/Code/DataManagement/mitkClippingProperty.h
+++ b/Core/Code/DataManagement/mitkClippingProperty.h
@@ -1,94 +1,93 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $
-Version: $Revision: 14081 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKCLIPPINGPROPERTY_H_HEADER_INCLUDED
#define MITKCLIPPINGPROPERTY_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkBaseProperty.h"
#include "mitkVector.h"
#include <itkConfigure.h>
#include <string>
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* \brief Property for clipping datasets; currently only
* clipping planes are possible
* \ingroup DataManagement
*/
class MITK_CORE_EXPORT ClippingProperty : public BaseProperty
{
public:
mitkClassMacro(ClippingProperty, BaseProperty);
typedef std::string ValueType;
itkNewMacro( ClippingProperty );
mitkNewMacro2Param( ClippingProperty,
const Point3D &, const Vector3D & );
bool GetClippingEnabled() const;
void SetClippingEnabled( bool enabled );
const Point3D &GetOrigin() const;
void SetOrigin( const Point3D &origin );
const Vector3D &GetNormal() const;
void SetNormal( const Vector3D &normal );
virtual std::string GetValueAsString() const;
using BaseProperty::operator =;
protected:
bool m_ClippingEnabled;
Point3D m_Origin;
Vector3D m_Normal;
ClippingProperty();
ClippingProperty( const Point3D &origin, const Vector3D &normal );
private:
// purposely not implemented
ClippingProperty(const ClippingProperty&);
ClippingProperty& operator=(const ClippingProperty&);
virtual bool IsEqual(const BaseProperty& property) const;
virtual bool Assign(const BaseProperty& property);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif /* MITKCLIPPINGPROPERTY_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkColorProperty.cpp b/Core/Code/DataManagement/mitkColorProperty.cpp
index 14ce2f7ec0..de9d84fdc8 100644
--- a/Core/Code/DataManagement/mitkColorProperty.cpp
+++ b/Core/Code/DataManagement/mitkColorProperty.cpp
@@ -1,88 +1,87 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <sstream>
#include "mitkColorProperty.h"
mitk::ColorProperty::ColorProperty()
: m_Color()
{
}
mitk::ColorProperty::ColorProperty(const float color[3]) : m_Color(color)
{
}
mitk::ColorProperty::ColorProperty(const float red, const float green, const float blue)
{
m_Color.Set(red, green, blue);
}
mitk::ColorProperty::ColorProperty(const mitk::Color & color) : m_Color(color)
{
}
bool mitk::ColorProperty::IsEqual(const BaseProperty& property) const
{
return this->m_Color == static_cast<const Self&>(property).m_Color;
}
bool mitk::ColorProperty::Assign(const BaseProperty& property)
{
this->m_Color = static_cast<const Self&>(property).m_Color;
return true;
}
const mitk::Color & mitk::ColorProperty::GetColor() const
{
return m_Color;
}
void mitk::ColorProperty::SetColor(const mitk::Color & color )
{
if(m_Color!=color)
{
m_Color = color;
Modified();
}
}
void mitk::ColorProperty::SetValue(const mitk::Color & color )
{
SetColor(color);
}
void mitk::ColorProperty::SetColor( float red, float green, float blue )
{
float tmp[3] = { red, green, blue };
SetColor(mitk::Color(tmp));
}
std::string mitk::ColorProperty::GetValueAsString() const {
std::stringstream myStr;
myStr.imbue(std::locale::classic());
myStr << GetValue() ;
return myStr.str();
}
const mitk::Color & mitk::ColorProperty::GetValue() const
{
return GetColor();
}
diff --git a/Core/Code/DataManagement/mitkColorProperty.h b/Core/Code/DataManagement/mitkColorProperty.h
index bf91857af8..9d222efb30 100644
--- a/Core/Code/DataManagement/mitkColorProperty.h
+++ b/Core/Code/DataManagement/mitkColorProperty.h
@@ -1,94 +1,93 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1
#define MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1
#include <MitkExports.h>
#include "mitkBaseProperty.h"
#include <itkRGBPixel.h>
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
//##Documentation
//## @brief Standard RGB color typedef (float)
//##
//## Standard RGB color typedef to get rid of template argument (float).
//## @ingroup Property
typedef itk::RGBPixel< float > Color;
//##Documentation
//## @brief RGB color property
//##
//## @ingroup DataManagement
class MITK_CORE_EXPORT ColorProperty : public BaseProperty
{
protected:
mitk::Color m_Color;
ColorProperty();
ColorProperty(const float red, const float green, const float blue);
ColorProperty(const float color[3]);
ColorProperty(const mitk::Color & color);
public:
mitkClassMacro(ColorProperty, BaseProperty);
itkNewMacro(ColorProperty);
mitkNewMacro1Param(ColorProperty, const float*);
mitkNewMacro1Param(ColorProperty, const mitk::Color&);
mitkNewMacro3Param(ColorProperty, const float, const float, const float);
typedef mitk::Color ValueType;
const mitk::Color & GetColor() const;
const mitk::Color & GetValue() const;
std::string GetValueAsString() const;
void SetColor(const mitk::Color & color );
void SetValue(const mitk::Color & color );
void SetColor( float red, float green, float blue );
using BaseProperty::operator=;
private:
// purposely not implemented
ColorProperty(const ColorProperty&);
ColorProperty& operator=(const ColorProperty&);
virtual bool IsEqual(const BaseProperty& property) const;
virtual bool Assign(const BaseProperty & property);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif /* MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 */
diff --git a/Core/Code/DataManagement/mitkCommon.h b/Core/Code/DataManagement/mitkCommon.h
index 1d4893acd2..ebeeee2e4b 100644
--- a/Core/Code/DataManagement/mitkCommon.h
+++ b/Core/Code/DataManagement/mitkCommon.h
@@ -1,123 +1,122 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITK_COMMON_H_DEFINED
#define MITK_COMMON_H_DEFINED
#ifdef _MSC_VER
// This warns about truncation to 255 characters in debug/browse info
#pragma warning (disable : 4786)
#pragma warning (disable : 4068 ) /* disable unknown pragma warnings */
#endif
//add only those headers here that are really necessary for all classes!
#include "itkObject.h"
#include "mitkConfig.h"
#include "mitkLogMacros.h"
#include "mitkExportMacros.h"
#include "mitkExceptionMacro.h"
#ifndef MITK_UNMANGLE_IPPIC
#define mitkIpPicDescriptor mitkIpPicDescriptor
#endif
typedef unsigned int MapperSlotId;
#define mitkClassMacro(className,SuperClassName) \
typedef className Self; \
typedef SuperClassName Superclass; \
typedef itk::SmartPointer<Self> Pointer; \
typedef itk::SmartPointer<const Self> ConstPointer; \
itkTypeMacro(className,SuperClassName)
/**
* Macro for Constructors with one parameter for classes derived from itk::Lightobject
**/
#define mitkNewMacro1Param(classname,type) \
static Pointer New(type _arg) \
{ \
Pointer smartPtr = new classname ( _arg ); \
smartPtr->UnRegister(); \
return smartPtr; \
} \
/**
* Macro for Constructors with two parameters for classes derived from itk::Lightobject
**/
#define mitkNewMacro2Param(classname,typea,typeb) \
static Pointer New(typea _arga, typeb _argb) \
{ \
Pointer smartPtr = new classname ( _arga, _argb ); \
smartPtr->UnRegister(); \
return smartPtr; \
} \
/**
* Macro for Constructors with three parameters for classes derived from itk::Lightobject
**/
#define mitkNewMacro3Param(classname,typea,typeb,typec) \
static Pointer New(typea _arga, typeb _argb, typec _argc) \
{ \
Pointer smartPtr = new classname ( _arga, _argb, _argc ); \
smartPtr->UnRegister(); \
return smartPtr; \
} \
/**
* Macro for Constructors with three parameters for classes derived from itk::Lightobject
**/
#define mitkNewMacro4Param(classname,typea,typeb,typec,typed) \
static Pointer New(typea _arga, typeb _argb, typec _argc, typed _argd) \
{ \
Pointer smartPtr = new classname ( _arga, _argb, _argc, _argd ); \
smartPtr->UnRegister(); \
return smartPtr; \
} \
/** Get a smart const pointer to an object. Creates the member
* Get"name"() (e.g., GetPoints()). */
#define mitkGetObjectMacroConst(name,type) \
virtual type * Get##name () const \
{ \
itkDebugMacro("returning " #name " address " << this->m_##name ); \
return this->m_##name.GetPointer(); \
}
/** Creates a Clone() method for "Classname". Returns a smartPtr of a clone of the
calling object*/
#define mitkCloneMacro(classname) \
virtual Pointer Clone() const \
{ \
Pointer smartPtr = new classname(*this); \
smartPtr->UnRegister(); \
return smartPtr; \
}
/** cross-platform deprecation macro
\todo maybe there is something in external toolkits (ITK, VTK,...) that we could reulse -- would be much preferable
*/
#ifdef __GNUC__
#define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func
#else
#pragma message("WARNING: You need to implement DEPRECATED for your compiler!")
#define DEPRECATED(func) func
#endif
#endif // MITK_COMMON_H_DEFINED
\ No newline at end of file
diff --git a/Core/Code/DataManagement/mitkDataNode.cpp b/Core/Code/DataManagement/mitkDataNode.cpp
index 14f49007ff..deb3eaf96a 100644
--- a/Core/Code/DataManagement/mitkDataNode.cpp
+++ b/Core/Code/DataManagement/mitkDataNode.cpp
@@ -1,553 +1,552 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDataNode.h"
#include "mitkCoreObjectFactory.h"
#include <vtkTransform.h>
#include "mitkProperties.h"
#include "mitkStringProperty.h"
#include "mitkGroupTagProperty.h"
#include "mitkSmartPointerProperty.h"
//#include "mitkMaterialProperty.h"
#include "mitkColorProperty.h"
#include "mitkLevelWindowProperty.h"
#include "mitkGeometry3D.h"
#include "mitkRenderingManager.h"
#include "mitkGlobalInteraction.h"
#include "mitkEventMapper.h"
#include "mitkGenericProperty.h"
#include "mitkCoreObjectFactory.h"
mitk::Mapper* mitk::DataNode::GetMapper(MapperSlotId id) const
{
if( (id >= m_Mappers.size()) || (m_Mappers[id].IsNull()) )
{
if(id >= m_Mappers.capacity())
{
// int i, size=id-m_Mappers.capacity()+10;
m_Mappers.resize(id+10);
}
m_Mappers[id] = CoreObjectFactory::GetInstance()->CreateMapper(const_cast<DataNode*>(this),id);
}
return m_Mappers[id];
}
mitk::BaseData* mitk::DataNode::GetData() const
{
return m_Data;
}
mitk::Interactor* mitk::DataNode::GetInteractor() const
{
return m_Interactor;
}
void mitk::DataNode::SetData(mitk::BaseData* baseData)
{
if(m_Data!=baseData)
{
m_Data=baseData;
m_Mappers.clear();
m_Mappers.resize(10);
mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this);
m_DataReferenceChangedTime.Modified();
Modified();
//inform the interactor about the change
if (m_Interactor.IsNotNull())
m_Interactor->DataChanged();
}
}
void mitk::DataNode::SetInteractor(mitk::Interactor* interactor)
{
m_Interactor = interactor;
if(m_Interactor.IsNotNull())
m_Interactor->SetDataNode(this);
}
mitk::DataNode::DataNode() : m_Data(NULL), m_PropertyListModifiedObserverTag(0)
{
m_Mappers.resize(10);
m_PropertyList = PropertyList::New();
// subscribe for modified event
itk::MemberCommand<mitk::DataNode>::Pointer _PropertyListModifiedCommand =
itk::MemberCommand<mitk::DataNode>::New();
_PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::DataNode::PropertyListModified);
m_PropertyListModifiedObserverTag = m_PropertyList->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand);
}
mitk::DataNode::~DataNode()
{
if(m_PropertyList.IsNotNull())
// remove modified event listener
m_PropertyList->RemoveObserver(m_PropertyListModifiedObserverTag);
Interactor* interactor = this->GetInteractor();
if ( interactor )
{
mitk::GlobalInteraction::GetInstance()->RemoveInteractor( interactor );
}
m_Mappers.clear();
m_Data = NULL;
}
mitk::DataNode& mitk::DataNode::operator=(const DataNode& right)
{
mitk::DataNode* node=mitk::DataNode::New();
node->SetData(right.GetData());
return *node;
}
mitk::DataNode& mitk::DataNode::operator=(mitk::BaseData* right)
{
mitk::DataNode* node=mitk::DataNode::New();
node->SetData(right);
return *node;
}
#if (_MSC_VER > 1200) || !defined(_MSC_VER)
MBI_STD::istream& mitk::operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn )
#endif
#if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
MBI_STD::istream& operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn )
#endif
{
dtn = mitk::DataNode::New();
//i >> av.get();
return i;
}
#if (_MSC_VER > 1200) || !defined(_MSC_VER)
MBI_STD::ostream& mitk::operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn)
#endif
#if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
MBI_STD::ostream& operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn)
#endif
{
if(dtn->GetData()!=NULL)
o<<dtn->GetData()->GetNameOfClass();
else
o<<"empty data";
return o;
}
void mitk::DataNode::SetMapper(MapperSlotId id, mitk::Mapper* mapper)
{
m_Mappers[id] = mapper;
if (mapper!=NULL)
mapper->SetDataNode(this);
}
void mitk::DataNode::UpdateOutputInformation()
{
if (this->GetSource())
{
this->GetSource()->UpdateOutputInformation();
}
}
void mitk::DataNode::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::DataNode::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::DataNode::VerifyRequestedRegion()
{
return true;
}
void mitk::DataNode::SetRequestedRegion(itk::DataObject * /*data*/)
{
}
void mitk::DataNode::CopyInformation(const itk::DataObject * /*data*/)
{
}
mitk::PropertyList* mitk::DataNode::GetPropertyList(const mitk::BaseRenderer* renderer) const
{
if(renderer==NULL)
return m_PropertyList;
mitk::PropertyList::Pointer & propertyList = m_MapOfPropertyLists[renderer];
if(propertyList.IsNull())
propertyList = mitk::PropertyList::New();
assert(m_MapOfPropertyLists[renderer].IsNotNull());
return propertyList;
}
void mitk::DataNode::ConcatenatePropertyList(PropertyList *pList, bool replace)
{
m_PropertyList->ConcatenatePropertyList(pList, replace);
}
mitk::BaseProperty* mitk::DataNode::GetProperty(const char *propertyKey, const mitk::BaseRenderer* renderer) const
{
if(propertyKey==NULL)
return NULL;
//renderer specified?
if (renderer)
{
std::map<const mitk::BaseRenderer*,mitk::PropertyList::Pointer>::const_iterator it;
//check for the renderer specific property
it=m_MapOfPropertyLists.find(renderer);
if(it!=m_MapOfPropertyLists.end()) //found
{
mitk::BaseProperty::Pointer property;
property=it->second->GetProperty(propertyKey);
if(property.IsNotNull())//found an enabled property in the render specific list
return property;
else //found a renderer specific list, but not the desired property
return m_PropertyList->GetProperty(propertyKey); //return renderer unspecific property
}
else //didn't find the property list of the given renderer
{
//return the renderer unspecific property if there is one
return m_PropertyList->GetProperty(propertyKey);
}
}
else //no specific renderer given; use the renderer independent one
{
mitk::BaseProperty::Pointer property;
property=m_PropertyList->GetProperty(propertyKey);
if(property.IsNotNull())
return property;
}
//only to satisfy compiler!
return NULL;
}
mitk::DataNode::GroupTagList mitk::DataNode::GetGroupTags() const
{
GroupTagList groups;
const PropertyList::PropertyMap* propertyMap = m_PropertyList->GetMap();
for ( PropertyList::PropertyMap::const_iterator groupIter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here
groupIter != propertyMap->end();
++groupIter )
{
const BaseProperty* bp = groupIter->second;
if ( dynamic_cast<const GroupTagProperty*>(bp) )
{
groups.insert( groupIter->first );
}
}
return groups;
}
bool mitk::DataNode::GetBoolProperty(const char* propertyKey, bool& boolValue, mitk::BaseRenderer* renderer) const
{
mitk::BoolProperty::Pointer boolprop = dynamic_cast<mitk::BoolProperty*>(GetProperty(propertyKey, renderer));
if(boolprop.IsNull())
return false;
boolValue = boolprop->GetValue();
return true;
}
bool mitk::DataNode::GetIntProperty(const char* propertyKey, int &intValue, mitk::BaseRenderer* renderer) const
{
mitk::IntProperty::Pointer intprop = dynamic_cast<mitk::IntProperty*>(GetProperty(propertyKey, renderer));
if(intprop.IsNull())
return false;
intValue = intprop->GetValue();
return true;
}
bool mitk::DataNode::GetFloatProperty(const char* propertyKey, float &floatValue, mitk::BaseRenderer* renderer) const
{
mitk::FloatProperty::Pointer floatprop = dynamic_cast<mitk::FloatProperty*>(GetProperty(propertyKey, renderer));
if(floatprop.IsNull())
return false;
floatValue = floatprop->GetValue();
return true;
}
bool mitk::DataNode::GetStringProperty(const char* propertyKey, std::string& string, mitk::BaseRenderer* renderer) const
{
mitk::StringProperty::Pointer stringProp = dynamic_cast<mitk::StringProperty*>(GetProperty(propertyKey, renderer));
if(stringProp.IsNull())
{
return false;
}
else
{
//memcpy((void*)string, stringProp->GetValue(), strlen(stringProp->GetValue()) + 1 ); // looks dangerous
string = stringProp->GetValue();
return true;
}
}
bool mitk::DataNode::GetColor(float rgb[3], mitk::BaseRenderer* renderer, const char* propertyKey) const
{
mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetProperty(propertyKey, renderer));
if(colorprop.IsNull())
return false;
memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
return true;
}
bool mitk::DataNode::GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* propertyKey) const
{
mitk::FloatProperty::Pointer opacityprop = dynamic_cast<mitk::FloatProperty*>(GetProperty(propertyKey, renderer));
if(opacityprop.IsNull())
return false;
opacity=opacityprop->GetValue();
return true;
}
bool mitk::DataNode::GetLevelWindow(mitk::LevelWindow &levelWindow, mitk::BaseRenderer* renderer, const char* propertyKey) const
{
mitk::LevelWindowProperty::Pointer levWinProp = dynamic_cast<mitk::LevelWindowProperty*>(GetProperty(propertyKey, renderer));
if(levWinProp.IsNull())
return false;
levelWindow=levWinProp->GetLevelWindow();
return true;
}
void mitk::DataNode::SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::ColorProperty::Pointer prop;
prop = mitk::ColorProperty::New(color);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
void mitk::DataNode::SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer, const char* propertyKey)
{
float color[3];
color[0]=red;
color[1]=green;
color[2]=blue;
SetColor(color, renderer, propertyKey);
}
void mitk::DataNode::SetColor(const float rgb[3], mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::ColorProperty::Pointer prop;
prop = mitk::ColorProperty::New(rgb);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
void mitk::DataNode::SetVisibility(bool visible, mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::BoolProperty::Pointer prop;
prop = mitk::BoolProperty::New(visible);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
void mitk::DataNode::SetOpacity(float opacity, mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::FloatProperty::Pointer prop;
prop = mitk::FloatProperty::New(opacity);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
void mitk::DataNode::SetLevelWindow(mitk::LevelWindow levelWindow, mitk::BaseRenderer* renderer, const char* propertyKey)
{
mitk::LevelWindowProperty::Pointer prop;
prop = mitk::LevelWindowProperty::New(levelWindow);
GetPropertyList(renderer)->SetProperty(propertyKey, prop);
}
void mitk::DataNode::SetIntProperty(const char* propertyKey, int intValue, mitk::BaseRenderer* renderer)
{
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::IntProperty::New(intValue));
}
void mitk::DataNode::SetBoolProperty( const char* propertyKey, bool boolValue, mitk::BaseRenderer* renderer/*=NULL*/ )
{
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue));
}
void mitk::DataNode::SetFloatProperty( const char* propertyKey, float floatValue, mitk::BaseRenderer* renderer/*=NULL*/ )
{
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue));
}
void mitk::DataNode::SetStringProperty( const char* propertyKey, const char* stringValue, mitk::BaseRenderer* renderer/*=NULL*/ )
{
GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue));
}
void mitk::DataNode::SetProperty(const char *propertyKey,
BaseProperty* propertyValue,
const mitk::BaseRenderer* renderer)
{
GetPropertyList(renderer)->SetProperty(propertyKey, propertyValue);
}
void mitk::DataNode::ReplaceProperty(const char *propertyKey,
BaseProperty* propertyValue,
const mitk::BaseRenderer* renderer)
{
GetPropertyList(renderer)->ReplaceProperty(propertyKey, propertyValue);
}
void mitk::DataNode::AddProperty(const char *propertyKey,
BaseProperty* propertyValue,
const mitk::BaseRenderer* renderer,
bool overwrite)
{
if((overwrite) || (GetProperty(propertyKey, renderer) == NULL))
{
SetProperty(propertyKey, propertyValue, renderer);
}
}
vtkLinearTransform* mitk::DataNode::GetVtkTransform(int t) const
{
assert(m_Data.IsNotNull());
mitk::Geometry3D* geometry = m_Data->GetGeometry(t);
if(geometry == NULL)
return NULL;
return geometry->GetVtkTransform();
}
unsigned long mitk::DataNode::GetMTime() const
{
unsigned long time = Superclass::GetMTime();
if(m_Data.IsNotNull())
{
if((time < m_Data->GetMTime()) ||
((m_Data->GetSource().IsNotNull()) && (time < m_Data->GetSource()->GetMTime()))
)
{
Modified();
return Superclass::GetMTime();
}
}
return time;
}
void mitk::DataNode::SetSelected(bool selected, mitk::BaseRenderer* renderer)
{
mitk::BoolProperty::Pointer selectedProperty = dynamic_cast<mitk::BoolProperty*>(GetProperty("selected"));
if ( selectedProperty.IsNull() )
{
selectedProperty = mitk::BoolProperty::New();
selectedProperty->SetValue(false);
SetProperty("selected", selectedProperty, renderer);
}
if( selectedProperty->GetValue() != selected )
{
selectedProperty->SetValue(selected);
itk::ModifiedEvent event;
InvokeEvent( event );
}
}
/*
class SelectedEvent : public itk::ModifiedEvent
{
public:
typedef SelectedEvent Self;
typedef itk::ModifiedEvent Superclass;
SelectedEvent(DataNode* dataNode)
{ m_DataNode = dataNode; };
DataNode* GetDataNode()
{ return m_DataNode; };
virtual const char * GetEventName() const
{ return "SelectedEvent"; }
virtual bool CheckEvent(const ::itk::EventObject* e) const
{ return dynamic_cast<const Self*>(e); }
virtual ::itk::EventObject* MakeObject() const
{ return new Self(m_DataNode); }
private:
DataNode* m_DataNode;
SelectedEvent(const Self& event)
{ m_DataNode = event.m_DataNode; };
void operator=(const Self& event)
{ m_DataNode = event.m_DataNode; }
};
*/
bool mitk::DataNode::IsSelected(mitk::BaseRenderer* renderer)
{
bool selected;
if ( !GetBoolProperty("selected", selected, renderer) )
return false;
return selected;
}
void mitk::DataNode::SetInteractorEnabled( const bool& enabled )
{
if ( m_Interactor.IsNull() )
{
itkWarningMacro("Interactor is NULL. Couldn't enable or disable interaction.");
return;
}
if ( enabled )
mitk::GlobalInteraction::GetInstance()->AddInteractor( m_Interactor.GetPointer() );
else
mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor.GetPointer() );
}
void mitk::DataNode::EnableInteractor()
{
SetInteractorEnabled( true );
}
void mitk::DataNode::DisableInteractor()
{
SetInteractorEnabled( false );
}
bool mitk::DataNode::IsInteractorEnabled() const
{
return mitk::GlobalInteraction::GetInstance()->InteractorRegistered( m_Interactor.GetPointer() );
}
void mitk::DataNode::PropertyListModified( const itk::Object* /*caller*/, const itk::EventObject& )
{
Modified();
}
diff --git a/Core/Code/DataManagement/mitkDataNode.h b/Core/Code/DataManagement/mitkDataNode.h
index 52e92c6126..3eb3354b55 100644
--- a/Core/Code/DataManagement/mitkDataNode.h
+++ b/Core/Code/DataManagement/mitkDataNode.h
@@ -1,525 +1,524 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 DATATREENODE_H_HEADER_INCLUDED_C1E14338
#define DATATREENODE_H_HEADER_INCLUDED_C1E14338
#include "mitkImageSource.h"
#include "mitkBaseData.h"
//#include "mitkMapper.h"
#include "mitkInteractor.h"
#ifdef MBI_NO_STD_NAMESPACE
#define MBI_STD
#include <iostream.h>
#include <fstream.h>
#else
#define MBI_STD std
#include <iostream>
#include <fstream>
#endif
#include "mitkStringProperty.h"
#include "mitkColorProperty.h"
#include "mitkPropertyList.h"
//#include "mitkMapper.h"
#include <map>
#include <set>
#include "mitkLevelWindow.h"
class vtkLinearTransform;
namespace mitk {
class BaseRenderer;
class Mapper;
//##Documentation
//## @brief Class for nodes of the DataTree
//##
//## Contains the data (instance of BaseData), a list of mappers, which can
//## draw the data, a transform (vtkTransform) and a list of properties
//## (PropertyList).
//## @ingroup DataManagement
//##
//## @todo clean up all the GetProperty methods. There are too many different flavours... Can most probably be reduced to <tt>bool GetProperty<type>(type&)</tt>
//##
//## @warning Change in semantics of SetProperty() since Aug 25th 2006. Check your usage of this method if you do
//## more with properties than just call <tt>SetProperty( "key", new SomeProperty("value") )</tt>.
class MITK_CORE_EXPORT DataNode : public itk::DataObject
{
public:
typedef mitk::Geometry3D::Pointer Geometry3DPointer;
typedef std::vector< itk::SmartPointer< Mapper > > MapperVector;
typedef std::map<const mitk::BaseRenderer*,mitk::PropertyList::Pointer> MapOfPropertyLists;
typedef std::set<std::string> GroupTagList;
mitkClassMacro(DataNode, itk::DataObject);
itkNewMacro(Self);
mitk::Mapper* GetMapper(MapperSlotId id) const;
//##Documentation
//## @brief Get the data object (instance of BaseData, e.g., an Image)
//## managed by this DataNode
BaseData* GetData() const;
//##Documentation
//## @brief Get the transformation applied prior to displaying the data as
//## a vtkTransform
//## \deprecated use GetData()->GetGeometry()->GetVtkTransform() instead
vtkLinearTransform* GetVtkTransform(int t=0) const;
//##Documentation
//## @brief Get the Interactor
Interactor* GetInteractor() const;
//##Documentation
//## @brief Set the data object (instance of BaseData, e.g., an Image)
//## managed by this DataNode
//## @warning the actor-mode of the vtkInteractor does not work any more, if the transform of the
//## data-tree-node is connected to the transform of the basedata via vtkTransform->SetInput.
virtual void SetData(mitk::BaseData* baseData);
//##Documentation
//## @brief Set the Interactor
virtual void SetInteractor(Interactor* interactor);
mitk::DataNode& operator=(const DataNode& right);
mitk::DataNode& operator=(BaseData* right);
virtual void SetMapper(MapperSlotId id, mitk::Mapper* mapper);
virtual void UpdateOutputInformation();
virtual void SetRequestedRegionToLargestPossibleRegion();
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
virtual bool VerifyRequestedRegion();
virtual void SetRequestedRegion(itk::DataObject *data);
virtual void CopyInformation(const itk::DataObject *data);
//##Documentation
//## @brief Set the property (instance of BaseProperty) with key @a propertyKey in the PropertyList
//## of the @a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-value.
//##
//## @warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do
//## more with properties than just call <tt>SetProperty( "key", new SomeProperty("value") )</tt>.
//##
//## @sa GetProperty
//## @sa m_PropertyList
//## @sa m_MapOfPropertyLists
void SetProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL);
//##Documentation
//## @brief Replace the property (instance of BaseProperty) with key @a propertyKey in the PropertyList
//## of the @a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-reference.
//##
//## If @a renderer is @a NULL the property is set in the BaseRenderer-independent
//## PropertyList of this DataNode.
//## @sa GetProperty
//## @sa m_PropertyList
//## @sa m_MapOfPropertyLists
void ReplaceProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL);
//##Documentation
//## @brief Add the property (instance of BaseProperty) if it does
//## not exist (or always if \a overwrite is \a true)
//## with key @a propertyKey in the PropertyList
//## of the @a renderer (if NULL, use BaseRenderer-independent
//## PropertyList). This is set-by-value.
//##
//## For \a overwrite == \a false the property is \em not changed
//## if it already exists. For \a overwrite == \a true the method
//## is identical to SetProperty.
//##
//## @sa SetProperty
//## @sa GetProperty
//## @sa m_PropertyList
//## @sa m_MapOfPropertyLists
void AddProperty(const char *propertyKey, BaseProperty* property, const mitk::BaseRenderer* renderer = NULL, bool overwrite = false);
//##Documentation
//## @brief Get the PropertyList of the @a renderer. If @a renderer is @a
//## NULL, the BaseRenderer-independent PropertyList of this DataNode
//## is returned.
//## @sa GetProperty
//## @sa m_PropertyList
//## @sa m_MapOfPropertyLists
mitk::PropertyList* GetPropertyList(const mitk::BaseRenderer* renderer = NULL) const;
//##Documentation
//## @brief Add values from another PropertyList.
//##
//## Overwrites values in m_PropertyList only when possible (i.e. when types are compatible).
//## If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty,
//## set the @param replace.
//##
//## @param replace true: if @param pList contains a property "visible" of type ColorProperty and our m_PropertyList also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects behind the pointer.
//##
//## @sa SetProperty
//## @sa ReplaceProperty
//## @sa m_PropertyList
void ConcatenatePropertyList(PropertyList* pList, bool replace = false);
//##Documentation
//## @brief Get the property (instance of BaseProperty) with key @a propertyKey from the PropertyList
//## of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
//##
//## If @a renderer is @a NULL or the @a propertyKey cannot be found
//## in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent
//## PropertyList of this DataNode is queried.
//## @sa GetPropertyList
//## @sa m_PropertyList
//## @sa m_MapOfPropertyLists
mitk::BaseProperty* GetProperty(const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const;
//##Documentation
//## @brief Get the property of type T with key @a propertyKey from the PropertyList
//## of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
//##
//## If @a renderer is @a NULL or the @a propertyKey cannot be found
//## in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent
//## PropertyList of this DataNode is queried.
//## @sa GetPropertyList
//## @sa m_PropertyList
//## @sa m_MapOfPropertyLists
template <typename T>
bool GetProperty(itk::SmartPointer<T> &property, const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const
{
property = dynamic_cast<T *>(GetProperty(propertyKey, renderer));
return property.IsNotNull();
}
//##Documentation
//## @brief Get the property of type T with key @a propertyKey from the PropertyList
//## of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList.
//##
//## If @a renderer is @a NULL or the @a propertyKey cannot be found
//## in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent
//## PropertyList of this DataNode is queried.
//## @sa GetPropertyList
//## @sa m_PropertyList
//## @sa m_MapOfPropertyLists
template <typename T>
bool GetProperty(T* &property, const char *propertyKey, const mitk::BaseRenderer* renderer = NULL) const
{
property = dynamic_cast<T *>(GetProperty(propertyKey, renderer));
return property!=NULL;
}
//##Documentation
//## @brief Convenience access method for GenericProperty<T> properties
//## (T being the type of the second parameter)
//## @return @a true property was found
template <typename T>
bool GetPropertyValue(const char* propertyKey, T & value, mitk::BaseRenderer* renderer=NULL) const
{
GenericProperty<T>* gp= dynamic_cast<GenericProperty<T>*>(GetProperty(propertyKey, renderer));
if ( gp != NULL )
{
value = gp->GetValue();
return true;
}
return false;
}
// @brief Get a set of all group tags from this node's property list
GroupTagList GetGroupTags() const;
//##Documentation
//## @brief Convenience access method for bool properties (instances of
//## BoolProperty)
//## @return @a true property was found
bool GetBoolProperty(const char* propertyKey, bool &boolValue, mitk::BaseRenderer* renderer = NULL) const;
//##Documentation
//## @brief Convenience access method for int properties (instances of
//## IntProperty)
//## @return @a true property was found
bool GetIntProperty(const char* propertyKey, int &intValue, mitk::BaseRenderer* renderer=NULL) const;
//##Documentation
//## @brief Convenience access method for float properties (instances of
//## FloatProperty)
//## @return @a true property was found
bool GetFloatProperty(const char* propertyKey, float &floatValue, mitk::BaseRenderer* renderer = NULL) const;
//##Documentation
//## @brief Convenience access method for string properties (instances of
//## StringProperty)
//## @return @a true property was found
bool GetStringProperty(const char* propertyKey, std::string& string, mitk::BaseRenderer* renderer = NULL) const;
//##Documentation
//## @brief Convenience access method for color properties (instances of
//## ColorProperty)
//## @return @a true property was found
bool GetColor(float rgb[3], mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color") const;
//##Documentation
//## @brief Convenience access method for level-window properties (instances of
//## LevelWindowProperty)
//## @return @a true property was found
bool GetLevelWindow(mitk::LevelWindow &levelWindow, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "levelwindow") const;
//##
//##Documentation
//## @brief set the node as selected
void SetSelected(bool selected, mitk::BaseRenderer* renderer=NULL);
//##
//##Documentation
//## @brief set the node as selected
//## @return @a true node is selected
bool IsSelected(mitk::BaseRenderer* renderer=NULL);
//##Documentation
//## @brief Convenience access method for accessing the name of an object (instance of
//## StringProperty with property-key "name")
//## @return @a true property was found
bool GetName(std::string& nodeName, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "name") const
{
return GetStringProperty(propertyKey, nodeName, renderer);
}
//##Documentation
//## @brief Extra convenience access method for accessing the name of an object (instance of
//## StringProperty with property-key "name").
//##
//## This method does not take the renderer specific
//## propertylists into account, because the name of an object should never be renderer specific.
//## @returns a std::string with the name of the object (content of "name" Property).
//## If there is no "name" Property, an empty string will be returned.
virtual std::string GetName() const
{
mitk::StringProperty* sp = dynamic_cast<mitk::StringProperty*>(this->GetProperty("name"));
if (sp == NULL)
return "";
return sp->GetValue();
}
//##Documentation
//## @brief Extra convenience access method to set the name of an object.
//##
//## The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name".
virtual void SetName( const char* name)
{
if (name == NULL)
return;
this->SetProperty("name", StringProperty::New(name));
}
//##Documentation
//## @brief Extra convenience access method to set the name of an object.
//##
//## The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name".
virtual void SetName( const std::string name)
{
this->SetName(name.c_str());
}
//##Documentation
//## @brief Convenience access method for visibility properties (instances
//## of BoolProperty with property-key "visible")
//## @return @a true property was found
//## @sa IsVisible
bool GetVisibility(bool &visible, mitk::BaseRenderer* renderer, const char* propertyKey = "visible") const
{
return GetBoolProperty(propertyKey, visible, renderer);
}
//##Documentation
//## @brief Convenience access method for opacity properties (instances of
//## FloatProperty)
//## @return @a true property was found
bool GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* propertyKey = "opacity") const;
//##Documentation
//## @brief Convenience access method for boolean properties (instances
//## of BoolProperty). Return value is the value of the property. If the property is
//## not found, the value of @a defaultIsOn is returned.
//##
//## Thus, the return value has a different meaning than in the
//## GetBoolProperty method!
//## @sa GetBoolProperty
bool IsOn(const char* propertyKey, mitk::BaseRenderer* renderer, bool defaultIsOn = true) const
{
if(propertyKey==NULL)
return defaultIsOn;
GetBoolProperty(propertyKey, defaultIsOn, renderer);
return defaultIsOn;
}
//##Documentation
//## @brief Convenience access method for visibility properties (instances
//## of BoolProperty). Return value is the visibility. Default is
//## visible==true, i.e., true is returned even if the property (@a
//## propertyKey) is not found.
//##
//## Thus, the return value has a different meaning than in the
//## GetVisibility method!
//## @sa GetVisibility
//## @sa IsOn
bool IsVisible(mitk::BaseRenderer* renderer, const char* propertyKey = "visible", bool defaultIsOn = true) const
{
return IsOn(propertyKey, renderer, defaultIsOn);
}
//##Documentation
//## @brief Convenience method for setting color properties (instances of
//## ColorProperty)
void SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
//##Documentation
//## @brief Convenience method for setting color properties (instances of
//## ColorProperty)
void SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
//##Documentation
//## @brief Convenience method for setting color properties (instances of
//## ColorProperty)
void SetColor(const float rgb[3], mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "color");
//##Documentation
//## @brief Convenience method for setting visibility properties (instances
//## of BoolProperty)
//## @param visible If set to true, the data will be rendered. If false, the render will skip this data.
//## @param renderer Specify a renderer if the visibility shall be specific to a renderer
//## @param propertykey Can be used to specify a user defined name of the visibility propery.
void SetVisibility(bool visible, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "visible");
//##Documentation
//## @brief Convenience method for setting opacity properties (instances of
//## FloatProperty)
void SetOpacity(float opacity, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "opacity");
//##Documentation
//## @brief Convenience method for setting level-window properties
//## (instances of LevelWindowProperty)
void SetLevelWindow(mitk::LevelWindow levelWindow, mitk::BaseRenderer* renderer = NULL, const char* propertyKey = "levelwindow");
//##Documentation
//## @brief Convenience method for setting int properties (instances of
//## IntProperty)
void SetIntProperty(const char* propertyKey, int intValue, mitk::BaseRenderer* renderer=NULL);
//##Documentation
//## @brief Convenience method for setting int properties (instances of
//## IntProperty)
void SetBoolProperty(const char* propertyKey, bool boolValue, mitk::BaseRenderer* renderer=NULL);
//##Documentation
//## @brief Convenience method for setting int properties (instances of
//## IntProperty)
void SetFloatProperty(const char* propertyKey, float floatValue, mitk::BaseRenderer* renderer=NULL);
//##Documentation
//## @brief Convenience method for setting int properties (instances of
//## IntProperty)
void SetStringProperty(const char* propertyKey, const char* string, mitk::BaseRenderer* renderer=NULL);
//##Documentation
//## @brief Get the timestamp of the last change of the contents of this node or
//## the referenced BaseData.
virtual unsigned long GetMTime() const;
//##Documentation
//## @brief Get the timestamp of the last change of the reference to the
//## BaseData.
unsigned long GetDataReferenceChangedTime() const
{
return m_DataReferenceChangedTime.GetMTime();
}
//##Documentation
//## @brief Adds or removes the associated interactor to mitk::GLobalInteraction.
//##
virtual void SetInteractorEnabled( const bool& enabled );
//##Documentation
//## @brief Adds the interactor to mitk::GlobalInteraction
//##
virtual void EnableInteractor();
//##Documentation
//## @brief Removes the Interactor from mitk::GlobalInteraction
//##
virtual void DisableInteractor();
//##Documentation
//## @brief Tests, if the interactor is already added to mitk::GlobalInteraction
//##
virtual bool IsInteractorEnabled() const;
protected:
DataNode();
virtual ~DataNode();
//##
//## Invoked when the property list was modified. Calls Modified() of the DataNode
virtual void PropertyListModified(const itk::Object *caller, const itk::EventObject &event);
//##Documentation
//## @brief Mapper-slots
mutable MapperVector m_Mappers;
//##Documentation
//## @brief The data object (instance of BaseData, e.g., an Image) managed
//## by this DataNode
BaseData::Pointer m_Data;
//##Documentation
//## @brief BaseRenderer-independent PropertyList
//##
//## Properties herein can be overwritten specifically for each BaseRenderer
//## by the BaseRenderer-specific properties defined in m_MapOfPropertyLists.
PropertyList::Pointer m_PropertyList;
//##Documentation
//## @brief Map associating each BaseRenderer with its own PropertyList
mutable MapOfPropertyLists m_MapOfPropertyLists;
//##Documentation
//## @brief Interactor, that handles the Interaction
Interactor::Pointer m_Interactor;
//##Documentation
//## @brief Timestamp of the last change of m_Data
itk::TimeStamp m_DataReferenceChangedTime;
unsigned long m_PropertyListModifiedObserverTag;
};
#if (_MSC_VER > 1200) || !defined(_MSC_VER)
MITK_CORE_EXPORT MBI_STD::istream& operator>>( MBI_STD::istream& i, DataNode::Pointer& dtn );
MITK_CORE_EXPORT MBI_STD::ostream& operator<<( MBI_STD::ostream& o, DataNode::Pointer& dtn);
#endif
} // namespace mitk
#if ((defined(_MSC_VER)) && (_MSC_VER <= 1200))
MITK_CORE_EXPORT MBI_STD::istream& operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn );
MITK_CORE_EXPORT MBI_STD::ostream& operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn);
#endif
#endif /* DATATREENODE_H_HEADER_INCLUDED_C1E14338 */
diff --git a/Core/Code/DataManagement/mitkDataStorage.cpp b/Core/Code/DataManagement/mitkDataStorage.cpp
index 9ee1adb74d..396e6bddea 100644
--- a/Core/Code/DataManagement/mitkDataStorage.cpp
+++ b/Core/Code/DataManagement/mitkDataStorage.cpp
@@ -1,513 +1,512 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDataStorage.h"
#include "mitkDataNode.h"
#include "mitkProperties.h"
#include "mitkNodePredicateBase.h"
#include "mitkNodePredicateProperty.h"
#include "mitkGroupTagProperty.h"
#include "itkMutexLockHolder.h"
#include "itkCommand.h"
mitk::DataStorage::DataStorage() : itk::Object()
, m_BlockNodeModifiedEvents(false)
{
}
mitk::DataStorage::~DataStorage()
{
///// we can not call GetAll() in destructor, because it is implemented in a subclass
//SetOfObjects::ConstPointer all = this->GetAll();
//for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
// this->RemoveListeners(it->Value());
//m_NodeModifiedObserverTags.clear();
//m_NodeDeleteObserverTags.clear();
}
void mitk::DataStorage::Add(mitk::DataNode* node, mitk::DataNode* parent)
{
mitk::DataStorage::SetOfObjects::Pointer parents = mitk::DataStorage::SetOfObjects::New();
parents->InsertElement(0, parent);
this->Add(node, parents);
}
void mitk::DataStorage::Remove(const mitk::DataStorage::SetOfObjects* nodes)
{
if (nodes == NULL)
return;
for (mitk::DataStorage::SetOfObjects::ConstIterator it = nodes->Begin(); it != nodes->End(); it++)
this->Remove(it.Value());
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::DataStorage::GetSubset(const NodePredicateBase* condition) const
{
mitk::DataStorage::SetOfObjects::ConstPointer result = this->FilterSetOfObjects(this->GetAll(), condition);
return result;
}
mitk::DataNode* mitk::DataStorage::GetNamedNode(const char* name) const
{
if (name == NULL)
return NULL;
mitk::StringProperty::Pointer s(mitk::StringProperty::New(name));
mitk::NodePredicateProperty::Pointer p = mitk::NodePredicateProperty::New("name", s);
mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetSubset(p);
if (rs->Size() >= 1)
return rs->GetElement(0);
else
return NULL;
}
mitk::DataNode* mitk::DataStorage::GetNode(const NodePredicateBase* condition) const
{
if (condition == NULL)
return NULL;
mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetSubset(condition);
if (rs->Size() >= 1)
return rs->GetElement(0);
else
return NULL;
}
mitk::DataNode* mitk::DataStorage::GetNamedDerivedNode(const char* name, const mitk::DataNode* sourceNode, bool onlyDirectDerivations) const
{
if (name == NULL)
return NULL;
mitk::StringProperty::Pointer s(mitk::StringProperty::New(name));
mitk::NodePredicateProperty::Pointer p = mitk::NodePredicateProperty::New("name", s);
mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDerivations(sourceNode, p, onlyDirectDerivations);
if (rs->Size() >= 1)
return rs->GetElement(0);
else
return NULL;
}
void mitk::DataStorage::PrintSelf(std::ostream& os, itk::Indent indent) const
{
//Superclass::PrintSelf(os, indent);
mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetAll();
os << indent << "DataStorage " << this << " is managing " << all->Size() << " objects. List of objects:" << std::endl;
for (mitk::DataStorage::SetOfObjects::ConstIterator allIt = all->Begin(); allIt != all->End(); allIt++)
{
std::string name;
allIt.Value()->GetName(name);
std::string datatype;
if (allIt.Value()->GetData() != NULL)
datatype = allIt.Value()->GetData()->GetNameOfClass();
os << indent << " " << allIt.Value().GetPointer() << "<" << datatype << ">: " << name << std::endl;
mitk::DataStorage::SetOfObjects::ConstPointer parents = this->GetSources(allIt.Value());
if (parents->Size() > 0)
{
os << indent << " Direct sources: ";
for (mitk::DataStorage::SetOfObjects::ConstIterator parentIt = parents->Begin(); parentIt != parents->End(); parentIt++)
os << parentIt.Value().GetPointer() << ", ";
os << std::endl;
}
mitk::DataStorage::SetOfObjects::ConstPointer derivations = this->GetDerivations(allIt.Value());
if (derivations->Size() > 0)
{
os << indent << " Direct derivations: ";
for (mitk::DataStorage::SetOfObjects::ConstIterator derivationIt = derivations->Begin(); derivationIt != derivations->End(); derivationIt++)
os << derivationIt.Value().GetPointer() << ", ";
os << std::endl;
}
}
os << std::endl;
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::DataStorage::FilterSetOfObjects(const SetOfObjects* set, const NodePredicateBase* condition) const
{
if (set == NULL)
return NULL;
mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = set->Begin(); it != set->End(); it++)
if (condition == NULL || condition->CheckNode(it.Value()) == true) //alway copy the set, otherwise the iterator in mitk::DataStorage::Remove() will crash
result->InsertElement(result->Size(), it.Value());
return mitk::DataStorage::SetOfObjects::ConstPointer(result);
}
const mitk::DataNode::GroupTagList mitk::DataStorage::GetGroupTags() const
{
DataNode::GroupTagList result;
SetOfObjects::ConstPointer all = this->GetAll();
if (all.IsNull())
return result;
for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = all->Begin(); nodeIt != all->End(); nodeIt++) // for each node
{
mitk::PropertyList* pl = nodeIt.Value()->GetPropertyList();
for (mitk::PropertyList::PropertyMap::const_iterator propIt = pl->GetMap()->begin(); propIt != pl->GetMap()->end(); propIt++)
if (dynamic_cast<mitk::GroupTagProperty*>(propIt->second.GetPointer()) != NULL)
result.insert(propIt->first);
}
return result;
}
void mitk::DataStorage::EmitAddNodeEvent(const mitk::DataNode* node)
{
AddNodeEvent.Send(node);
}
void mitk::DataStorage::EmitRemoveNodeEvent(const mitk::DataNode* node)
{
RemoveNodeEvent.Send(node);
}
void mitk::DataStorage::OnNodeModifiedOrDeleted( const itk::Object *caller, const itk::EventObject &event )
{
if(m_BlockNodeModifiedEvents)
return;
const mitk::DataNode* _Node = dynamic_cast<const mitk::DataNode*>(caller);
if(_Node)
{
const itk::ModifiedEvent* modEvent = dynamic_cast<const itk::ModifiedEvent*>(&event);
if(modEvent)
ChangedNodeEvent.Send(_Node);
else
DeleteNodeEvent.Send(_Node);
}
}
void mitk::DataStorage::AddListeners( const mitk::DataNode* _Node )
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_MutexOne);
// node must not be 0 and must not be yet registered
mitk::DataNode* NonConstNode = const_cast<mitk::DataNode*>(_Node);
if(_Node && m_NodeModifiedObserverTags
.find(NonConstNode) == m_NodeModifiedObserverTags.end())
{
itk::MemberCommand<mitk::DataStorage>::Pointer nodeModifiedCommand =
itk::MemberCommand<mitk::DataStorage>::New();
nodeModifiedCommand->SetCallbackFunction(this
, &mitk::DataStorage::OnNodeModifiedOrDeleted);
m_NodeModifiedObserverTags[NonConstNode]
= NonConstNode->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand);
// add itk delete listener on datastorage
itk::MemberCommand<mitk::DataStorage>::Pointer deleteCommand =
itk::MemberCommand<mitk::DataStorage>::New();
deleteCommand->SetCallbackFunction(this, &mitk::DataStorage::OnNodeModifiedOrDeleted);
// add observer
m_NodeDeleteObserverTags[NonConstNode]
= NonConstNode->AddObserver(itk::DeleteEvent(), deleteCommand);
}
}
void mitk::DataStorage::RemoveListeners( const mitk::DataNode* _Node )
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_MutexOne) ;
// node must not be 0 and must be registered
mitk::DataNode* NonConstNode = const_cast<mitk::DataNode*>(_Node);
if(_Node && m_NodeModifiedObserverTags
.find(NonConstNode) != m_NodeModifiedObserverTags.end())
{
// const cast is bad! but sometimes it is necessary. removing an observer does not really
// touch the internal state
NonConstNode->RemoveObserver(m_NodeModifiedObserverTags
.find(NonConstNode)->second);
NonConstNode->RemoveObserver(m_NodeDeleteObserverTags
.find(NonConstNode)->second);
m_NodeModifiedObserverTags.erase(NonConstNode);
m_NodeDeleteObserverTags.erase(NonConstNode);
}
}
mitk::TimeSlicedGeometry::Pointer mitk::DataStorage::ComputeBoundingGeometry3D( const SetOfObjects* input, const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2)
{
if (input == NULL)
throw std::invalid_argument("DataStorage: input is invalid");
BoundingBox::PointsContainer::Pointer pointscontainer=BoundingBox::PointsContainer::New();
BoundingBox::PointIdentifier pointid=0;
Point3D point;
Vector3D minSpacing;
minSpacing.Fill(ScalarTypeNumericTraits::max());
ScalarType stmin, stmax;
stmin= ScalarTypeNumericTraits::NonpositiveMin();
stmax= ScalarTypeNumericTraits::max();
ScalarType minimalIntervallSize = stmax;
ScalarType minimalTime = stmax;
ScalarType maximalTime = 0;
// Needed for check of zero bounding boxes
mitk::ScalarType nullpoint[]={0,0,0,0,0,0};
BoundingBox::BoundsArrayType itkBoundsZero(nullpoint);
for (SetOfObjects::ConstIterator it = input->Begin(); it != input->End(); ++it)
{
DataNode::Pointer node = it->Value();
if((node.IsNotNull()) && (node->GetData() != NULL) &&
(node->GetData()->IsEmpty()==false) &&
node->IsOn(boolPropertyKey, renderer) &&
node->IsOn(boolPropertyKey2, renderer)
)
{
const TimeSlicedGeometry* geometry = node->GetData()->GetUpdatedTimeSlicedGeometry();
if (geometry != NULL )
{
// bounding box (only if non-zero)
BoundingBox::BoundsArrayType itkBounds = geometry->GetBoundingBox()->GetBounds();
if (itkBounds == itkBoundsZero)
{
continue;
}
unsigned char i;
for(i=0; i<8; ++i)
{
point = geometry->GetCornerPoint(i);
if(point[0]*point[0]+point[1]*point[1]+point[2]*point[2] < large)
pointscontainer->InsertElement( pointid++, point);
else
{
itkGenericOutputMacro( << "Unrealistically distant corner point encountered. Ignored. Node: " << node );
}
}
// spacing
try
{
AffineTransform3D::Pointer inverseTransform = AffineTransform3D::New();
geometry->GetIndexToWorldTransform()->GetInverse(inverseTransform);
vnl_vector< AffineTransform3D::MatrixType::ValueType > unitVector(3);
int axis;
for(axis = 0; axis < 3; ++axis)
{
unitVector.fill(0);
unitVector[axis] = 1.0;
ScalarType mmPerPixel = 1.0/(inverseTransform->GetMatrix()*unitVector).magnitude();
if(minSpacing[axis] > mmPerPixel)
{
minSpacing[axis] = mmPerPixel;
}
}
// time bounds
// iterate over all time steps
// Attention: Objects with zero bounding box are not respected in time bound calculation
TimeBounds minTB = geometry->GetTimeBounds();
for (unsigned int i=0; i<geometry->GetTimeSteps(); i++)
{
const TimeBounds & curTimeBounds = node->GetData()->GetGeometry(i)->GetTimeBounds();
// get the minimal time of all objects in the DataStorage
if ((curTimeBounds[0]<minimalTime)&&(curTimeBounds[0]>stmin))
{
minimalTime=curTimeBounds[0];
}
// get the maximal time of all objects in the DataStorage
if ((curTimeBounds[1]>maximalTime)&&(curTimeBounds[1]<stmax))
{
maximalTime = curTimeBounds[1];
}
// get the minimal TimeBound of all time steps of the current DataNode
if (curTimeBounds[1]-curTimeBounds[0]<minTB[1]-minTB[0])
{
minTB = curTimeBounds;
}
}
// get the minimal interval size of all time steps of all objects of the DataStorage
if (minTB[1]-minTB[0]<minimalIntervallSize)
{
minimalIntervallSize = minTB[1]-minTB[0];
}
}
catch(itk::ExceptionObject e)
{
MITK_ERROR << e << std::endl;
}
}
}
}
BoundingBox::Pointer result = BoundingBox::New();
result->SetPoints(pointscontainer);
result->ComputeBoundingBox();
// minimal time bounds of a single time step for all geometries
TimeBounds minTimeBounds;
minTimeBounds[0] = 0;
minTimeBounds[1] = 1;
// compute the number of time steps
unsigned int numberOfTimeSteps = 1;
if (maximalTime!=0) // make sure that there is at least one time sliced geometry in the data storage
{
minTimeBounds[0] = minimalTime;
minTimeBounds[1] = minimalTime + minimalIntervallSize;
numberOfTimeSteps = (maximalTime-minimalTime)/minimalIntervallSize;
}
TimeSlicedGeometry::Pointer timeSlicedGeometry = NULL;
if ( result->GetPoints()->Size()>0 )
{
// Initialize a geometry of a single time step
Geometry3D::Pointer geometry = Geometry3D::New();
geometry->Initialize();
// correct bounding-box (is now in mm, should be in index-coordinates)
// according to spacing
BoundingBox::BoundsArrayType bounds = result->GetBounds();
int i;
for(i = 0; i < 6; ++i)
{
bounds[i] /= minSpacing[i/2];
}
geometry->SetBounds(bounds);
geometry->SetSpacing(minSpacing);
geometry->SetTimeBounds(minTimeBounds);
// Initialize the time sliced geometry
timeSlicedGeometry = TimeSlicedGeometry::New();
timeSlicedGeometry->InitializeEvenlyTimed(geometry,numberOfTimeSteps);
}
return timeSlicedGeometry;
}
mitk::TimeSlicedGeometry::Pointer mitk::DataStorage::ComputeBoundingGeometry3D( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2)
{
return this->ComputeBoundingGeometry3D(this->GetAll(), boolPropertyKey, renderer, boolPropertyKey2);
}
mitk::TimeSlicedGeometry::Pointer mitk::DataStorage::ComputeVisibleBoundingGeometry3D( mitk::BaseRenderer* renderer, const char* boolPropertyKey )
{
return ComputeBoundingGeometry3D( "visible", renderer, boolPropertyKey );
}
mitk::BoundingBox::Pointer mitk::DataStorage::ComputeBoundingBox( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2)
{
BoundingBox::PointsContainer::Pointer pointscontainer=BoundingBox::PointsContainer::New();
BoundingBox::PointIdentifier pointid=0;
Point3D point;
// Needed for check of zero bounding boxes
mitk::ScalarType nullpoint[]={0,0,0,0,0,0};
BoundingBox::BoundsArrayType itkBoundsZero(nullpoint);
SetOfObjects::ConstPointer all = this->GetAll();
for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
{
DataNode::Pointer node = it->Value();
if((node.IsNotNull()) && (node->GetData() != NULL) &&
(node->GetData()->IsEmpty()==false) &&
node->IsOn(boolPropertyKey, renderer) &&
node->IsOn(boolPropertyKey2, renderer)
)
{
const Geometry3D* geometry = node->GetData()->GetUpdatedTimeSlicedGeometry();
if (geometry != NULL )
{
// bounding box (only if non-zero)
BoundingBox::BoundsArrayType itkBounds = geometry->GetBoundingBox()->GetBounds();
if (itkBounds == itkBoundsZero)
{
continue;
}
unsigned char i;
for(i=0; i<8; ++i)
{
point = geometry->GetCornerPoint(i);
if(point[0]*point[0]+point[1]*point[1]+point[2]*point[2] < large)
pointscontainer->InsertElement( pointid++, point);
else
{
itkGenericOutputMacro( << "Unrealistically distant corner point encountered. Ignored. Node: " << node );
}
}
}
}
}
BoundingBox::Pointer result = BoundingBox::New();
result->SetPoints(pointscontainer);
result->ComputeBoundingBox();
return result;
}
mitk::TimeBounds mitk::DataStorage::ComputeTimeBounds( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2)
{
TimeBounds timeBounds;
ScalarType stmin, stmax, cur;
stmin= ScalarTypeNumericTraits::NonpositiveMin();
stmax= ScalarTypeNumericTraits::max();
timeBounds[0]=stmax; timeBounds[1]=stmin;
SetOfObjects::ConstPointer all = this->GetAll();
for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
{
DataNode::Pointer node = it->Value();
if((node.IsNotNull()) && (node->GetData() != NULL) &&
(node->GetData()->IsEmpty()==false) &&
node->IsOn(boolPropertyKey, renderer) &&
node->IsOn(boolPropertyKey2, renderer)
)
{
const Geometry3D* geometry = node->GetData()->GetUpdatedTimeSlicedGeometry();
if (geometry != NULL )
{
const TimeBounds & curTimeBounds = geometry->GetTimeBounds();
cur=curTimeBounds[0];
//is it after -infinity, but before everything else that we found until now?
if((cur > stmin) && (cur < timeBounds[0]))
timeBounds[0] = cur;
cur=curTimeBounds[1];
//is it before infinity, but after everything else that we found until now?
if((cur < stmax) && (cur > timeBounds[1]))
timeBounds[1] = cur;
}
}
}
if(!(timeBounds[0] < stmax))
{
timeBounds[0] = stmin;
timeBounds[1] = stmax;
}
return timeBounds;
}
diff --git a/Core/Code/DataManagement/mitkDataStorage.h b/Core/Code/DataManagement/mitkDataStorage.h
index cb0e449d64..cb5a90b82e 100644
--- a/Core/Code/DataManagement/mitkDataStorage.h
+++ b/Core/Code/DataManagement/mitkDataStorage.h
@@ -1,395 +1,394 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKDATASTORAGE_H_HEADER_INCLUDED_
#define MITKDATASTORAGE_H_HEADER_INCLUDED_
#include "itkObject.h"
#include <MitkExports.h>
#include "mitkMessage.h"
#include "itkVectorContainer.h"
#include "mitkDataNode.h"
#include "mitkGeometry3D.h"
#include "itkSimpleFastMutexLock.h"
#include <map>
namespace mitk {
class NodePredicateBase;
class DataNode;
class BaseRenderer;
//##Documentation
//## @brief Data management class that handles 'was created by' relations
//##
//## The DataStorage provides data storage and management functionality.
//## It handles a 'was created by' relation by associating each data object with a
//## set of source objects, that this object was created from.
//## Thus, nodes are stored in a noncyclical directed graph data structure.
//## If a new node is added to the DataStorage, AddNodeEvent is emitted.
//## If a node is removed, RemoveNodeEvent is emitted.
//##
//##
//## \ingroup DataStorage
class MITK_CORE_EXPORT DataStorage : public itk::Object
{
public:
mitkClassMacro(DataStorage, itk::Object);
//##Documentation
//## @brief A Container of objects that is used as a result set of GetSubset() query operations (Set of SmartPointers to DataNodes).
typedef itk::VectorContainer<unsigned int, mitk::DataNode::Pointer> SetOfObjects;
//##Documentation
//## @brief Adds a DataNode containing a data object to its internal storage
//##
//## This Method adds a new data object to the DataStorage. The new object is
//## passed in the first parameter. The second parameter is a set
//## of source objects, that were used to create this object. The new object will have
//## a 'was created from' relation to its source objects.
//## the addition of a new object will fire the notification mechanism.
//## If the node parameter is NULL or if the DataNode has already been added,
//## an exception will be thrown.
virtual void Add(mitk::DataNode* node, const mitk::DataStorage::SetOfObjects* parents = NULL) = 0;
//##Documentation
//## @brief Convenience method to add a node that has one parent
//##
void Add(mitk::DataNode* node, mitk::DataNode* parent);
//##Documentation
//## @brief Removes node from the DataStorage
//##
virtual void Remove(const mitk::DataNode* node) = 0;
//##Documentation
//## @brief Checks if a node exists in the DataStorage
//##
virtual bool Exists(const mitk::DataNode* node) const = 0;
//##Documentation
//## @brief Removes a set of nodes from the DataStorage
//##
void Remove(const mitk::DataStorage::SetOfObjects* nodes);
//##Documentation
//## @brief returns a set of data objects that meet the given condition(s)
//##
//## GetSubset returns a set of objects with a specific data type that meet the condition(s)
//## specified in the condition parameter. Conditions can be
//## - data type of the data object
//## - is source object of specific object (e.g. all source objects of node x)
//## - has property with specific value (e.g. OrganType is Liver)
//## - negation of any condition
//## - conjunction of a set of conditions
//## - disjunction of a set of conditions
//## Conditions are implemented as predicates using the Composite Design Pattern
//## (see definition of NodePredicateBase for details).
//## The method returns a set of SmartPointers to the DataNodes that fulfill the
//## conditions. A set of all objects can be retrieved with the GetAll() method;
SetOfObjects::ConstPointer GetSubset(const NodePredicateBase* condition) const;
//##Documentation
//## @brief returns a set of source objects for a given node that meet the given condition(s).
//##
virtual SetOfObjects::ConstPointer GetSources(const mitk::DataNode* node, const NodePredicateBase* condition = NULL, bool onlyDirectSources = true) const = 0;
//##Documentation
//## @brief returns a set of derived objects for a given node.
//##
//## GetDerivations() returns a set of objects that are derived from the DataNode node.
//## This means, that node was used to create the returned objects. If the parameter
//## onlyDirectDerivations is set to true (default value), only objects that directly have
//## node as one of their source objects will be returned. Otherwise, objects that are
//## derived from derivations of node are returned too.
//## The derived objects can be filtered with a predicate object as described in the GetSubset()
//## method by providing a predicate as the condition parameter.
virtual SetOfObjects::ConstPointer GetDerivations(const mitk::DataNode* node, const NodePredicateBase* condition = NULL, bool onlyDirectDerivations = true) const = 0;
//##Documentation
//## @brief returns a set of all data objects that are stored in the data storage
//##
virtual SetOfObjects::ConstPointer GetAll() const = 0;
//##Documentation
//## @brief Convenience method to get the first node that matches the predicate condition
//##
mitk::DataNode* GetNode(const NodePredicateBase* condition = NULL) const;
//##Documentation
//## @brief Convenience method to get the first node with a given name
//##
mitk::DataNode* GetNamedNode(const char* name) const;
//##Documentation
//## @brief Convenience method to get the first node with a given name
//##
mitk::DataNode* GetNamedNode(const std::string name) const
{
return this->GetNamedNode(name.c_str());
}
//##Documentation
//## @brief Convenience method to get the first node with a given name that is derived from sourceNode
//##
mitk::DataNode* GetNamedDerivedNode(const char* name, const mitk::DataNode* sourceNode, bool onlyDirectDerivations = true) const;
//##Documentation
//## @brief Convenience method to get the first data object of a given data type with a given name
//##
template <class DataType>
DataType* GetNamedObject(const char* name) const
{
if (name == NULL)
return NULL;
mitk::DataNode* n = this->GetNamedNode(name);
if (n == NULL)
return NULL;
else
return dynamic_cast<DataType*>(n->GetData());
}
//##Documentation
//## @brief Convenience method to get the first data object of a given data type with a given name
//##
template <class DataType>
DataType* GetNamedObject(const std::string name) const
{
return this->GetNamedObject<DataType>(name.c_str());
}
//##Documentation
//## @brief Convenience method to get the first data object of a given data type with a given name that is derived from a specific node
//##
template <class DataType>
DataType* GetNamedDerivedObject(const char* name, const mitk::DataNode* sourceNode, bool onlyDirectDerivations = true) const
{
if (name == NULL)
return NULL;
mitk::DataNode* n = this->GetNamedDerivedNode(name, sourceNode, onlyDirectDerivations);
if (n == NULL)
return NULL;
else
return dynamic_cast<DataType*>(n->GetData());
}
//##Documentation
//## @brief Returns a list of used grouptags
//##
const DataNode::GroupTagList GetGroupTags() const;
/*ITK Mutex */
mutable itk::SimpleFastMutexLock m_MutexOne;
/* Public Events */
typedef Message1<const mitk::DataNode*> DataStorageEvent;
//##Documentation
//## @brief AddEvent is emitted whenever a new node has been added to the DataStorage.
//##
//## Observers should register to this event by calling myDataStorage->AddNodeEvent.AddListener(myObject, MyObject::MyMethod).
//## After registering, myObject->MyMethod() will be called every time a new node has been added to the DataStorage.
//## Observers should unregister by calling myDataStorage->AddNodeEvent.RemoveListener(myObject, MyObject::MyMethod).
//## Note: AddEvents are _not_ emitted if a node is added to DataStorage by adding it to the the underlying DataTree!
// member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef for
// a Message1 object which is thread safe
DataStorageEvent AddNodeEvent;
//##Documentation
//## @brief RemoveEvent is emitted directly before a node is removed from the DataStorage.
//##
//## Observers should register to this event by calling myDataStorage->RemoveNodeEvent.AddListener(myObject, MyObject::MyMethod).
//## After registering, myObject->MyMethod() will be called every time a new node has been added to the DataStorage.
//## Observers should unregister by calling myDataStorage->RemoveNodeEvent.RemoveListener(myObject, MyObject::MyMethod).
//## Note: RemoveEvents are also emitted if a node was removed from the DataStorage by deleting it from the underlying DataTree
// member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef for
// a Message1 object which is thread safe
DataStorageEvent RemoveNodeEvent;
//##Documentation
//## @brief ChangedEvent is emitted directly after a node was changed.
//##
//## Observers should register to this event by calling myDataStorage->ChangedNodeEvent.AddListener(myObject, MyObject::MyMethod).
//## After registering, myObject->MyMethod() will be called every time a new node has been changed.
//## Observers should unregister by calling myDataStorage->ChangedNodeEvent.RemoveListener(myObject, MyObject::MyMethod).
//## Internally the DataStorage listens to itk::ModifiedEvents on the nodes and forwards them
//## to the listeners of this event.
// member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef for
// a Message1 object which is thread safe
DataStorageEvent ChangedNodeEvent;
//##Documentation
//## @brief DeleteNodeEvent is emitted directly before a node is deleted.
//##
//## Observers should register to this event by calling myDataStorage->DeleteNodeEvent.AddListener(myObject, MyObject::MyMethod).
//## After registering, myObject->MyMethod() will be called when a node is deleted.
//## Observers should unregister by calling myDataStorage->DeleteNodeEvent.RemoveListener(myObject, MyObject::MyMethod).
//## Internally the DataStorage listens to itk::DeleteEvents on the nodes and forwards them
//## to the listeners of this event.
// member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef for
// a Message1 object which is thread safe
DataStorageEvent DeleteNodeEvent;
//##Documentation
//## @brief Compute the axis-parallel bounding geometry of the input objects
//##
//## Throws std::invalid_argument exception if input is NULL
//## @param input set of objects of the DataStorage to be included in the bounding geometry
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
//## @param renderer see @a boolPropertyKey
//## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
mitk::TimeSlicedGeometry::Pointer ComputeBoundingGeometry3D( const SetOfObjects* input, const char* boolPropertyKey = NULL, mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL);
//##Documentation
//## @brief Compute the axis-parallel bounding geometry of the data tree
//## (bounding box, minimal spacing of the considered nodes, live-span)
//##
//## it -> an iterator to a data tree structure
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
//## @param renderer see @a boolPropertyKey
//## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
mitk::TimeSlicedGeometry::Pointer ComputeBoundingGeometry3D( const char* boolPropertyKey = NULL, mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL);
//##Documentation
//## @brief Compute the axis-parallel bounding geometry of all visible parts of the
//## data tree bounding box, minimal spacing of the considered nodes, live-span)
//##
//## Simply calls ComputeBoundingGeometry3D(it, "visible", renderer, boolPropertyKey).
//## it -> an iterator of a data tree structure
//## @param renderer the reference to the renderer
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
mitk::TimeSlicedGeometry::Pointer ComputeVisibleBoundingGeometry3D( mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey = NULL);
//##Documentation
//## @brief Compute the bounding box of data tree structure
//## it -> an iterator to a data tree structure
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
//## @param renderer see @a boolPropertyKey
//## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
mitk::BoundingBox::Pointer ComputeBoundingBox( const char* boolPropertyKey = NULL, mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey2 = NULL);
//##Documentation
//## \brief Compute the bounding box of all visible parts of the data tree structure, for general
//## rendering or renderer specific visibility property checking
//##
//## Simply calls ComputeBoundingBox(it, "visible", renderer, boolPropertyKey).
//## it -> an iterator of a data tree structure
//## @param renderer the reference to the renderer
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the bounding-box calculation.
mitk::BoundingBox::Pointer ComputeVisibleBoundingBox( mitk::BaseRenderer* renderer = NULL, const char* boolPropertyKey = NULL)
{
return ComputeBoundingBox( "visible", renderer, boolPropertyKey);
}
//##Documentation
//## @brief Compute the time-bounds of the contents of a data tree structure
//##
//## The methods returns only [-infinity, +infinity], if all data-objects have an infinite live-span. Otherwise,
//## all data-objects with infinite live-span are ignored.
//## it -> an iterator to a data tree structure
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the time-bounds calculation.
//## @param renderer see @a boolPropertyKey
//## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
mitk::TimeBounds ComputeTimeBounds( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2);
//##Documentation
//## @brief Compute the time-bounds of all visible parts of the data tree structure, for general
//## rendering or renderer specific visibility property checking
//##
//## The methods returns only [-infinity, +infinity], if all data-objects have an infinite live-span. Otherwise,
//## all data-objects with infinite live-span are ignored.
//## Simply calls ComputeTimeBounds(it, "visible", renderer, boolPropertyKey).
//## @param it an iterator to a data tree structure
//## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
//## and is set to @a false, the node is ignored for the time-bounds calculation.
//## @param renderer see @a boolPropertyKey
mitk::TimeBounds ComputeTimeBounds( mitk::BaseRenderer* renderer, const char* boolPropertyKey)
{
return ComputeTimeBounds( "visible", renderer, boolPropertyKey);
}
protected:
//##Documentation
//## @brief EmitAddNodeEvent emits the AddNodeEvent
//##
//## This method should be called by subclasses to emit the AddNodeEvent
void EmitAddNodeEvent(const mitk::DataNode* node);
//##Documentation
//## @brief EmitRemoveNodeEvent emits the RemoveNodeEvent
//##
//## This method should be called by subclasses to emit the RemoveNodeEvent
void EmitRemoveNodeEvent(const mitk::DataNode* node);
//##Documentation
//## @brief OnNodeModified listens to modified events of DataNodes.
//##
//## The node is hidden behind the caller parameter, which has to be casted first.
//## If the cast succeeds the ChangedNodeEvent is emitted with this node.
void OnNodeModifiedOrDeleted( const itk::Object *caller, const itk::EventObject &event );
//##Documentation
//## @brief Adds a Modified-Listener to the given Node.
void AddListeners(const mitk::DataNode* _Node);
//##Documentation
//## @brief Removes a Modified-Listener from the given Node.
void RemoveListeners(const mitk::DataNode* _Node);
//##Documentation
//## @brief Saves Modified-Observer Tags for each node in order to remove the event listeners again.
std::map<const mitk::DataNode*, unsigned long> m_NodeModifiedObserverTags;
//##Documentation
//## @brief Saves Delete-Observer Tags for each node in order to remove the event listeners again.
std::map<const mitk::DataNode*, unsigned long> m_NodeDeleteObserverTags;
//##Documentation
//## @brief If this class changes nodes itself, set this to TRUE in order
//## to suppress NodeChangedEvent to be emitted.
bool m_BlockNodeModifiedEvents;
//##Documentation
//## @brief Standard Constructor for ::New() instantiation
DataStorage();
//##Documentation
//## @brief Standard Destructor
virtual ~DataStorage();
//##Documentation
//## @brief Filters a SetOfObjects by the condition. If no condition is provided, the original set is returned
SetOfObjects::ConstPointer FilterSetOfObjects(const SetOfObjects* set, const NodePredicateBase* condition) const;
//##Documentation
//## @brief Prints the contents of the DataStorage to os. Do not call directly, call ->Print() instead
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
};
} // namespace mitk
#endif /* MITKDATASTORAGE_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkDisplayGeometry.cpp b/Core/Code/DataManagement/mitkDisplayGeometry.cpp
index b2e0939be1..e827af8b2f 100644
--- a/Core/Code/DataManagement/mitkDisplayGeometry.cpp
+++ b/Core/Code/DataManagement/mitkDisplayGeometry.cpp
@@ -1,624 +1,623 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDisplayGeometry.h"
mitk::AffineGeometryFrame3D::Pointer mitk::DisplayGeometry::Clone() const
{
itkExceptionMacro(<<"calling mitk::DisplayGeometry::Clone does not make much sense.");
}
bool mitk::DisplayGeometry::IsValid() const
{
return m_Valid && m_WorldGeometry.IsNotNull() && m_WorldGeometry->IsValid();
}
unsigned long mitk::DisplayGeometry::GetMTime() const
{
if((m_WorldGeometry.IsNotNull()) && (Geometry2D::GetMTime() < m_WorldGeometry->GetMTime()))
{
Modified();
}
return Geometry2D::GetMTime();
}
const mitk::TimeBounds& mitk::DisplayGeometry::GetTimeBounds() const
{
if(m_WorldGeometry.IsNull())
{
return m_TimeBounds;
}
return m_WorldGeometry->GetTimeBounds();
}
// size definition methods
void mitk::DisplayGeometry::SetWorldGeometry(const Geometry2D* aWorldGeometry)
{
m_WorldGeometry = aWorldGeometry;
Modified();
}
bool mitk::DisplayGeometry::SetOriginInMM(const Vector2D& origin_mm)
{
m_OriginInMM = origin_mm;
WorldToDisplay(m_OriginInMM, m_OriginInDisplayUnits);
Modified();
return !this->RefitVisibleRect();
}
mitk::Vector2D mitk::DisplayGeometry::GetOriginInMM() const
{
return m_OriginInMM;
}
mitk::Vector2D mitk::DisplayGeometry::GetOriginInDisplayUnits() const
{
return m_OriginInDisplayUnits;
}
void mitk::DisplayGeometry::SetSizeInDisplayUnits(unsigned int width, unsigned int height, bool keepDisplayedRegion)
{
Vector2D oldSizeInMM( m_SizeInMM );
Point2D oldCenterInMM;
if(keepDisplayedRegion)
{
Point2D centerInDisplayUnits;
centerInDisplayUnits[0] = m_SizeInDisplayUnits[0]*0.5;
centerInDisplayUnits[1] = m_SizeInDisplayUnits[1]*0.5;
DisplayToWorld(centerInDisplayUnits, oldCenterInMM);
}
m_SizeInDisplayUnits[0]=width;
m_SizeInDisplayUnits[1]=height;
if(m_SizeInDisplayUnits[0] <= 0)
m_SizeInDisplayUnits[0] = 1;
if(m_SizeInDisplayUnits[1] <= 0)
m_SizeInDisplayUnits[1] = 1;
DisplayToWorld(m_SizeInDisplayUnits, m_SizeInMM);
if(keepDisplayedRegion)
{
Point2D positionOfOldCenterInCurrentDisplayUnits;
WorldToDisplay(oldCenterInMM, positionOfOldCenterInCurrentDisplayUnits);
Point2D currentNewCenterInDisplayUnits;
currentNewCenterInDisplayUnits[0] = m_SizeInDisplayUnits[0]*0.5;
currentNewCenterInDisplayUnits[1] = m_SizeInDisplayUnits[1]*0.5;
Vector2D shift;
shift=positionOfOldCenterInCurrentDisplayUnits.GetVectorFromOrigin()-currentNewCenterInDisplayUnits;
MoveBy(shift);
Zoom(m_SizeInMM.GetNorm()/oldSizeInMM.GetNorm(), currentNewCenterInDisplayUnits);
}
Modified();
}
mitk::Vector2D mitk::DisplayGeometry::GetSizeInDisplayUnits() const
{
return m_SizeInDisplayUnits;
}
mitk::Vector2D mitk::DisplayGeometry::GetSizeInMM() const
{
return m_SizeInMM;
}
unsigned int mitk::DisplayGeometry::GetDisplayWidth() const
{
assert(m_SizeInDisplayUnits[0] >= 0);
return (unsigned int)m_SizeInDisplayUnits[0];
}
unsigned int mitk::DisplayGeometry::GetDisplayHeight() const
{
assert(m_SizeInDisplayUnits[1] >= 0);
return (unsigned int)m_SizeInDisplayUnits[1];
}
// zooming, panning, restriction of both
void mitk::DisplayGeometry::SetConstrainZoomingAndPanning(bool constrain)
{
m_ConstrainZoomingAndPanning = constrain;
if (m_ConstrainZoomingAndPanning)
{
this->RefitVisibleRect();
}
}
bool mitk::DisplayGeometry::GetConstrainZommingAndPanning() const
{
return m_ConstrainZoomingAndPanning;
}
bool mitk::DisplayGeometry::SetScaleFactor(ScalarType mmPerDisplayUnit)
{
if(mmPerDisplayUnit<0.0001)
{
mmPerDisplayUnit=0.0001;
}
m_ScaleFactorMMPerDisplayUnit = mmPerDisplayUnit;
assert(m_ScaleFactorMMPerDisplayUnit < ScalarTypeNumericTraits::infinity());
DisplayToWorld(m_SizeInDisplayUnits, m_SizeInMM);
return !this->RefitVisibleRect();
}
mitk::ScalarType mitk::DisplayGeometry::GetScaleFactorMMPerDisplayUnit() const
{
return m_ScaleFactorMMPerDisplayUnit;
}
// Zooms with a factor (1.0=identity) around the specified center in display units
bool mitk::DisplayGeometry::Zoom(ScalarType factor, const Point2D& centerInDisplayUnits)
{
assert(factor > 0);
if ( SetScaleFactor(m_ScaleFactorMMPerDisplayUnit/factor) )
{
return SetOriginInMM(m_OriginInMM-centerInDisplayUnits.GetVectorFromOrigin()*(1-factor)*m_ScaleFactorMMPerDisplayUnit);
}
else
{
return false;
}
}
// Zooms with a factor (1.0=identity) around the specified center, but tries (if its within view contraints) to match the center in display units with the center in world coordinates.
bool mitk::DisplayGeometry::ZoomWithFixedWorldCoordinates(ScalarType factor, const Point2D& focusDisplayUnits, const Point2D& focusUnitsInMM )
{
assert(factor > 0);
SetScaleFactor(m_ScaleFactorMMPerDisplayUnit/factor);
SetOriginInMM(focusUnitsInMM.GetVectorFromOrigin()-focusDisplayUnits.GetVectorFromOrigin()*m_ScaleFactorMMPerDisplayUnit);
return true;
}
bool mitk::DisplayGeometry::MoveBy(const Vector2D& shiftInDisplayUnits)
{
SetOriginInMM(m_OriginInMM+shiftInDisplayUnits*m_ScaleFactorMMPerDisplayUnit);
Modified();
return !this->RefitVisibleRect();
}
void mitk::DisplayGeometry::Fit()
{
if((m_WorldGeometry.IsNull()) || (m_WorldGeometry->IsValid() == false)) return;
/// \FIXME: try to remove all the casts
int width=(int)m_SizeInDisplayUnits[0];
int height=(int)m_SizeInDisplayUnits[1];
ScalarType w = width;
ScalarType h = height;
const ScalarType& widthInMM = m_WorldGeometry->GetParametricExtentInMM(0);
const ScalarType& heightInMM = m_WorldGeometry->GetParametricExtentInMM(1);
ScalarType aspRatio=((ScalarType)widthInMM)/heightInMM;
ScalarType x = (ScalarType)w/widthInMM;
ScalarType y = (ScalarType)h/heightInMM;
if (x > y)
{
w = (int) (aspRatio*h);
}
else
{
h = (int) (w/aspRatio);
}
if(w>0)
{
SetScaleFactor(widthInMM/w);
}
Vector2D origin_display;
origin_display[0]=-(width-w)/2.0;
origin_display[1]=-(height-h)/2.0;
SetOriginInMM(origin_display*m_ScaleFactorMMPerDisplayUnit);
this->RefitVisibleRect();
Modified();
}
// conversion methods
void mitk::DisplayGeometry::DisplayToWorld(const Point2D &pt_display, Point2D &pt_mm) const
{
pt_mm[0]=m_ScaleFactorMMPerDisplayUnit*pt_display[0]+m_OriginInMM[0];
pt_mm[1]=m_ScaleFactorMMPerDisplayUnit*pt_display[1]+m_OriginInMM[1];
}
void mitk::DisplayGeometry::WorldToDisplay(const Point2D &pt_mm, Point2D &pt_display) const
{
pt_display[0]=(pt_mm[0]-m_OriginInMM[0])*(1.0/m_ScaleFactorMMPerDisplayUnit);
pt_display[1]=(pt_mm[1]-m_OriginInMM[1])*(1.0/m_ScaleFactorMMPerDisplayUnit);
}
void mitk::DisplayGeometry::DisplayToWorld(const Vector2D &vec_display, Vector2D &vec_mm) const
{
vec_mm=vec_display*m_ScaleFactorMMPerDisplayUnit;
}
void mitk::DisplayGeometry::WorldToDisplay(const Vector2D &vec_mm, Vector2D &vec_display) const
{
vec_display=vec_mm*(1.0/m_ScaleFactorMMPerDisplayUnit);
}
void mitk::DisplayGeometry::ULDisplayToMM(const Point2D &pt_ULdisplay, Point2D &pt_mm) const
{
ULDisplayToDisplay(pt_ULdisplay, pt_mm);
DisplayToWorld(pt_mm, pt_mm);
}
void mitk::DisplayGeometry::MMToULDisplay(const Point2D &pt_mm, Point2D &pt_ULdisplay) const
{
WorldToDisplay(pt_mm, pt_ULdisplay);
DisplayToULDisplay(pt_ULdisplay, pt_ULdisplay);
}
void mitk::DisplayGeometry::ULDisplayToMM(const Vector2D &vec_ULdisplay, Vector2D &vec_mm) const
{
ULDisplayToDisplay(vec_ULdisplay, vec_mm);
DisplayToWorld(vec_mm, vec_mm);
}
void mitk::DisplayGeometry::MMToULDisplay(const Vector2D &vec_mm, Vector2D &vec_ULdisplay) const
{
WorldToDisplay(vec_mm, vec_ULdisplay);
DisplayToULDisplay(vec_ULdisplay, vec_ULdisplay);
}
void mitk::DisplayGeometry::ULDisplayToDisplay(const Point2D &pt_ULdisplay, Point2D &pt_display) const
{
pt_display[0]=pt_ULdisplay[0];
pt_display[1]=GetDisplayHeight()-pt_ULdisplay[1];
}
void mitk::DisplayGeometry::DisplayToULDisplay(const Point2D &pt_display, Point2D &pt_ULdisplay) const
{
ULDisplayToDisplay(pt_display, pt_ULdisplay);
}
void mitk::DisplayGeometry::ULDisplayToDisplay(const Vector2D &vec_ULdisplay, Vector2D &vec_display) const
{
vec_display[0]= vec_ULdisplay[0];
vec_display[1]=-vec_ULdisplay[1];
}
void mitk::DisplayGeometry::DisplayToULDisplay(const Vector2D &vec_display, Vector2D &vec_ULdisplay) const
{
ULDisplayToDisplay(vec_display, vec_ULdisplay);
}
bool mitk::DisplayGeometry::Project(const Point3D &pt3d_mm, Point3D &projectedPt3d_mm) const
{
if(m_WorldGeometry.IsNotNull())
{
return m_WorldGeometry->Project(pt3d_mm, projectedPt3d_mm);
}
else
{
return false;
}
}
bool mitk::DisplayGeometry::Project(const Point3D & atPt3d_mm, const Vector3D &vec3d_mm, Vector3D &projectedVec3d_mm) const
{
if(m_WorldGeometry.IsNotNull())
{
return m_WorldGeometry->Project(atPt3d_mm, vec3d_mm, projectedVec3d_mm);
}
else
{
return false;
}
}
bool mitk::DisplayGeometry::Map(const Point3D &pt3d_mm, Point2D &pt2d_mm) const
{
if(m_WorldGeometry.IsNotNull())
{
return m_WorldGeometry->Map(pt3d_mm, pt2d_mm);
}
else
{
return false;
}
}
void mitk::DisplayGeometry::Map(const Point2D &pt2d_mm, Point3D &pt3d_mm) const
{
if(m_WorldGeometry.IsNull()) return;
m_WorldGeometry->Map(pt2d_mm, pt3d_mm);
}
bool mitk::DisplayGeometry::Map(const Point3D & atPt3d_mm, const Vector3D &vec3d_mm, Vector2D &vec2d_mm) const
{
if(m_WorldGeometry.IsNotNull())
{
return m_WorldGeometry->Map(atPt3d_mm, vec3d_mm, vec2d_mm);
}
else
{
return false;
}
}
void mitk::DisplayGeometry::Map(const Point2D & atPt2d_mm, const Vector2D &vec2d_mm, Vector3D &vec3d_mm) const
{
if(m_WorldGeometry.IsNull()) return;
m_WorldGeometry->Map(atPt2d_mm, vec2d_mm, vec3d_mm);
}
// protected methods
mitk::DisplayGeometry::DisplayGeometry()
:m_ScaleFactorMMPerDisplayUnit(1.0)
,m_WorldGeometry(NULL)
,m_ConstrainZoomingAndPanning(true)
,m_MaxWorldViewPercentage(1.0)
,m_MinWorldViewPercentage(0.1)
{
m_OriginInMM.Fill(0.0);
m_OriginInDisplayUnits.Fill(0.0);
m_SizeInMM.Fill(1.0);
m_SizeInDisplayUnits.Fill(10.0);
}
mitk::DisplayGeometry::~DisplayGeometry()
{
}
bool mitk::DisplayGeometry::RefitVisibleRect()
{
// do nothing if not asked to
if (!m_ConstrainZoomingAndPanning) return false;
// don't allow recursion (need to be fixed, singleton)
static bool inRecalculate = false;
if (inRecalculate) return false;
inRecalculate = true;
// rename some basic measures of the current viewport and world geometry (MM = milimeters Px = Pixels = display units)
float displayXMM = m_OriginInMM[0];
float displayYMM = m_OriginInMM[1];
float displayWidthPx = m_SizeInDisplayUnits[0];
float displayHeightPx = m_SizeInDisplayUnits[1];
float displayWidthMM = m_SizeInDisplayUnits[0] * m_ScaleFactorMMPerDisplayUnit;
float displayHeightMM = m_SizeInDisplayUnits[1] * m_ScaleFactorMMPerDisplayUnit;
float worldWidthMM = m_WorldGeometry->GetParametricExtentInMM(0);
float worldHeightMM = m_WorldGeometry->GetParametricExtentInMM(1);
// reserve variables for the correction logic to save a corrected origin and zoom factor
Vector2D newOrigin = m_OriginInMM;
bool correctPanning = false;
float newScaleFactor = m_ScaleFactorMMPerDisplayUnit;
bool correctZooming = false;
// start of the correction logic
// zoom to big means:
// at a given percentage of the world's width/height should be visible. Otherwise
// the whole screen could show only one pixel
//
// zoom to small means:
// zooming out should be limited at the point where the smaller of the world's sides is completely visible
bool zoomXtooSmall = displayWidthPx * m_ScaleFactorMMPerDisplayUnit > m_MaxWorldViewPercentage * worldWidthMM;
bool zoomXtooBig = displayWidthPx * m_ScaleFactorMMPerDisplayUnit < m_MinWorldViewPercentage * worldWidthMM;
bool zoomYtooSmall = displayHeightPx * m_ScaleFactorMMPerDisplayUnit > m_MaxWorldViewPercentage * worldHeightMM;
bool zoomYtooBig = displayHeightPx * m_ScaleFactorMMPerDisplayUnit < m_MinWorldViewPercentage * worldHeightMM;
// constrain zooming in both direction
if ( zoomXtooBig && zoomYtooBig)
{
double fx = worldWidthMM * m_MinWorldViewPercentage / displayWidthPx;
double fy = worldHeightMM * m_MinWorldViewPercentage / displayHeightPx;
newScaleFactor = fx < fy ? fx : fy;
correctZooming = true;
}
// constrain zooming in x direction
else if ( zoomXtooBig )
{
newScaleFactor = worldWidthMM * m_MinWorldViewPercentage / displayWidthPx;
correctZooming = true;
}
// constrain zooming in y direction
else if ( zoomYtooBig )
{
newScaleFactor = worldHeightMM * m_MinWorldViewPercentage / displayHeightPx;
correctZooming = true;
}
// constrain zooming out
// we stop zooming out at these situations:
//
// *** display
// --- image
//
// **********************
// * * x side maxed out
// * *
// *--------------------*
// *| |*
// *| |*
// *--------------------*
// * *
// * *
// * *
// **********************
//
// **********************
// * |------| * y side maxed out
// * | | *
// * | | *
// * | | *
// * | | *
// * | | *
// * | | *
// * | | *
// * |------| *
// **********************
//
// In both situations we center the not-maxed out direction
//
if ( zoomXtooSmall && zoomYtooSmall )
{
// determine and set the bigger scale factor
float fx = worldWidthMM * m_MaxWorldViewPercentage / displayWidthPx;
float fy = worldHeightMM * m_MaxWorldViewPercentage / displayHeightPx;
newScaleFactor = fx > fy ? fx : fy;
correctZooming = true;
}
// actually execute correction
if (correctZooming)
{
SetScaleFactor(newScaleFactor);
}
displayWidthMM = m_SizeInDisplayUnits[0] * m_ScaleFactorMMPerDisplayUnit;
displayHeightMM = m_SizeInDisplayUnits[1] * m_ScaleFactorMMPerDisplayUnit;
// constrain panning
if(worldWidthMM<displayWidthMM)
{
// zoomed out too much in x (but tolerated because y is still ok)
// --> center x
newOrigin[0] = (worldWidthMM - displayWidthMM) / 2.0;
correctPanning = true;
}
else
{
// make sure left display border inside our world
if (displayXMM < 0)
{
newOrigin[0] = 0;
correctPanning = true;
}
// make sure right display border inside our world
else if (displayXMM + displayWidthMM > worldWidthMM)
{
newOrigin[0] = worldWidthMM - displayWidthMM;
correctPanning = true;
}
}
if (worldHeightMM<displayHeightMM)
{
// zoomed out too much in y (but tolerated because x is still ok)
// --> center y
newOrigin[1] = (worldHeightMM - displayHeightMM) / 2.0;
correctPanning = true;
}
else
{
// make sure top display border inside our world
if (displayYMM + displayHeightMM > worldHeightMM)
{
newOrigin[1] = worldHeightMM - displayHeightMM;
correctPanning = true;
}
// make sure bottom display border inside our world
else
if (displayYMM < 0)
{
newOrigin[1] = 0;
correctPanning = true;
}
}
if (correctPanning)
{
SetOriginInMM( newOrigin );
}
inRecalculate = false;
if ( correctPanning || correctZooming )
{
Modified();
}
// return true if any correction has been made
return correctPanning || correctZooming;
}
void mitk::DisplayGeometry::PrintSelf(std::ostream& os, itk::Indent indent) const
{
if(m_WorldGeometry.IsNull())
{
os << indent << " WorldGeometry: " << "NULL" << std::endl;
}
else
{
m_WorldGeometry->Print(os, indent);
os << indent << " OriginInMM: " << m_OriginInMM << std::endl;
os << indent << " OriginInDisplayUnits: " << m_OriginInDisplayUnits << std::endl;
os << indent << " SizeInMM: " << m_SizeInMM << std::endl;
os << indent << " SizeInDisplayUnits: " << m_SizeInDisplayUnits << std::endl;
os << indent << " ScaleFactorMMPerDisplayUni: " << m_ScaleFactorMMPerDisplayUnit << std::endl;
}
Superclass::PrintSelf(os,indent);
}
diff --git a/Core/Code/DataManagement/mitkDisplayGeometry.h b/Core/Code/DataManagement/mitkDisplayGeometry.h
index aa7ec4137c..a1a3882206 100644
--- a/Core/Code/DataManagement/mitkDisplayGeometry.h
+++ b/Core/Code/DataManagement/mitkDisplayGeometry.h
@@ -1,228 +1,227 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 mitkDisplayGeometry_h
#define mitkDisplayGeometry_h
#include "mitkGeometry2D.h"
namespace mitk
{
/**
\brief Describes the geometry on the display/screen for 2D display.
The main purpose of this class is to convert between display coordinates
(in display-units) and world coordinates (in mm).
DisplayGeometry depends on the size of the display area (widget width and
height, m_SizeInDisplayUnits) and on a Geometry2D (m_WoldGeometry). It
represents a recangular view on this world-geometry. E.g., you can tell
the DisplayGeometry to fit the world-geometry in the display area by
calling Fit(). Provides methods for zooming and panning.
Zooming and panning can be restricted within reasonable bounds by setting
the ConstrainZoomingAndPanning flag. In these cases you can re-define what
bounds you accept as "reasonable" by calling
\warning \em Units refers to the units of the underlying world-geometry.
Take care, whether these are really the units you want to convert to.
E.g., when you want to convert a point \a pt_display (which is 2D) given
in display coordinates into a point in units of a BaseData-object @a datum
(the requested point is 3D!), use
\code
displaygeometry->DisplayToWorld(pt_display, pt2d_mm);
displaygeometry->Map(pt2d_mm, pt3d_mm);
datum->GetGeometry()->WorldToIndex(pt3d_mm, pt3d_datum_units);
\endcode
Even, if you want to convert the 2D point \a pt_display into a 2D point in
units on a certain 2D geometry \a certaingeometry, it is safer to use
\code
displaygeometry->DisplayToWorld(pt_display, pt_mm);
certaingeometry->WorldToIndex(pt_mm, pt_certain_geometry_units);
\endcode
unless you can be sure that the underlying geometry of \a displaygeometry
is really the \a certaingeometry.
\ingroup Geometry
*/
class MITK_CORE_EXPORT DisplayGeometry : public Geometry2D
{
public:
mitkClassMacro(DisplayGeometry,Geometry2D);
/// Method for creation through the object factory.
itkNewMacro(Self);
/// \brief duplicates the geometry, NOT useful for this sub-class
virtual AffineGeometryFrame3D::Pointer Clone() const;
virtual bool IsValid() const;
/// \return this objects modified time.
virtual unsigned long GetMTime() const;
virtual const TimeBounds& GetTimeBounds() const;
// size definition methods
virtual void SetWorldGeometry(const Geometry2D* aWorldGeometry);
itkGetConstObjectMacro(WorldGeometry, Geometry2D);
/// \return if new origin was within accepted limits
virtual bool SetOriginInMM(const Vector2D& origin_mm);
virtual Vector2D GetOriginInMM() const;
virtual Vector2D GetOriginInDisplayUnits() const;
/**
\brief Set the size of the display in display units.
This method must be called every time the display is resized (normally, the GUI-toolkit
informs about resizing).
\param keepDisplayedRegion: if \a true (the default), the displayed contents is zoomed/shrinked
so that the displayed region is (approximately) the same as before: The point at the center will
be kept at the center and the length of the diagonal of the displayed region \em in \em units
will also be kept.
When the aspect ration changes, the displayed region includes the old displayed region, but
cannot be exaclty the same.
*/
virtual void SetSizeInDisplayUnits(unsigned int width, unsigned int height, bool keepDisplayedRegion=true);
virtual Vector2D GetSizeInDisplayUnits() const;
virtual Vector2D GetSizeInMM() const;
unsigned int GetDisplayWidth() const;
unsigned int GetDisplayHeight() const;
// zooming, panning, restriction of both
virtual void SetConstrainZoomingAndPanning(bool constrain);
virtual bool GetConstrainZommingAndPanning() const;
/// what percentage of the world should be visible at maximum zoom out (default 1.0, i.e. 100% of width or height)
itkGetMacro(MaxWorldViewPercentage, float);
itkSetMacro(MaxWorldViewPercentage, float);
/// what percentage of the world should be visible at maximum zoom in (default 0.1, i.e. 10% of width or height)
itkGetMacro(MinWorldViewPercentage, float);
itkSetMacro(MinWorldViewPercentage, float);
virtual bool SetScaleFactor(ScalarType mmPerDisplayUnit);
ScalarType GetScaleFactorMMPerDisplayUnit() const;
/**
* \brief Zooms with a factor (1.0=identity) to/from the specified center in display units
* \return true if zoom request was within accepted limits
*/
virtual bool Zoom(ScalarType factor, const Point2D& centerInDisplayUnits);
/**
* \brief Zooms with a factor (1.0=identity) to/from the specified center, trying to preserve the center of zoom in world coordiantes
*
* Same zoom as mentioned above but tries (if it's within view contraints) to match the center in display units with the center in world coordinates.
*
* \return true if zoom request was within accepted limits
*/
virtual bool ZoomWithFixedWorldCoordinates(ScalarType factor, const Point2D& focusDisplayUnits, const Point2D& focusUnitsInMM );
// \return true if move request was within accepted limits
virtual bool MoveBy(const Vector2D& shiftInDisplayUnits);
// \brief align display with world, make world completely visible
virtual void Fit();
// conversion methods
virtual void DisplayToWorld(const Point2D &pt_display, Point2D &pt_mm) const;
virtual void WorldToDisplay(const Point2D &pt_mm, Point2D &pt_display) const;
virtual void DisplayToWorld(const Vector2D &vec_display, Vector2D &vec_mm) const;
virtual void WorldToDisplay(const Vector2D &vec_mm, Vector2D &vec_display) const;
virtual void ULDisplayToMM(const Point2D &pt_ULdisplay, Point2D &pt_mm) const;
virtual void MMToULDisplay(const Point2D &pt_mm, Point2D &pt_ULdisplay) const;
virtual void ULDisplayToMM(const Vector2D &vec_ULdisplay, Vector2D &vec_mm) const;
virtual void MMToULDisplay(const Vector2D &vec_mm, Vector2D &vec_ULdisplay) const;
virtual void ULDisplayToDisplay(const Point2D &pt_ULdisplay, Point2D &pt_display) const;
virtual void DisplayToULDisplay(const Point2D &pt_display, Point2D &pt_ULdisplay) const;
virtual void ULDisplayToDisplay(const Vector2D &vec_ULdisplay, Vector2D &vec_display) const;
virtual void DisplayToULDisplay(const Vector2D &vec_display, Vector2D &vec_ULdisplay) const;
virtual bool Project(const Point3D &pt3d_mm, Point3D &projectedPt3d_mm) const;
virtual bool Project(const Point3D & atPt3d_mm, const Vector3D &vec3d_mm, Vector3D &projectedVec3d_mm) const;
virtual bool Map(const Point3D &pt3d_mm, Point2D &pt2d_mm) const;
virtual void Map(const Point2D &pt2d_mm, Point3D &pt3d_mm) const;
virtual bool Map(const Point3D & atPt3d_mm, const Vector3D &vec3d_mm, Vector2D &vec2d_mm) const;
virtual void Map(const Point2D & atPt2d_mm, const Vector2D &vec2d_mm, Vector3D &vec3d_mm) const;
protected:
DisplayGeometry();
virtual ~DisplayGeometry();
/**
\brief Called after zooming/panning to restrict these operations to sensible measures.
\return true if a correction in either zooming or panning was made
Enforces a couple of constraints on the relation of the current viewport and the current world geometry.
The basic logic in this lengthy method is:
<ol>
<li> Make display region big enough (in case of too large zoom factors)
<li> Make display region small enough (so that the image cannot be scaled into a single screen pixel
<li> Correct panning for each border (left, right, bottom, top)
</ol>
The little more complicated implementation is illustrated in the code itself.
*/
virtual bool RefitVisibleRect();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
Vector2D m_OriginInMM;
Vector2D m_OriginInDisplayUnits;
ScalarType m_ScaleFactorMMPerDisplayUnit;
Vector2D m_SizeInMM;
Vector2D m_SizeInDisplayUnits;
Geometry2D::ConstPointer m_WorldGeometry;
bool m_ConstrainZoomingAndPanning;
float m_MaxWorldViewPercentage;
float m_MinWorldViewPercentage;
};
} // namespace
#endif // include guard
diff --git a/Core/Code/DataManagement/mitkEnumerationProperty.cpp b/Core/Code/DataManagement/mitkEnumerationProperty.cpp
index 4cdcc2dbfd..ccc0951dd5 100644
--- a/Core/Code/DataManagement/mitkEnumerationProperty.cpp
+++ b/Core/Code/DataManagement/mitkEnumerationProperty.cpp
@@ -1,196 +1,195 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkEnumerationProperty.h"
#include <algorithm>
// static map members of EnumerationProperty. These Maps point to per-classname-maps of ID <-> String. Accessed by GetEnumIds() and GetEnumString().
mitk::EnumerationProperty::IdMapForClassNameContainerType mitk::EnumerationProperty::s_IdMapForClassName;
mitk::EnumerationProperty::StringMapForClassNameContainerType mitk::EnumerationProperty::s_StringMapForClassName;
mitk::EnumerationProperty::EnumerationProperty()
{
m_CurrentValue = 0;
}
bool mitk::EnumerationProperty::AddEnum( const std::string& name, const IdType& id )
{
if ( ( ! IsValidEnumerationValue( name ) ) && ( ! IsValidEnumerationValue( id ) ) )
{
GetEnumIds().insert( std::make_pair( id, name ) );
GetEnumStrings().insert( std::make_pair( name, id ) );
return true;
}
else
{
return false;
}
}
bool mitk::EnumerationProperty::SetValue( const std::string& name )
{
if ( IsValidEnumerationValue( name ) )
{
m_CurrentValue = GetEnumId( name );
Modified();
return true;
}
else
{
return false;
}
}
bool mitk::EnumerationProperty::SetValue( const IdType& id )
{
if ( IsValidEnumerationValue( id ) )
{
m_CurrentValue = id;
Modified();
return true;
}
else
{
return false;
}
}
mitk::EnumerationProperty::IdType mitk::EnumerationProperty::GetValueAsId() const
{
return m_CurrentValue;
}
std::string mitk::EnumerationProperty::GetValueAsString() const
{
return GetEnumString( m_CurrentValue );
}
void mitk::EnumerationProperty::Clear()
{
GetEnumIds().clear();
GetEnumStrings().clear();
m_CurrentValue = 0;
}
mitk::EnumerationProperty::EnumIdsContainerType::size_type mitk::EnumerationProperty::Size() const
{
return GetEnumIds().size();
}
mitk::EnumerationProperty::EnumConstIterator mitk::EnumerationProperty::Begin() const
{
return GetEnumIds().begin();
}
mitk::EnumerationProperty::EnumConstIterator mitk::EnumerationProperty::End() const
{
return GetEnumIds().end();
}
std::string mitk::EnumerationProperty::GetEnumString( const IdType& id ) const
{
if ( IsValidEnumerationValue( id ) )
{
return GetEnumIds().find( id )->second;
}
else
{
return "invalid enum id or enums empty";
}
}
mitk::EnumerationProperty::IdType mitk::EnumerationProperty::GetEnumId( const std::string& name ) const
{
if ( IsValidEnumerationValue( name ) )
{
return GetEnumStrings().find( name )->second;
}
else
{
return 0;
}
}
bool mitk::EnumerationProperty::IsEqual( const BaseProperty& property ) const
{
const Self& other = static_cast<const Self&>(property);
return this->Size() == other.Size() && this->GetValueAsId() == other.GetValueAsId() &&
std::equal( this->Begin(), this->End(), other.Begin() );
}
bool mitk::EnumerationProperty::Assign( const BaseProperty& property )
{
const Self& other = static_cast<const Self&>(property);
this->GetEnumIds() = other.GetEnumIds();
this->GetEnumStrings() = other.GetEnumStrings();
this->m_CurrentValue = other.m_CurrentValue;
this->Size() == other.Size() && this->GetValueAsId() == other.GetValueAsId() &&
std::equal( this->Begin(), this->End(), other.Begin() );
return true;
}
bool mitk::EnumerationProperty::IsValidEnumerationValue( const IdType& val ) const
{
return ( GetEnumIds().find( val ) != GetEnumIds().end() );
}
bool mitk::EnumerationProperty::IsValidEnumerationValue( const std::string& val ) const
{
return ( GetEnumStrings().find( val ) != GetEnumStrings().end() );
}
mitk::EnumerationProperty::EnumIdsContainerType& mitk::EnumerationProperty::GetEnumIds()
{
std::string className = this->GetNameOfClass(); // virtual!
return s_IdMapForClassName[ className ];
}
const mitk::EnumerationProperty::EnumIdsContainerType& mitk::EnumerationProperty::GetEnumIds() const
{
std::string className = this->GetNameOfClass(); // virtual!
return s_IdMapForClassName[ className ];
}
mitk::EnumerationProperty::EnumStringsContainerType& mitk::EnumerationProperty::GetEnumStrings()
{
std::string className = this->GetNameOfClass(); // virtual!
return s_StringMapForClassName[ className ];
}
const mitk::EnumerationProperty::EnumStringsContainerType& mitk::EnumerationProperty::GetEnumStrings() const
{
std::string className = this->GetNameOfClass(); // virtual!
return s_StringMapForClassName[ className ];
}
diff --git a/Core/Code/DataManagement/mitkEnumerationProperty.h b/Core/Code/DataManagement/mitkEnumerationProperty.h
index 04db8b1c8c..247b1e27a7 100644
--- a/Core/Code/DataManagement/mitkEnumerationProperty.h
+++ b/Core/Code/DataManagement/mitkEnumerationProperty.h
@@ -1,226 +1,225 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 _MITK_ENUMERATION_PROPERTY__H_
#define _MITK_ENUMERATION_PROPERTY__H_
#include "mitkBaseProperty.h"
#include <map>
#include <string>
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* This class may be used to store properties similar to enumeration values.
* Each enumeration value is identified via a string representation and a
* id. Note, that both string representation and id MUST be unique. This is checked
* when inserting a new enumeration value. Please note that you have to add valid
* enumeration values before you may use the Get/SetValue methods.
*
* To use the class enumeration property you have 2 choices:
*
* 1. Directly use the class and add your possible enumeration values via
* AddEnum(name, id). NOte that the ids do not have to be in any order, they
* just have to be unique. The current value is set via SetValue(...) and
* retrieved via GetValueAsId() or GetValueAsString().
* 2. Create a subclass, which adds the possible enumeration values in its
* constructor and maybe adds some additional convenience functions to
* set/get the value. NOte that you should override AddEnum(...) as protected
* so that the user may not add additional invalid enumeration values.
* As example see mitk::VtkRepresentationProperty or mitk::VtkInterpolationProperty
*
* @ingroup DataManagement
*/
class MITK_CORE_EXPORT EnumerationProperty : public BaseProperty
{
public:
mitkClassMacro( EnumerationProperty, BaseProperty );
itkNewMacro(EnumerationProperty);
/**
* Represents the unique id which is asigned to each enumeration value
*/
typedef unsigned int IdType;
/**
* Type used to store a mapping from enumeration id to enumeration string/
* description
*/
typedef std::map<IdType, std::string> EnumIdsContainerType;
/**
* Type used to store a mapping from enumeration string/description to
* enumeration id
*/
typedef std::map<std::string, IdType> EnumStringsContainerType;
/**
* Type used for iterators over all defined enumeration values.
*/
typedef EnumIdsContainerType::const_iterator EnumConstIterator;
/**
* Adds an enumeration value into the enumeration. The name and id provided
* must be unique. This is checked while adding the new enumeration value.
* If it is not unique, false is returned. If addition was successful, true
* is returned.
* @param name the unique string representation of the enumeration value
* @param id the unique integer representation of the enumeration value
* @returns true, if the name/id combination was successfully added to the
* enumeration values or true otherwise
*/
virtual bool AddEnum( const std::string& name, const IdType& id );
/**
* Sets the current value of the enumeration
* @param name the string representation of the enumeration value to set
* @returns true if the value was successfully set (i.e. it was valid), or
* false, if the name provided is incalid.
*/
virtual bool SetValue( const std::string& name );
/**
* Sets the current value of the enumeration
* @param id the integer representation of the enumeration value to set
* @returns true if the value was successfully set (i.e. it was valid), or
* false, if the id provided is invalid.
*/
virtual bool SetValue( const IdType& id );
/**
* Returns the id of the current enumeration value. If it was not yet set,
* the return value is unspecified
*/
virtual IdType GetValueAsId() const;
/**
* Returns the string representation of the current enumeration value. If it
* was not yet set, the return value is unspecified
*/
virtual std::string GetValueAsString() const;
/**
* Clears all possible enumeration values and the current enumeration value.
*/
virtual void Clear();
/**
* Determines the number of enumeration values which have been added via
* AddEnum(...).
* @returns the number of enumeration values associated with this Enumeration
* Property
*/
virtual EnumIdsContainerType::size_type Size() const;
/**
* Provides access to the set of known enumeration values. The string representation
* may be accessed via iterator->second, the id may be access via iterator->first
* @returns an iterator over all enumeration values.
*/
virtual EnumConstIterator Begin() const;
/**
* Specifies the end of the range of the known enumeration values.
* @returns an iterator pointing past the last known element of the possible
* enumeration values.
*/
virtual EnumConstIterator End() const;
/**
* Returns the string representation for the given id.
* @param id the id for which the string representation should be determined
* if id is invalid, the return value is unspecified.
* @returns the string representation of the given enumeration value
*/
virtual std::string GetEnumString( const IdType& id ) const;
/**
* Returns the integer representation for the given string.
* @param name the enumeration name for which the integer representation should be determined
* if the name is invalid, the return value is unspecified.
* @returns the integer representation of the given enumeration value
*/
virtual IdType GetEnumId( const std::string& name ) const;
/**
* Determines if a given integer representation of an enumeration value
* is valid or not
* @param val the integer value to check
* @returns true if the given value is valid or false otherwise
*/
virtual bool IsValidEnumerationValue( const IdType& val ) const;
/**
* Determines if a given string representation of an enumeration value
* is valid or not
* @param val the string to check
* @returns true if the given value is valid or false otherwise
*/
virtual bool IsValidEnumerationValue( const std::string& val ) const;
const EnumIdsContainerType& GetEnumIds() const;
const EnumStringsContainerType& GetEnumStrings() const;
EnumIdsContainerType& GetEnumIds();
EnumStringsContainerType& GetEnumStrings();
using BaseProperty::operator=;
protected:
/**
* Default constructor. The current value of the enumeration is undefined.
*/
EnumerationProperty();
virtual bool IsEqual( const BaseProperty& property ) const;
virtual bool Assign( const BaseProperty& property );
private:
// purposely not implemented
EnumerationProperty(const EnumerationProperty&);
EnumerationProperty& operator=(const EnumerationProperty&);
IdType m_CurrentValue;
typedef std::map<std::string, EnumIdsContainerType> IdMapForClassNameContainerType;
typedef std::map<std::string, EnumStringsContainerType> StringMapForClassNameContainerType;
static IdMapForClassNameContainerType s_IdMapForClassName;
static StringMapForClassNameContainerType s_StringMapForClassName;
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace
#endif
diff --git a/Core/Code/DataManagement/mitkGenericLookupTable.h b/Core/Code/DataManagement/mitkGenericLookupTable.h
index baec1dcadc..2fce3afe13 100644
--- a/Core/Code/DataManagement/mitkGenericLookupTable.h
+++ b/Core/Code/DataManagement/mitkGenericLookupTable.h
@@ -1,162 +1,161 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-06-24 19:37:48 +0200 (Di, 24 Jun 2008) $
-Version: $Revision: 14641 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGENERICLOOKUPTABLE_H_HEADER_INCLUDED_C1061CEE
#define MITKGENERICLOOKUPTABLE_H_HEADER_INCLUDED_C1061CEE
#include <string>
#include <sstream>
#include <stdlib.h>
#include <map>
#include <itkDataObject.h>
#include "mitkVector.h"
#include <MitkExports.h>
namespace mitk {
/**
* @brief Template class for generating lookup-tables
*
* This class template can be instantiated for all classes/internal types that fulfills
* these requirements:
* - an operator<< so that the properties value can be put into a std::stringstream
* - an operator== so that two properties can be checked for equality
*
* The main purpose of this class is to be used in conjunction with
* GenericLookupTableProperty. This enables passing of arbitrary lookup
* tables to mappers to configure the rendering process.
*/
template <typename T>
class GenericLookupTable
{
public:
typedef unsigned int IdentifierType;
typedef T ValueType;
typedef std::map< IdentifierType, ValueType > LookupTableType;
typedef GenericLookupTable Self;
GenericLookupTable() {}
virtual ~GenericLookupTable()
{
}
virtual const char *GetNameOfClass() const
{
return "GenericLookupTable";
}
void SetTableValue( IdentifierType id, ValueType value )
{
m_LookupTable[id] = value;
}
bool ValueExists(IdentifierType id) const
{
typename LookupTableType::const_iterator it = m_LookupTable.find(id);
return (it != m_LookupTable.end());
}
ValueType GetTableValue( IdentifierType id ) const
{
typename LookupTableType::const_iterator it = m_LookupTable.find(id);
if (it != m_LookupTable.end())
return it->second;
else
throw std::range_error("id does not exist in the lookup table");
}
const LookupTableType& GetLookupTable() const
{
return m_LookupTable;
}
bool operator==( const Self& lookupTable ) const
{
return (m_LookupTable == lookupTable.m_LookupTable);
}
bool operator!=( const Self& lookupTable ) const
{
return !(m_LookupTable == lookupTable.m_LookupTable);
}
virtual Self& operator=(const Self& other) // \TODO: this needs to be unit tested!
{
if ( this == &other )
{
return *this;
}
else
{
m_LookupTable.clear();
m_LookupTable = other.m_LookupTable;
return *this;
}
}
protected:
LookupTableType m_LookupTable;
};
} // namespace mitk
/**
* Generates a specialized subclass of mitk::GenericLookupTable.
* This way, GetNameOfClass() returns the value provided by LookupTableName.
* Please see mitkProperties.h for examples.
* @param LookupTableName the name of the instantiation of GenericLookupTable
* @param Type the value type of the GenericLookupTable
*/
#define mitkSpecializeGenericLookupTable(LookupTableName,Type) \
class MITK_CORE_EXPORT LookupTableName: public GenericLookupTable< Type > \
{ \
public: \
typedef LookupTableName Self; \
typedef GenericLookupTable< Type > Superclass; \
virtual const char *GetNameOfClass() const \
{return #LookupTableName;} \
LookupTableName() {} \
virtual Superclass& operator=(const Superclass& other) { return Superclass::operator=(other); } \
virtual ~LookupTableName() {} \
}; \
MITK_CORE_EXPORT std::ostream& operator<<(std::ostream& stream, const LookupTableName& /*l*/);
/**
* Generates the ostream << operator for the lookuptable. This definition
* of a global function must be in a cpp file, therefore it is split from the
* class declaration macro mitkSpecializeGenericLookupTable.
*/
#define mitkSpecializeGenericLookupTableOperator(LookupTableName) \
std::ostream& mitk::operator<<(std::ostream& stream, const LookupTableName& l) \
{ \
typedef LookupTableName::LookupTableType::const_iterator IterType; \
IterType e = l.GetLookupTable().end(); \
IterType b = l.GetLookupTable().begin(); \
stream << "["; \
for (IterType i = b; i != e; ++i) \
{ \
if (i != b) \
{ \
stream << ", "; \
} \
stream << i->first << " -> " << i->second; \
} \
return stream << "]"; \
};
#endif
diff --git a/Core/Code/DataManagement/mitkGenericProperty.h b/Core/Code/DataManagement/mitkGenericProperty.h
index 8d8778afde..2d8167ba26 100644
--- a/Core/Code/DataManagement/mitkGenericProperty.h
+++ b/Core/Code/DataManagement/mitkGenericProperty.h
@@ -1,128 +1,127 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGENERICPROPERTY_H_HEADER_INCLUDED_C1061CEE
#define MITKGENERICPROPERTY_H_HEADER_INCLUDED_C1061CEE
#include <string>
#include <sstream>
#include <stdlib.h>
#include "mitkVector.h"
#include <MitkExports.h>
#include "mitkBaseProperty.h"
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/*!
@ brief Template class for generating properties for int, float, bool, etc.
This class template can be instantiated for all classes/internal types that fulfills
these requirements:
- an operator<< so that the properties value can be put into a std::stringstream
- an operator== so that two properties can be checked for equality
Note: you must use the macro mitkSpecializeGenericProperty to provide specializations
for concrete types (e.g. BoolProperty). Please see mitkProperties.h for examples. If you
don't use the mitkSpecializeGenericProperty Macro, GetNameOfClass() returns a wrong name.
*/
template <typename T>
class MITK_EXPORT GenericProperty : public BaseProperty
{
public:
mitkClassMacro(GenericProperty, BaseProperty);
mitkNewMacro1Param(GenericProperty<T>, T);
typedef T ValueType;
itkSetMacro(Value,T);
itkGetConstMacro(Value,T);
virtual std::string GetValueAsString() const
{
std::stringstream myStr;
myStr << GetValue() ;
return myStr.str();
}
using BaseProperty::operator=;
protected:
GenericProperty() {}
GenericProperty(T x)
: m_Value(x) {}
T m_Value;
private:
// purposely not implemented
GenericProperty(const GenericProperty&);
GenericProperty& operator=(const GenericProperty&);
virtual bool IsEqual(const BaseProperty& other) const
{
return (this->m_Value == static_cast<const Self&>(other).m_Value);
}
virtual bool Assign(const BaseProperty& other)
{
this->m_Value = static_cast<const Self&>(other).m_Value;
return true;
}
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
/**
* Generates a specialized subclass of mitk::GenericProperty.
* This way, GetNameOfClass() returns the value provided by PropertyName.
* Please see mitkProperties.h for examples.
* @param PropertyName the name of the subclass of GenericProperty
* @param Type the value type of the GenericProperty
* @param Export the export macro for DLL usage
*/
#define mitkDeclareGenericProperty(PropertyName,Type,Export) \
class Export PropertyName: public GenericProperty< Type > \
{ \
public: \
mitkClassMacro(PropertyName, GenericProperty< Type >); \
itkNewMacro(PropertyName); \
mitkNewMacro1Param(PropertyName, Type); \
using BaseProperty::operator=; \
protected: \
PropertyName(); \
PropertyName(Type x); \
};
#define mitkDefineGenericProperty(PropertyName,Type,DefaultValue) \
mitk::PropertyName::PropertyName() : Superclass(DefaultValue) { } \
mitk::PropertyName::PropertyName(Type x) : Superclass(x) {}
#endif /* MITKGENERICPROPERTY_H_HEADER_INCLUDED_C1061CEE */
diff --git a/Core/Code/DataManagement/mitkGeometry2D.cpp b/Core/Code/DataManagement/mitkGeometry2D.cpp
index 3dfdb48c34..1230129597 100644
--- a/Core/Code/DataManagement/mitkGeometry2D.cpp
+++ b/Core/Code/DataManagement/mitkGeometry2D.cpp
@@ -1,273 +1,272 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGeometry2D.h"
#include <vtkTransform.h>
mitk::Geometry2D::Geometry2D()
: m_ScaleFactorMMPerUnitX( 1.0 ),
m_ScaleFactorMMPerUnitY( 1.0 ),
m_ReferenceGeometry( NULL )
{
}
mitk::Geometry2D::Geometry2D(const Geometry2D& other)
: Geometry3D(other), m_ScaleFactorMMPerUnitX( other.m_ScaleFactorMMPerUnitX),
m_ScaleFactorMMPerUnitY( other.m_ScaleFactorMMPerUnitY),
m_ReferenceGeometry( other.m_ReferenceGeometry )
{
}
mitk::Geometry2D::~Geometry2D()
{
}
void
mitk::Geometry2D::SetIndexToWorldTransform(
mitk::AffineTransform3D* transform)
{
Superclass::SetIndexToWorldTransform(transform);
m_ScaleFactorMMPerUnitX=GetExtentInMM(0)/GetExtent(0);
m_ScaleFactorMMPerUnitY=GetExtentInMM(1)/GetExtent(1);
assert(m_ScaleFactorMMPerUnitX<ScalarTypeNumericTraits::infinity());
assert(m_ScaleFactorMMPerUnitY<ScalarTypeNumericTraits::infinity());
}
void
mitk::Geometry2D::SetExtentInMM(int direction, ScalarType extentInMM)
{
Superclass::SetExtentInMM(direction, extentInMM);
m_ScaleFactorMMPerUnitX=GetExtentInMM(0)/GetExtent(0);
m_ScaleFactorMMPerUnitY=GetExtentInMM(1)/GetExtent(1);
assert(m_ScaleFactorMMPerUnitX<ScalarTypeNumericTraits::infinity());
assert(m_ScaleFactorMMPerUnitY<ScalarTypeNumericTraits::infinity());
}
bool
mitk::Geometry2D::Map(
const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
{
assert(m_BoundingBox.IsNotNull());
Point3D pt3d_units;
BackTransform(pt3d_mm, pt3d_units);
pt2d_mm[0]=pt3d_units[0]*m_ScaleFactorMMPerUnitX;
pt2d_mm[1]=pt3d_units[1]*m_ScaleFactorMMPerUnitY;
pt3d_units[2]=0;
return const_cast<BoundingBox*>(m_BoundingBox.GetPointer())->IsInside(pt3d_units);
}
void
mitk::Geometry2D::Map(const mitk::Point2D &pt2d_mm, mitk::Point3D &pt3d_mm) const
{
Point3D pt3d_units;
pt3d_units[0]=pt2d_mm[0]/m_ScaleFactorMMPerUnitX;
pt3d_units[1]=pt2d_mm[1]/m_ScaleFactorMMPerUnitY;
pt3d_units[2]=0;
pt3d_mm = GetParametricTransform()->TransformPoint(pt3d_units);
}
void
mitk::Geometry2D::IndexToWorld(
const mitk::Point2D &/*pt_units*/, mitk::Point2D &/*pt_mm*/) const
{
itkExceptionMacro(<< "No general transform possible (only affine) ==> no general" \
" IndexToWorld(const mitk::Point2D &pt_mm, mitk::Point2D &pt_units)" \
" possible. Has to be implemented in sub-class.");
}
void
mitk::Geometry2D::WorldToIndex(
const mitk::Point2D &/*pt_mm*/, mitk::Point2D &/*pt_units*/) const
{
itkExceptionMacro(<< "No general back transform possible (only affine) ==> no general" \
" WorldToIndex(const mitk::Point2D &pt_mm, mitk::Point2D &pt_units)" \
" possible. Has to be implemented in sub-class.");
}
void
mitk::Geometry2D::IndexToWorld(const mitk::Point2D &/*atPt2d_units*/,
const mitk::Vector2D &/*vec_units*/, mitk::Vector2D &/*vec_mm*/) const
{
itkExceptionMacro(<< "No general transform possible (only affine) ==> no general" \
" IndexToWorld(const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units)" \
" possible. Has to be implemented in sub-class.");
}
void
mitk::Geometry2D::WorldToIndex(const mitk::Point2D &/*atPt2d_mm*/,
const mitk::Vector2D &/*vec_mm*/, mitk::Vector2D &/*vec_units*/) const
{
itkExceptionMacro(<< "No general back transform possible (only affine) ==> no general" \
" WorldToIndex(const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units)" \
" possible. Has to be implemented in sub-class.");
}
void
mitk::Geometry2D::SetSizeInUnits(mitk::ScalarType width, mitk::ScalarType height)
{
ScalarType bounds[6]={0, width, 0, height, 0, 1};
ScalarType extent, newextentInMM;
if(GetExtent(0)>0)
{
extent = GetExtent(0);
if(width>extent)
newextentInMM = GetExtentInMM(0)/width*extent;
else
newextentInMM = GetExtentInMM(0)*extent/width;
SetExtentInMM(0, newextentInMM);
}
if(GetExtent(1)>0)
{
extent = GetExtent(1);
if(width>extent)
newextentInMM = GetExtentInMM(1)/height*extent;
else
newextentInMM = GetExtentInMM(1)*extent/height;
SetExtentInMM(1, newextentInMM);
}
SetBounds(bounds);
}
bool
mitk::Geometry2D::Project(
const mitk::Point3D &pt3d_mm, mitk::Point3D &projectedPt3d_mm) const
{
assert(m_BoundingBox.IsNotNull());
Point3D pt3d_units;
BackTransform(pt3d_mm, pt3d_units);
pt3d_units[2] = 0;
projectedPt3d_mm = GetParametricTransform()->TransformPoint(pt3d_units);
return const_cast<BoundingBox*>(m_BoundingBox.GetPointer())->IsInside(pt3d_units);
}
bool
mitk::Geometry2D::Map(const mitk::Point3D & atPt3d_mm,
const mitk::Vector3D &vec3d_mm, mitk::Vector2D &vec2d_mm) const
{
Point2D pt2d_mm_start, pt2d_mm_end;
Point3D pt3d_mm_end;
bool inside=Map(atPt3d_mm, pt2d_mm_start);
pt3d_mm_end = atPt3d_mm+vec3d_mm;
inside&=Map(pt3d_mm_end, pt2d_mm_end);
vec2d_mm=pt2d_mm_end-pt2d_mm_start;
return inside;
}
void
mitk::Geometry2D::Map(const mitk::Point2D &/*atPt2d_mm*/,
const mitk::Vector2D &/*vec2d_mm*/, mitk::Vector3D &/*vec3d_mm*/) const
{
//@todo implement parallel to the other Map method!
assert(false);
}
bool
mitk::Geometry2D::Project(const mitk::Point3D & atPt3d_mm,
const mitk::Vector3D &vec3d_mm, mitk::Vector3D &projectedVec3d_mm) const
{
assert(m_BoundingBox.IsNotNull());
Vector3D vec3d_units;
BackTransform(atPt3d_mm, vec3d_mm, vec3d_units);
vec3d_units[2] = 0;
projectedVec3d_mm = GetParametricTransform()->TransformVector(vec3d_units);
Point3D pt3d_units;
BackTransform(atPt3d_mm, pt3d_units);
return const_cast<BoundingBox*>(m_BoundingBox.GetPointer())->IsInside(pt3d_units);
}
mitk::ScalarType
mitk::Geometry2D::SignedDistance(const mitk::Point3D& pt3d_mm) const
{
Point3D projectedPoint;
Project(pt3d_mm, projectedPoint);
Vector3D direction = pt3d_mm-projectedPoint;
ScalarType distance = direction.GetNorm();
if(IsAbove(pt3d_mm) == false)
distance*=-1.0;
return distance;
}
bool
mitk::Geometry2D::IsAbove(const mitk::Point3D& pt3d_mm) const
{
Point3D pt3d_units;
Geometry3D::WorldToIndex(pt3d_mm, pt3d_units);
return (pt3d_units[2] > m_BoundingBox->GetBounds()[4]);
}
mitk::AffineGeometryFrame3D::Pointer
mitk::Geometry2D::Clone() const
{
Self::Pointer newGeometry = new Geometry2D(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
void
mitk::Geometry2D::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os,indent);
os << indent << " ScaleFactorMMPerUnitX: "
<< m_ScaleFactorMMPerUnitX << std::endl;
os << indent << " ScaleFactorMMPerUnitY: "
<< m_ScaleFactorMMPerUnitY << std::endl;
}
void
mitk::Geometry2D::SetReferenceGeometry( mitk::Geometry3D *geometry )
{
m_ReferenceGeometry = geometry;
}
mitk::Geometry3D *
mitk::Geometry2D::GetReferenceGeometry() const
{
return m_ReferenceGeometry;
}
bool
mitk::Geometry2D::HasReferenceGeometry() const
{
return ( m_ReferenceGeometry != NULL );
}
diff --git a/Core/Code/DataManagement/mitkGeometry2D.h b/Core/Code/DataManagement/mitkGeometry2D.h
index da0410306e..c8382dab52 100644
--- a/Core/Code/DataManagement/mitkGeometry2D.h
+++ b/Core/Code/DataManagement/mitkGeometry2D.h
@@ -1,264 +1,263 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 GEOMETRY2D_H_HEADER_INCLUDED_C1F4D8E0
#define GEOMETRY2D_H_HEADER_INCLUDED_C1F4D8E0
#include <MitkExports.h>
#include "mitkGeometry3D.h"
namespace mitk {
/**
* \brief Describes the geometry of a two-dimensional object
*
* Describes a two-dimensional manifold, i.e., to put it simply,
* an object that can be described using a 2D coordinate-system.
*
* Geometry2D can map points between 3D world coordinates
* (in mm) and the described 2D coordinate-system (in mm) by first projecting
* the 3D point onto the 2D manifold and then calculating the 2D-coordinates
* (in mm). These 2D-mm-coordinates can be further converted into
* 2D-unit-coordinates (e.g., pixels), giving a parameter representation of
* the object with parameter values inside a rectangle
* (e.g., [0,0]..[width, height]), which is the bounding box (bounding range
* in z-direction always [0]..[1]).
*
* A Geometry2D describes the 2D representation within a 3D object and is
* therefore itself a Geometry3D (derived from Geometry3D). For example,
* a single CT-image (slice) is 2D in the sense that you can access the
* pixels using 2D-coordinates, but is also 3D, as the pixels are really
* voxels, thus have an extension (thickness) in the 3rd dimension.
*
* Most often, instances of Geometry2D will be used to descibe a plane,
* which is represented by the sub-class PlaneGeometry, but curved
* surfaces are also possible.
*
* Optionally, a reference Geometry3D can be specified, which usually would
* be the geometry associated with the underlying dataset. This is currently
* used for calculating the intersection of inclined / rotated planes
* (represented as Geometry2D) with the bounding box of the associated
* Geometry3D.
*
* \warning The Geometry2Ds are not necessarily up-to-date and not even
* initialized. As described in the previous paragraph, one of the
* Generate-/Copy-/UpdateOutputInformation methods have to initialize it.
* mitk::BaseData::GetGeometry2D() makes sure, that the Geometry2D is
* up-to-date before returning it (by setting the update extent appropriately
* and calling UpdateOutputInformation).
*
* Rule: everything is in mm (or ms for temporal information) if not
* stated otherwise.
* \ingroup Geometry
*/
class MITK_CORE_EXPORT Geometry2D : public mitk::Geometry3D
{
public:
mitkClassMacro(Geometry2D, mitk::Geometry3D);
itkNewMacro(Self);
/**
* \brief Project a 3D point given in mm (\a pt3d_mm) onto the 2D
* geometry. The result is a 2D point in mm (\a pt2d_mm).
*
* The result is a 2D point in mm (\a pt2d_mm) relative to the upper-left
* corner of the geometry. To convert this point into units (e.g., pixels
* in case of an image), use WorldToIndex.
* \return true projection was possible
* \sa Project(const mitk::Point3D &pt3d_mm, mitk::Point3D
* &projectedPt3d_mm)
*/
virtual bool Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const;
/**
* \brief Converts a 2D point given in mm (\a pt2d_mm) relative to the
* upper-left corner of the geometry into the corresponding
* world-coordinate (a 3D point in mm, \a pt3d_mm).
*
* To convert a 2D point given in units (e.g., pixels in case of an
* image) into a 2D point given in mm (as required by this method), use
* IndexToWorld.
*/
virtual void Map(const mitk::Point2D &pt2d_mm, mitk::Point3D &pt3d_mm) const;
/**
* \brief Convert a 2D point given in units (e.g., pixels in case of an
* image) into a 2D point given in mm
*/
virtual void IndexToWorld(
const mitk::Point2D &pt_units, mitk::Point2D &pt_mm) const;
/**
* \brief Convert a 2D point given in mm into a 2D point given in mm
* (e.g., pixels in case of an image)
*/
virtual void WorldToIndex(
const mitk::Point2D &pt_mm, mitk::Point2D &pt_units) const;
/**
* \brief Convert a 2D vector given in units (e.g., pixels in case of an
* image) into a 2D vector given in mm
* \warning strange: in contrast to vtkTransform the class itk::Transform
* does not have the parameter, \em where the vector that is to be
* transformed is located. This method here should also need this
* information for general transforms.
*/
virtual void IndexToWorld(
const mitk::Point2D &atPt2d_units, const mitk::Vector2D &vec_units,
mitk::Vector2D &vec_mm) const;
/**
* \brief Convert a 2D vector given in mm into a 2D point vector in mm
* (e.g., pixels in case of an image)
* \warning strange: in contrast to vtkTransform the class itk::Transform
* does not have the parameter, \em where the vector that is to be
* transformed is located. This method here should also need this
* information for general transforms.
*/
virtual void WorldToIndex(
const mitk::Point2D &atPt2d_mm, const mitk::Vector2D &vec_mm,
mitk::Vector2D &vec_units) const;
/**
* \brief Set the width and height of this 2D-geometry in units by calling
* SetBounds. This does \a not change the extent in mm!
*
* For an image, this is the number of pixels in x-/y-direction.
* \note In contrast to calling SetBounds directly, this does \a not change
* the extent in mm!
*/
virtual void SetSizeInUnits(mitk::ScalarType width, mitk::ScalarType height);
/**
* \brief Project a 3D point given in mm (\a pt3d_mm) onto the 2D
* geometry. The result is a 3D point in mm (\a projectedPt3d_mm).
*
* \return true projection was possible
*/
virtual bool Project(const mitk::Point3D &pt3d_mm,
mitk::Point3D &projectedPt3d_mm) const;
/**
* \brief Project a 3D vector given in mm (\a vec3d_mm) onto the 2D
* geometry. The result is a 2D vector in mm (\a vec2d_mm).
*
* The result is a 2D vector in mm (\a vec2d_mm) relative to the
* upper-left
* corner of the geometry. To convert this point into units (e.g., pixels
* in case of an image), use WorldToIndex.
* \return true projection was possible
* \sa Project(const mitk::Vector3D &vec3d_mm, mitk::Vector3D
* &projectedVec3d_mm)
*/
virtual bool Map(const mitk::Point3D & atPt3d_mm,
const mitk::Vector3D &vec3d_mm, mitk::Vector2D &vec2d_mm) const;
/**
* \brief Converts a 2D vector given in mm (\a vec2d_mm) relative to the
* upper-left corner of the geometry into the corresponding
* world-coordinate (a 3D vector in mm, \a vec3d_mm).
*
* To convert a 2D vector given in units (e.g., pixels in case of an
* image) into a 2D vector given in mm (as required by this method), use
* IndexToWorld.
*/
virtual void Map(const mitk::Point2D & atPt2d_mm,
const mitk::Vector2D &vec2d_mm, mitk::Vector3D &vec3d_mm) const;
/**
* \brief Project a 3D vector given in mm (\a vec3d_mm) onto the 2D
* geometry. The result is a 3D vector in mm (\a projectedVec3d_mm).
*
* \return true projection was possible
*/
virtual bool Project(const mitk::Point3D & atPt3d_mm,
const mitk::Vector3D &vec3d_mm, mitk::Vector3D &projectedVec3d_mm) const;
/**
* \brief Distance of the point from the geometry
* (bounding-box \em not considered)
*
*/
inline ScalarType Distance(const Point3D& pt3d_mm) const
{
return fabs(SignedDistance(pt3d_mm));
}
/**
* \brief Signed distance of the point from the geometry
* (bounding-box \em not considered)
*
*/
virtual ScalarType SignedDistance(const Point3D& pt3d_mm) const;
/**
* \brief Test if the point is above the geometry
* (bounding-box \em not considered)
*
*/
virtual bool IsAbove(const Point3D& pt3d_mm) const;
virtual void SetIndexToWorldTransform(mitk::AffineTransform3D* transform);
virtual void SetExtentInMM(int direction, ScalarType extentInMM);
virtual AffineGeometryFrame3D::Pointer Clone() const;
/**
* \brief Set the geometrical frame of reference in which this Geometry2D
* is placed.
*
* This would usually be the Geometry3D of the underlying dataset, but
* setting it is optional.
*/
void SetReferenceGeometry( mitk::Geometry3D *geometry );
/**
* \brief Get the geometrical frame of reference for this Geometry2D.
*/
Geometry3D *GetReferenceGeometry() const;
bool HasReferenceGeometry() const;
protected:
Geometry2D();
Geometry2D(const Geometry2D& other);
virtual ~Geometry2D();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
/**
* \brief factor to convert x-coordinates from mm to units and vice versa
*
*/
mutable mitk::ScalarType m_ScaleFactorMMPerUnitX;
/**
* \brief factor to convert y-coordinates from mm to units and vice versa
*
*/
mutable mitk::ScalarType m_ScaleFactorMMPerUnitY;
mitk::Geometry3D *m_ReferenceGeometry;
};
} // namespace mitk
#endif /* GEOMETRY2D_H_HEADER_INCLUDED_C1F4D8E0 */
diff --git a/Core/Code/DataManagement/mitkGeometry2DData.cpp b/Core/Code/DataManagement/mitkGeometry2DData.cpp
index 427668e770..9ae687ff4c 100644
--- a/Core/Code/DataManagement/mitkGeometry2DData.cpp
+++ b/Core/Code/DataManagement/mitkGeometry2DData.cpp
@@ -1,91 +1,90 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGeometry2DData.h"
#include "mitkBaseProcess.h"
mitk::Geometry2DData::Geometry2DData()
{
}
mitk::Geometry2DData::~Geometry2DData()
{
}
void mitk::Geometry2DData::SetGeometry(mitk::Geometry3D *geometry)
{
if(geometry==NULL)
SetGeometry2D(NULL);
else
{
Geometry2D* geometry2d = dynamic_cast<Geometry2D*>(geometry);
if(geometry2d==NULL)
itkExceptionMacro(<<"Trying to set a geometry which is not a Geometry2D into Geometry2DData.");
SetGeometry2D(geometry2d);
}
}
void mitk::Geometry2DData::SetGeometry2D(mitk::Geometry2D *geometry2d)
{
if(geometry2d != NULL)
{
TimeSlicedGeometry* timeSlicedGeometry = GetTimeSlicedGeometry();
if(timeSlicedGeometry == NULL)
{
Superclass::SetGeometry(geometry2d);
return;
}
timeSlicedGeometry->InitializeEvenlyTimed(geometry2d, 1);
Modified();
}
else
Superclass::SetGeometry(geometry2d);
}
void mitk::Geometry2DData::UpdateOutputInformation()
{
Superclass::UpdateOutputInformation();
}
void mitk::Geometry2DData::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::Geometry2DData::RequestedRegionIsOutsideOfTheBufferedRegion()
{
if(GetGeometry2D()==NULL) return true;
return false;
}
bool mitk::Geometry2DData::VerifyRequestedRegion()
{
if(GetGeometry2D()==NULL) return false;
return true;
}
void mitk::Geometry2DData::SetRequestedRegion(itk::DataObject *)
{
}
void mitk::Geometry2DData::CopyInformation(const itk::DataObject *)
{
}
diff --git a/Core/Code/DataManagement/mitkGeometry2DData.h b/Core/Code/DataManagement/mitkGeometry2DData.h
index a38ddf7f35..fa268e67cc 100644
--- a/Core/Code/DataManagement/mitkGeometry2DData.h
+++ b/Core/Code/DataManagement/mitkGeometry2DData.h
@@ -1,78 +1,77 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGEOMETRY2DDATA_H_HEADER_INCLUDED_C19C01E2
#define MITKGEOMETRY2DDATA_H_HEADER_INCLUDED_C19C01E2
#include <MitkExports.h>
#include "mitkBaseData.h"
#include "mitkGeometryData.h"
#include "mitkGeometry2D.h"
namespace mitk {
//##Documentation
//## @brief Data class containing Geometry2D objects
//## @ingroup Geometry
//##
class MITK_CORE_EXPORT Geometry2DData : public GeometryData
{
public:
mitkClassMacro(Geometry2DData, GeometryData);
itkNewMacro(Self);
//##Documentation
//## @brief Set the reference to a Geometry2D that is stored
//## by the object
//##
//## @warning Accepts only instances of Geometry2D or sub-classes.
virtual void SetGeometry(mitk::Geometry3D *geometry);
//##Documentation
//## @brief Set the reference to the Geometry2D that is stored
//## by the object
virtual void SetGeometry2D(mitk::Geometry2D* geometry2d);
//##Documentation
//## @brief Get the reference to the Geometry2D that is stored
//## by the object
virtual mitk::Geometry2D * GetGeometry2D() const
{
return static_cast<mitk::Geometry2D *>(GetGeometry());
};
virtual void UpdateOutputInformation();
virtual void SetRequestedRegionToLargestPossibleRegion();
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
virtual bool VerifyRequestedRegion();
virtual void SetRequestedRegion(itk::DataObject *data);
virtual void CopyInformation(const itk::DataObject *data);
protected:
Geometry2DData();
virtual ~Geometry2DData();
};
} // namespace mitk
#endif /* MITKGEOMETRY2DDATA_H_HEADER_INCLUDED_C19C01E2 */
diff --git a/Core/Code/DataManagement/mitkGeometry3D.cpp b/Core/Code/DataManagement/mitkGeometry3D.cpp
index f5614e85ed..f49cdd2486 100644
--- a/Core/Code/DataManagement/mitkGeometry3D.cpp
+++ b/Core/Code/DataManagement/mitkGeometry3D.cpp
@@ -1,741 +1,740 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <sstream>
#include "mitkGeometry3D.h"
#include "mitkMatrixConvert.h"
#include "mitkRotationOperation.h"
#include "mitkRestorePlanePositionOperation.h"
#include "mitkPointOperation.h"
#include "mitkInteractionConst.h"
//#include "mitkStatusBar.h"
#include <vtkMatrixToLinearTransform.h>
#include <vtkMatrix4x4.h>
// Standard constructor for the New() macro. Sets the geometry to 3 dimensions
mitk::Geometry3D::Geometry3D()
: m_ParametricBoundingBox(NULL),
m_ImageGeometry(false), m_Valid(true), m_FrameOfReferenceID(0), m_IndexToWorldTransformLastModified(0)
{
FillVector3D(m_FloatSpacing, 1,1,1);
m_VtkMatrix = vtkMatrix4x4::New();
m_VtkIndexToWorldTransform = vtkMatrixToLinearTransform::New();
m_VtkIndexToWorldTransform->SetInput(m_VtkMatrix);
Initialize();
}
mitk::Geometry3D::Geometry3D(const Geometry3D& other) : Superclass(), mitk::OperationActor(), m_ParametricBoundingBox(other.m_ParametricBoundingBox),m_TimeBounds(other.m_TimeBounds),
m_ImageGeometry(other.m_ImageGeometry), m_Valid(other.m_Valid), m_FrameOfReferenceID(other.m_FrameOfReferenceID), m_IndexToWorldTransformLastModified(other.m_IndexToWorldTransformLastModified), m_RotationQuaternion( other.m_RotationQuaternion ) , m_Origin(other.m_Origin)
{
// AffineGeometryFrame
SetBounds(other.GetBounds());
//SetIndexToObjectTransform(other.GetIndexToObjectTransform());
//SetObjectToNodeTransform(other.GetObjectToNodeTransform());
//SetIndexToWorldTransform(other.GetIndexToWorldTransform());
// this is not used in AffineGeometryFrame of ITK, thus there are not Get and Set methods
// m_IndexToNodeTransform = other.m_IndexToNodeTransform;
// m_InvertedTransform = TransformType::New();
// m_InvertedTransform = TransformType::New();
// m_InvertedTransform->DeepCopy(other.m_InvertedTransform);
m_VtkMatrix = vtkMatrix4x4::New();
m_VtkMatrix->DeepCopy(other.m_VtkMatrix);
if (other.m_ParametricBoundingBox.IsNotNull())
{
m_ParametricBoundingBox = other.m_ParametricBoundingBox->DeepCopy();
}
FillVector3D(m_FloatSpacing,other.m_FloatSpacing[0],other.m_FloatSpacing[1],other.m_FloatSpacing[2]);
m_VtkIndexToWorldTransform = vtkMatrixToLinearTransform::New();
m_VtkIndexToWorldTransform->DeepCopy(other.m_VtkIndexToWorldTransform);
m_VtkIndexToWorldTransform->SetInput(m_VtkMatrix);
other.InitializeGeometry(this);
}
mitk::Geometry3D::~Geometry3D()
{
m_VtkMatrix->Delete();
m_VtkIndexToWorldTransform->Delete();
}
static void CopySpacingFromTransform(mitk::AffineTransform3D* transform, mitk::Vector3D& spacing, float floatSpacing[3])
{
mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = transform->GetMatrix().GetVnlMatrix();
spacing[0]=vnlmatrix.get_column(0).magnitude();
spacing[1]=vnlmatrix.get_column(1).magnitude();
spacing[2]=vnlmatrix.get_column(2).magnitude();
floatSpacing[0]=spacing[0];
floatSpacing[1]=spacing[1];
floatSpacing[2]=spacing[2];
}
void mitk::Geometry3D::Initialize()
{
float b[6] = {0,1,0,1,0,1};
SetFloatBounds(b);
m_IndexToObjectTransform = TransformType::New();
m_ObjectToNodeTransform = TransformType::New();
if(m_IndexToWorldTransform.IsNull())
m_IndexToWorldTransform = TransformType::New();
else
m_IndexToWorldTransform->SetIdentity();
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing, m_FloatSpacing);
vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin);
m_VtkMatrix->Identity();
m_TimeBounds[0]=ScalarTypeNumericTraits::NonpositiveMin(); m_TimeBounds[1]=ScalarTypeNumericTraits::max();
m_FrameOfReferenceID = 0;
m_ImageGeometry = false;
}
void mitk::Geometry3D::TransferItkToVtkTransform()
{
// copy m_IndexToWorldTransform into m_VtkIndexToWorldTransform
TransferItkTransformToVtkMatrix(m_IndexToWorldTransform.GetPointer(), m_VtkMatrix);
m_VtkIndexToWorldTransform->Modified();
}
void mitk::Geometry3D::TransferVtkToItkTransform()
{
TransferVtkMatrixToItkTransform(m_VtkMatrix, m_IndexToWorldTransform.GetPointer());
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing, m_FloatSpacing);
vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin);
}
void mitk::Geometry3D::SetIndexToWorldTransformByVtkMatrix(vtkMatrix4x4* vtkmatrix)
{
m_VtkMatrix->DeepCopy(vtkmatrix);
TransferVtkToItkTransform();
}
void mitk::Geometry3D::SetTimeBounds(const TimeBounds& timebounds)
{
if(m_TimeBounds != timebounds)
{
m_TimeBounds = timebounds;
Modified();
}
}
void mitk::Geometry3D::SetFloatBounds(const float bounds[6])
{
mitk::BoundingBox::BoundsArrayType b;
const float *input = bounds;
int i=0;
for(mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); i < 6 ;++i) *it++ = (mitk::ScalarType)*input++;
SetBoundsArray(b, m_BoundingBox);
}
void mitk::Geometry3D::SetFloatBounds(const double bounds[6])
{
mitk::BoundingBox::BoundsArrayType b;
const double *input = bounds;
int i=0;
for(mitk::BoundingBox::BoundsArrayType::Iterator it = b.Begin(); i < 6 ;++i) *it++ = (mitk::ScalarType)*input++;
SetBoundsArray(b, m_BoundingBox);
}
void mitk::Geometry3D::SetParametricBounds(const BoundingBox::BoundsArrayType& bounds)
{
SetBoundsArray(bounds, m_ParametricBoundingBox);
}
void mitk::Geometry3D::WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
{
BackTransform(pt_mm, pt_units);
}
void mitk::Geometry3D::IndexToWorld(const mitk::Point3D &pt_units, mitk::Point3D &pt_mm) const
{
pt_mm = m_IndexToWorldTransform->TransformPoint(pt_units);
}
void mitk::Geometry3D::WorldToIndex(const mitk::Point3D & /*atPt3d_mm*/, const mitk::Vector3D &vec_mm, mitk::Vector3D &vec_units) const
{
MITK_WARN<<"Warning! Call of the deprecated function Geometry3D::WorldToIndex(point, vec, vec). Use Geometry3D::WorldToIndex(vec, vec) instead!";
//BackTransform(atPt3d_mm, vec_mm, vec_units);
this->WorldToIndex(vec_mm, vec_units);
}
void mitk::Geometry3D::WorldToIndex( const mitk::Vector3D &vec_mm, mitk::Vector3D &vec_units) const
{
BackTransform( vec_mm, vec_units);
}
void mitk::Geometry3D::IndexToWorld(const mitk::Point3D &/*atPt3d_units*/, const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const
{
MITK_WARN<<"Warning! Call of the deprecated function Geometry3D::IndexToWorld(point, vec, vec). Use Geometry3D::IndexToWorld(vec, vec) instead!";
//vec_mm = m_IndexToWorldTransform->TransformVector(vec_units);
this->IndexToWorld(vec_units, vec_mm);
}
void mitk::Geometry3D::IndexToWorld(const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const
{
vec_mm = m_IndexToWorldTransform->TransformVector(vec_units);
}
void mitk::Geometry3D::SetIndexToWorldTransform(mitk::AffineTransform3D* transform)
{
if(m_IndexToWorldTransform.GetPointer() != transform)
{
Superclass::SetIndexToWorldTransform(transform);
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing, m_FloatSpacing);
vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin);
TransferItkToVtkTransform();
Modified();
}
}
mitk::AffineGeometryFrame3D::Pointer mitk::Geometry3D::Clone() const
{
Self::Pointer newGeometry = new Self(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
/*
void mitk::Geometry3D::InitializeGeometry(Geometry3D * newGeometry) const
{
Superclass::InitializeGeometry(newGeometry);
newGeometry->SetTimeBounds(m_TimeBounds);
//newGeometry->GetVtkTransform()->SetMatrix(m_VtkIndexToWorldTransform->GetMatrix()); IW
//newGeometry->TransferVtkToItkTransform(); //MH
newGeometry->SetFrameOfReferenceID(GetFrameOfReferenceID());
newGeometry->m_ImageGeometry = m_ImageGeometry;
}
*/
void mitk::Geometry3D::SetExtentInMM(int direction, ScalarType extentInMM)
{
ScalarType len = GetExtentInMM(direction);
if(fabs(len - extentInMM)>=mitk::eps)
{
AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = m_IndexToWorldTransform->GetMatrix().GetVnlMatrix();
if(len>extentInMM)
vnlmatrix.set_column(direction, vnlmatrix.get_column(direction)/len*extentInMM);
else
vnlmatrix.set_column(direction, vnlmatrix.get_column(direction)*extentInMM/len);
Matrix3D matrix;
matrix = vnlmatrix;
m_IndexToWorldTransform->SetMatrix(matrix);
Modified();
}
}
mitk::BoundingBox::Pointer mitk::Geometry3D::CalculateBoundingBoxRelativeToTransform(const mitk::AffineTransform3D* transform) const
{
mitk::BoundingBox::PointsContainer::Pointer pointscontainer=mitk::BoundingBox::PointsContainer::New();
mitk::BoundingBox::PointIdentifier pointid=0;
unsigned char i;
if(transform!=NULL)
{
mitk::AffineTransform3D::Pointer inverse = mitk::AffineTransform3D::New();
transform->GetInverse(inverse);
for(i=0; i<8; ++i)
pointscontainer->InsertElement( pointid++, inverse->TransformPoint( GetCornerPoint(i) ));
}
else
{
for(i=0; i<8; ++i)
pointscontainer->InsertElement( pointid++, GetCornerPoint(i) );
}
mitk::BoundingBox::Pointer result = mitk::BoundingBox::New();
result->SetPoints(pointscontainer);
result->ComputeBoundingBox();
return result;
}
#include <vtkTransform.h>
void mitk::Geometry3D::ExecuteOperation(Operation* operation)
{
vtkTransform *vtktransform = vtkTransform::New();
vtktransform->SetMatrix(m_VtkMatrix);
switch (operation->GetOperationType())
{
case OpNOTHING:
break;
case OpMOVE:
{
mitk::PointOperation *pointOp = dynamic_cast<mitk::PointOperation *>(operation);
if (pointOp == NULL)
{
//mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000);
return;
}
mitk::Point3D newPos = pointOp->GetPoint();
ScalarType data[3];
vtktransform->GetPosition(data);
vtktransform->PostMultiply();
vtktransform->Translate(newPos[0], newPos[1], newPos[2]);
vtktransform->PreMultiply();
break;
}
case OpSCALE:
{
mitk::PointOperation *pointOp = dynamic_cast<mitk::PointOperation *>(operation);
if (pointOp == NULL)
{
//mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000);
return;
}
mitk::Point3D newScale = pointOp->GetPoint();
ScalarType data[3];
/* calculate new scale: newscale = oldscale * (oldscale + scaletoadd)/oldscale */
data[0] = 1 + (newScale[0] / GetMatrixColumn(0).magnitude());
data[1] = 1 + (newScale[1] / GetMatrixColumn(1).magnitude());
data[2] = 1 + (newScale[2] / GetMatrixColumn(2).magnitude());
mitk::Point3D center = const_cast<mitk::BoundingBox*>(m_BoundingBox.GetPointer())->GetCenter();
ScalarType pos[3];
vtktransform->GetPosition(pos);
vtktransform->PostMultiply();
vtktransform->Translate(-pos[0], -pos[1], -pos[2]);
vtktransform->Translate(-center[0], -center[1], -center[2]);
vtktransform->PreMultiply();
vtktransform->Scale(data[0], data[1], data[2]);
vtktransform->PostMultiply();
vtktransform->Translate(+center[0], +center[1], +center[2]);
vtktransform->Translate(pos[0], pos[1], pos[2]);
vtktransform->PreMultiply();
break;
}
case OpROTATE:
{
mitk::RotationOperation *rotateOp = dynamic_cast<mitk::RotationOperation *>(operation);
if (rotateOp == NULL)
{
//mitk::StatusBar::GetInstance()->DisplayText("received wrong type of operation!See mitkAffineInteractor.cpp", 10000);
return;
}
Vector3D rotationVector = rotateOp->GetVectorOfRotation();
Point3D center = rotateOp->GetCenterOfRotation();
ScalarType angle = rotateOp->GetAngleOfRotation();
vtktransform->PostMultiply();
vtktransform->Translate(-center[0], -center[1], -center[2]);
vtktransform->RotateWXYZ(angle, rotationVector[0], rotationVector[1], rotationVector[2]);
vtktransform->Translate(center[0], center[1], center[2]);
vtktransform->PreMultiply();
break;
}
case OpRESTOREPLANEPOSITION:
{
//Copy necessary to avoid vtk warning
vtkMatrix4x4* matrix = vtkMatrix4x4::New();
TransferItkTransformToVtkMatrix(dynamic_cast<mitk::RestorePlanePositionOperation*>(operation)->GetTransform().GetPointer(), matrix);
vtktransform->SetMatrix(matrix);
break;
}
default:
vtktransform->Delete();
return;
}
m_VtkMatrix->DeepCopy(vtktransform->GetMatrix());
TransferVtkToItkTransform();
Modified();
vtktransform->Delete();
}
void mitk::Geometry3D::BackTransform(const mitk::Point3D &in, mitk::Point3D& out) const
{
ScalarType temp[3];
unsigned int i, j;
const TransformType::OffsetType& offset = m_IndexToWorldTransform->GetOffset();
// Remove offset
for (j = 0; j < 3; j++)
{
temp[j] = in[j] - offset[j];
}
// Get WorldToIndex transform
if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime())
{
m_InvertedTransform = TransformType::New();
if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() ))
{
itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." );
}
m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime();
}
// Check for valid matrix inversion
const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix();
if(inverse.GetVnlMatrix().has_nans())
{
itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl
<< m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl
<< inverse );
}
// Transform point
for (i = 0; i < 3; i++)
{
out[i] = 0.0;
for (j = 0; j < 3; j++)
{
out[i] += inverse[i][j]*temp[j];
}
}
}
void mitk::Geometry3D::BackTransform(const mitk::Point3D &/*at*/, const mitk::Vector3D &in, mitk::Vector3D& out) const
{
MITK_INFO<<"Warning! Call of the deprecated function Geometry3D::BackTransform(point, vec, vec). Use Geometry3D::BackTransform(vec, vec) instead!";
//// Get WorldToIndex transform
//if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime())
//{
// m_InvertedTransform = TransformType::New();
// if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() ))
// {
// itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." );
// }
// m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime();
//}
//// Check for valid matrix inversion
//const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix();
//if(inverse.GetVnlMatrix().has_nans())
//{
// itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl
// << m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl
// << inverse );
//}
//// Transform vector
//for (unsigned int i = 0; i < 3; i++)
//{
// out[i] = 0.0;
// for (unsigned int j = 0; j < 3; j++)
// {
// out[i] += inverse[i][j]*in[j];
// }
//}
this->BackTransform(in, out);
}
void mitk::Geometry3D::BackTransform(const mitk::Vector3D& in, mitk::Vector3D& out) const
{
// Get WorldToIndex transform
if (m_IndexToWorldTransformLastModified != m_IndexToWorldTransform->GetMTime())
{
m_InvertedTransform = TransformType::New();
if (!m_IndexToWorldTransform->GetInverse( m_InvertedTransform.GetPointer() ))
{
itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed." );
}
m_IndexToWorldTransformLastModified = m_IndexToWorldTransform->GetMTime();
}
// Check for valid matrix inversion
const TransformType::MatrixType& inverse = m_InvertedTransform->GetMatrix();
if(inverse.GetVnlMatrix().has_nans())
{
itkExceptionMacro( "Internal ITK matrix inversion error, cannot proceed. Matrix was: " << std::endl
<< m_IndexToWorldTransform->GetMatrix() << "Suggested inverted matrix is:" << std::endl
<< inverse );
}
// Transform vector
for (unsigned int i = 0; i < 3; i++)
{
out[i] = 0.0;
for (unsigned int j = 0; j < 3; j++)
{
out[i] += inverse[i][j]*in[j];
}
}
}
const float* mitk::Geometry3D::GetFloatSpacing() const
{
return m_FloatSpacing;
}
void mitk::Geometry3D::SetSpacing(const mitk::Vector3D& aSpacing)
{
if(mitk::Equal(m_Spacing, aSpacing) == false)
{
assert(aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0);
m_Spacing = aSpacing;
AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = m_IndexToWorldTransform->GetMatrix().GetVnlMatrix();
mitk::VnlVector col;
col = vnlmatrix.get_column(0); col.normalize(); col*=aSpacing[0]; vnlmatrix.set_column(0, col);
col = vnlmatrix.get_column(1); col.normalize(); col*=aSpacing[1]; vnlmatrix.set_column(1, col);
col = vnlmatrix.get_column(2); col.normalize(); col*=aSpacing[2]; vnlmatrix.set_column(2, col);
Matrix3D matrix;
matrix = vnlmatrix;
AffineTransform3D::Pointer transform = AffineTransform3D::New();
transform->SetMatrix(matrix);
transform->SetOffset(m_IndexToWorldTransform->GetOffset());
SetIndexToWorldTransform(transform.GetPointer());
itk2vtk(m_Spacing, m_FloatSpacing);
}
}
void mitk::Geometry3D::SetOrigin(const Point3D & origin)
{
if(origin!=GetOrigin())
{
m_Origin = origin;
m_IndexToWorldTransform->SetOffset(m_Origin.GetVectorFromOrigin());
Modified();
TransferItkToVtkTransform();
}
}
void mitk::Geometry3D::Translate(const Vector3D & vector)
{
if((vector[0] != 0) || (vector[1] != 0) || (vector[2] != 0))
{
m_IndexToWorldTransform->SetOffset(m_IndexToWorldTransform->GetOffset()+vector);
TransferItkToVtkTransform();
Modified();
}
}
void mitk::Geometry3D::SetIdentity()
{
m_IndexToWorldTransform->SetIdentity();
m_Origin.Fill(0);
Modified();
TransferItkToVtkTransform();
}
void mitk::Geometry3D::Compose( const mitk::AffineGeometryFrame3D::TransformType * other, bool pre )
{
m_IndexToWorldTransform->Compose(other, pre);
CopySpacingFromTransform(m_IndexToWorldTransform, m_Spacing, m_FloatSpacing);
vtk2itk(m_IndexToWorldTransform->GetOffset(), m_Origin);
Modified();
TransferItkToVtkTransform();
}
void mitk::Geometry3D::Compose( const vtkMatrix4x4 * vtkmatrix, bool pre )
{
mitk::AffineGeometryFrame3D::TransformType::Pointer itkTransform = mitk::AffineGeometryFrame3D::TransformType::New();
TransferVtkMatrixToItkTransform(vtkmatrix, itkTransform.GetPointer());
Compose(itkTransform, pre);
}
const std::string mitk::Geometry3D::GetTransformAsString( TransformType* transformType )
{
std::ostringstream out;
out << '[';
for( int i=0; i<3; ++i )
{
out << '[';
for( int j=0; j<3; ++j )
out << transformType->GetMatrix().GetVnlMatrix().get(i, j) << ' ';
out << ']';
}
out << "][";
for( int i=0; i<3; ++i )
out << transformType->GetOffset()[i] << ' ';
out << "]\0";
return out.str();
}
void mitk::Geometry3D::PrintSelf(std::ostream& os, itk::Indent indent) const
{
os << indent << " IndexToWorldTransform: ";
if(m_IndexToWorldTransform.IsNull())
os << "NULL" << std::endl;
else
{
// from itk::MatrixOffsetTransformBase
unsigned int i, j;
os << std::endl;
os << indent << "Matrix: " << std::endl;
for (i = 0; i < 3; i++)
{
os << indent.GetNextIndent();
for (j = 0; j < 3; j++)
{
os << m_IndexToWorldTransform->GetMatrix()[i][j] << " ";
}
os << std::endl;
}
os << indent << "Offset: " << m_IndexToWorldTransform->GetOffset() << std::endl;
os << indent << "Center: " << m_IndexToWorldTransform->GetCenter() << std::endl;
os << indent << "Translation: " << m_IndexToWorldTransform->GetTranslation() << std::endl;
os << indent << "Inverse: " << std::endl;
for (i = 0; i < 3; i++)
{
os << indent.GetNextIndent();
for (j = 0; j < 3; j++)
{
os << m_IndexToWorldTransform->GetInverseMatrix()[i][j] << " ";
}
os << std::endl;
}
// from itk::ScalableAffineTransform
os << indent << "Scale : ";
for (i = 0; i < 3; i++)
{
os << m_IndexToWorldTransform->GetScale()[i] << " ";
}
os << std::endl;
}
os << indent << " BoundingBox: ";
if(m_BoundingBox.IsNull())
os << "NULL" << std::endl;
else
{
os << indent << "( ";
for (unsigned int i=0; i<3; i++)
{
os << m_BoundingBox->GetBounds()[2*i] << "," << m_BoundingBox->GetBounds()[2*i+1] << " ";
}
os << " )" << std::endl;
}
os << indent << " Origin: " << m_Origin << std::endl;
os << indent << " ImageGeometry: " << m_ImageGeometry << std::endl;
os << indent << " Spacing: " << m_Spacing << std::endl;
os << indent << " TimeBounds: " << m_TimeBounds << std::endl;
}
mitk::Point3D mitk::Geometry3D::GetCornerPoint(int id) const
{
assert(id >= 0);
assert(m_BoundingBox.IsNotNull());
BoundingBox::BoundsArrayType bounds = m_BoundingBox->GetBounds();
Point3D cornerpoint;
switch(id)
{
case 0: FillVector3D(cornerpoint, bounds[0],bounds[2],bounds[4]); break;
case 1: FillVector3D(cornerpoint, bounds[0],bounds[2],bounds[5]); break;
case 2: FillVector3D(cornerpoint, bounds[0],bounds[3],bounds[4]); break;
case 3: FillVector3D(cornerpoint, bounds[0],bounds[3],bounds[5]); break;
case 4: FillVector3D(cornerpoint, bounds[1],bounds[2],bounds[4]); break;
case 5: FillVector3D(cornerpoint, bounds[1],bounds[2],bounds[5]); break;
case 6: FillVector3D(cornerpoint, bounds[1],bounds[3],bounds[4]); break;
case 7: FillVector3D(cornerpoint, bounds[1],bounds[3],bounds[5]); break;
default:
{
itkExceptionMacro(<<"A cube only has 8 corners. These are labeled 0-7.");
return NULL;
}
}
if(m_ImageGeometry)
{
// Here i have to adjust the 0.5 offset manually, because the cornerpoint is the corner of the
// bounding box. The bounding box itself is no image, so it is corner-based
FillVector3D(cornerpoint, cornerpoint[0]-0.5, cornerpoint[1]-0.5, cornerpoint[2]-0.5);
}
return m_IndexToWorldTransform->TransformPoint(cornerpoint);
}
mitk::Point3D mitk::Geometry3D::GetCornerPoint(bool xFront, bool yFront, bool zFront) const
{
assert(m_BoundingBox.IsNotNull());
BoundingBox::BoundsArrayType bounds = m_BoundingBox->GetBounds();
Point3D cornerpoint;
cornerpoint[0] = (xFront ? bounds[0] : bounds[1]);
cornerpoint[1] = (yFront ? bounds[2] : bounds[3]);
cornerpoint[2] = (zFront ? bounds[4] : bounds[5]);
if(m_ImageGeometry)
{
// Here i have to adjust the 0.5 offset manually, because the cornerpoint is the corner of the
// bounding box. The bounding box itself is no image, so it is corner-based
FillVector3D(cornerpoint, cornerpoint[0]-0.5, cornerpoint[1]-0.5, cornerpoint[2]-0.5);
}
return m_IndexToWorldTransform->TransformPoint(cornerpoint);
}
void
mitk::Geometry3D::ResetSubTransforms()
{
}
void
mitk::Geometry3D::ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry )
{
// If Geometry is switched to ImageGeometry, you have to put an offset to the origin, because
// imageGeometries origins are pixel-center-based
// ... and remove the offset, if you switch an imageGeometry back to a normal geometry
// For more information please see the Geometry documentation page
if(m_ImageGeometry == isAnImageGeometry)
return;
const BoundingBox::BoundsArrayType& boundsarray =
this->GetBoundingBox()->GetBounds();
Point3D originIndex;
FillVector3D(originIndex, boundsarray[0], boundsarray[2], boundsarray[4]);
if(isAnImageGeometry == true)
FillVector3D( originIndex,
originIndex[0] + 0.5,
originIndex[1] + 0.5,
originIndex[2] + 0.5 );
else
FillVector3D( originIndex,
originIndex[0] - 0.5,
originIndex[1] - 0.5,
originIndex[2] - 0.5 );
Point3D originWorld;
originWorld = GetIndexToWorldTransform()
->TransformPoint( originIndex );
// instead could as well call IndexToWorld(originIndex,originWorld);
SetOrigin(originWorld);
this->SetImageGeometry(isAnImageGeometry);
}
diff --git a/Core/Code/DataManagement/mitkGeometry3D.h b/Core/Code/DataManagement/mitkGeometry3D.h
index c7c7decbce..609fc622f3 100644
--- a/Core/Code/DataManagement/mitkGeometry3D.h
+++ b/Core/Code/DataManagement/mitkGeometry3D.h
@@ -1,663 +1,662 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD
#define GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD
#include <MitkExports.h>
#include <mitkCommon.h>
#include "mitkVector.h"
#include "mitkOperationActor.h"
#include <itkIndex.h>
#include <itkBoundingBox.h>
#include <itkQuaternionRigidTransform.h>
#include <itkAffineGeometryFrame.h>
class vtkLinearTransform;
class vtkMatrixToLinearTransform;
class vtkMatrix4x4;
namespace mitk {
//##Documentation
//## @brief Standard 3D-BoundingBox typedef
//##
//## Standard 3D-BoundingBox typedef to get rid of template arguments (3D, type).
typedef itk::BoundingBox<unsigned long, 3, ScalarType> BoundingBox;
//##Documentation
//## @brief Standard typedef for time-bounds
typedef itk::FixedArray<ScalarType,2> TimeBounds;
typedef itk::FixedArray<ScalarType, 3> FixedArrayType;
typedef itk::AffineGeometryFrame<ScalarType, 3> AffineGeometryFrame3D;
//##Documentation
//## @brief Describes the geometry of a data object
//##
//## At least, it can return the bounding box of the data object.
//##
//## The class holds
//## \li a bounding box which is axes-parallel in intrinsic coordinates
//## (often integer indices of pixels), to be accessed by
//## GetBoundingBox()
//## \li a transform to convert intrinsic coordinates into a
//## world-coordinate system with coordinates in millimeters
//## and milliseconds (all are floating point values), to
//## be accessed by GetIndexToWorldTransform()
//## \li a life span, i.e. a bounding box in time in ms (with
//## start and end time), to be accessed by GetTimeBounds().
//## The default is minus infinity to plus infinity.
//##
//## Geometry3D and its sub-classes allow converting between
//## intrinsic coordinates (called index or unit coordinates)
//## and world-coordinates (called world or mm coordinates),
//## e.g. WorldToIndex.
//## In case you need integer index coordinates, provide an
//## mitk::Index3D (or itk::Index) as target variable to
//## WorldToIndex, otherwise you will get a continuous index
//## (floating point values).
//##
//## An important sub-class is SlicedGeometry3D, which descibes
//## data objects consisting of slices, e.g., objects of type Image.
//## Conversions between world coordinates (in mm) and unit coordinates
//## (e.g., pixels in the case of an Image) can be performed.
//##
//## For more information on related classes, see \ref Geometry.
//##
//## Geometry3D instances referring to an Image need a slightly
//## different definition of corners, see SetImageGeometry. This
//## is usualy automatically called by Image.
//##
//## Geometry3D have to be initialized in the method GenerateOutputInformation()
//## of BaseProcess (or CopyInformation/ UpdateOutputInformation of BaseData,
//## if possible, e.g., by analyzing pic tags in Image) subclasses. See also
//## itk::ProcessObject::GenerateOutputInformation(),
//## itk::DataObject::CopyInformation() and
//## itk::DataObject::UpdateOutputInformation().
//##
//## Rule: everything is in mm (ms) if not stated otherwise.
//## @ingroup Geometry
class MITK_CORE_EXPORT Geometry3D : public AffineGeometryFrame3D, public OperationActor
{
public:
mitkClassMacro(Geometry3D, AffineGeometryFrame3D);
typedef itk::QuaternionRigidTransform< ScalarType > QuaternionTransformType;
typedef QuaternionTransformType::VnlQuaternionType VnlQuaternionType;
/** Method for creation through the object factory. */
itkNewMacro(Self);
// a bit of a misuse, but we want only doxygen to see the following:
#ifdef DOXYGEN_SKIP
//##Documentation
//## @brief Get the transformation used to convert from index
//## to world coordinates
itkGetObjectMacro(IndexToWorldTransform, AffineTransform3D);
#endif
//## @brief Set the transformation used to convert from index
//## to world coordinates
virtual void SetIndexToWorldTransform(mitk::AffineTransform3D* transform);
//##Documentation
//## @brief Convenience method for setting the ITK transform
//## (m_IndexToWorldTransform) via an vtkMatrix4x4
//## \sa SetIndexToWorldTransform
virtual void SetIndexToWorldTransformByVtkMatrix(vtkMatrix4x4* vtkmatrix);
#ifdef DOXYGEN_SKIP
//##Documentation
//## @brief Get bounding box (in index/unit coordinates)
itkGetConstObjectMacro(BoundingBox, BoundingBoxType);
//##Documentation
//## @brief Get bounding box (in index/unit coordinates) as a BoundsArrayType
const BoundsArrayType GetBounds() const
{
assert(m_BoundingBox.IsNotNull());
return m_BoundingBox->GetBounds();
}
//##Documentation
//## \brief Set the bounding box (in index/unit coordinates)
//##
//## Only possible via the BoundsArray to make clear that a
//## copy of the bounding-box is stored, not a reference to it.
virtual void SetBounds(const BoundsArrayType& bounds);
#endif
//##Documentation
//## @brief Set the bounding box (in index/unit coordinates) via a float array
virtual void SetFloatBounds(const float bounds[6]);
//##Documentation
//## @brief Set the bounding box (in index/unit coordinates) via a double array
virtual void SetFloatBounds(const double bounds[6]);
//##Documentation
//## @brief When switching from an Image Geometry to a normal Geometry (and the other way around), you have to change the origin as well (See Geometry Documentation)! This function will change the "isImageGeometry" bool flag and changes the origin respectively.
virtual void ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry );
//##Documentation
//## @brief Get the time bounds (in ms)
itkGetConstReferenceMacro(TimeBounds, TimeBounds);
//##Documentation
//## @brief Set the time bounds (in ms)
virtual void SetTimeBounds(const TimeBounds& timebounds);
//##Documentation
//## @brief Get the position of the corner number \a id (in world coordinates)
//##
//## See SetImageGeometry for how a corner is defined on images.
Point3D GetCornerPoint(int id) const;
//##Documentation
//## @brief Get the position of a corner (in world coordinates)
//##
//## See SetImageGeometry for how a corner is defined on images.
Point3D GetCornerPoint(bool xFront=true, bool yFront=true, bool zFront=true) const;
//##Documentation
//## @brief Get vector along bounding-box in the specified @a direction in mm
//##
//## The length of the vector is the size of the bounding-box in the
//## specified @a direction in mm
//## \sa GetMatrixColumn
Vector3D GetAxisVector(unsigned int direction) const
{
Vector3D frontToBack;
frontToBack.Set_vnl_vector(m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction));
frontToBack *= GetExtent(direction);
return frontToBack;
}
//##Documentation
//## @brief Get the center of the bounding-box in mm
//##
Point3D GetCenter() const
{
assert(m_BoundingBox.IsNotNull());
return m_IndexToWorldTransform->TransformPoint(m_BoundingBox->GetCenter());
}
//##Documentation
//## @brief Get the squared length of the diagonal of the bounding-box in mm
//##
double GetDiagonalLength2() const
{
Vector3D diagonalvector = GetCornerPoint()-GetCornerPoint(false, false, false);
return diagonalvector.GetSquaredNorm();
}
//##Documentation
//## @brief Get the length of the diagonal of the bounding-box in mm
//##
double GetDiagonalLength() const
{
return sqrt(GetDiagonalLength2());
}
//##Documentation
//## @brief Get a VnlVector along bounding-box in the specified
//## @a direction, length is spacing
//##
//## \sa GetAxisVector
VnlVector GetMatrixColumn(unsigned int direction) const
{
return m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction);
}
#ifdef DOXYGEN_SKIP
//##Documentation
//## @brief Get the extent of the bounding box (in index/unit coordinates)
//##
//## To access the extent in mm use GetExtentInMM
ScalarType GetExtent(unsigned int direction) const;
#endif
//##Documentation
//## @brief Get the extent of the bounding-box in the specified @a direction in mm
//##
//## Equals length of GetAxisVector(direction).
ScalarType GetExtentInMM(int direction) const
{
return m_IndexToWorldTransform->GetMatrix().GetVnlMatrix().get_column(direction).magnitude()*GetExtent(direction);
}
//##Documentation
//## @brief Set the extent of the bounding-box in the specified @a direction in mm
//##
//## @note This changes the matrix in the transform, @a not the bounds, which are given in units!
virtual void SetExtentInMM(int direction, ScalarType extentInMM);
//##Documentation
//## @brief Get the m_IndexToWorldTransform as a vtkLinearTransform
vtkLinearTransform* GetVtkTransform() const
{
return (vtkLinearTransform*)m_VtkIndexToWorldTransform;
}
//##Documentation
//## @brief Set the origin, i.e. the upper-left corner of the plane
//##
virtual void SetOrigin(const Point3D& origin);
//##Documentation
//## @brief Translate the origin by a vector
//##
virtual void Translate(const Vector3D& vector);
//##Documentation
//## @brief Set the transform to identity
//##
virtual void SetIdentity();
//##Documentation
//## @brief Compose new IndexToWorldTransform with a given transform.
//##
//## This method composes m_IndexToWorldTransform with another transform,
//## modifying self to be the composition of self and other.
//## If the argument pre is true, then other is precomposed with self;
//## that is, the resulting transformation consists of first applying
//## other to the source, followed by self. If pre is false or omitted,
//## then other is post-composed with self; that is the resulting
//## transformation consists of first applying self to the source,
//## followed by other.
virtual void Compose( const AffineGeometryFrame3D::TransformType * other, bool pre = 0 );
//##Documentation
//## @brief Compose new IndexToWorldTransform with a given vtkMatrix4x4.
//##
//## Converts the vtkMatrix4x4 into a itk-transform and calls the previous method.
virtual void Compose( const vtkMatrix4x4 * vtkmatrix, bool pre = 0 );
//##Documentation
//## @brief Get the origin, e.g. the upper-left corner of the plane
const Point3D& GetOrigin() const
{
return m_Origin;
}
//##Documentation
//## @brief Get the origin as VnlVector
//##
//## \sa GetOrigin
VnlVector GetOriginVnl() const
{
return const_cast<Self*>(this)->m_Origin.Get_vnl_vector();
}
//##Documentation
//## @brief Convert world coordinates (in mm) of a \em point to (continuous!) index coordinates
//## \warning If you need (discrete) integer index coordinates (e.g., for iterating easily over an image),
//## use WorldToIndex(const mitk::Point3D& pt_mm, itk::Index<VIndexDimension> &index).
//## For further information about coordinates types, please see the Geometry documentation
void WorldToIndex(const mitk::Point3D& pt_mm, mitk::Point3D& pt_units) const;
//##Documentation
//## @brief Convert (continuous or discrete) index coordinates of a \em point to world coordinates (in mm)
//## For further information about coordinates types, please see the Geometry documentation
void IndexToWorld(const mitk::Point3D& pt_units, mitk::Point3D& pt_mm) const;
//##Documentation
//## @brief Convert world coordinates (in mm) of a \em vector
//## \a vec_mm to (continuous!) index coordinates.
//## @deprecated First parameter (Point3D) is not used. If possible, please use void WorldToIndex(const mitk::Vector3D& vec_mm, mitk::Vector3D& vec_units) const.
//## For further information about coordinates types, please see the Geometry documentation
void WorldToIndex(const mitk::Point3D& atPt3d_mm, const mitk::Vector3D& vec_mm, mitk::Vector3D& vec_units) const;
//##Documentation
//## @brief Convert world coordinates (in mm) of a \em vector
//## \a vec_mm to (continuous!) index coordinates.
//## For further information about coordinates types, please see the Geometry documentation
void WorldToIndex(const mitk::Vector3D& vec_mm, mitk::Vector3D& vec_units) const;
//##Documentation
//## @brief Convert (continuous or discrete) index coordinates of a \em vector
//## \a vec_units to world coordinates (in mm)
//## @deprecated First parameter (Point3D) is not used. If possible, please use void IndexToWorld(const mitk::Vector3D& vec_units, mitk::Vector3D& vec_mm) const.
//## For further information about coordinates types, please see the Geometry documentation
void IndexToWorld(const mitk::Point3D& atPt3d_units, const mitk::Vector3D& vec_units, mitk::Vector3D& vec_mm) const;
//##Documentation
//## @brief Convert (continuous or discrete) index coordinates of a \em vector
//## \a vec_units to world coordinates (in mm)
//## For further information about coordinates types, please see the Geometry documentation
void IndexToWorld(const mitk::Vector3D& vec_units, mitk::Vector3D& vec_mm) const;
//##Documentation
//## @brief Convert world coordinates (in mm) of a \em point to (discrete!) index coordinates.
//## This method rounds to integer indices!
//## For further information about coordinates types, please see the Geometry documentation
template <unsigned int VIndexDimension>
void WorldToIndex(const mitk::Point3D& pt_mm, itk::Index<VIndexDimension> &index) const
{
typedef itk::Index<VIndexDimension> IndexType;
mitk::Point3D pt_units;
this->WorldToIndex(pt_mm, pt_units);
int i, dim=index.GetIndexDimension();
if(dim>3)
{
index.Fill(0);
dim=3;
}
for(i=0;i<dim;++i){
//index[i]=itk::Math::RoundHalfIntegerUp<typename IndexType::IndexValueType >( pt_units[i] );
index[i]=itk::Math::RoundHalfIntegerUp( pt_units[i] );
}
}
//##Documentation
//## @brief Deprecated for use with ITK version 3.10 or newer.
//## Convert world coordinates (in mm) of a \em point to
//## ITK physical coordinates (in mm, but without a possible rotation)
//##
//## This method is useful if you have want to access an mitk::Image
//## via an itk::Image. ITK v3.8 and older did not support rotated (tilted)
//## images, i.e., ITK images are always parallel to the coordinate axes.
//## When accessing a (possibly rotated) mitk::Image via an itk::Image
//## the rotational part of the transformation in the Geometry3D is
//## simply discarded; in other word: only the origin and spacing is
//## used by ITK, not the complete matrix available in MITK.
//## With WorldToItkPhysicalPoint you can convert an MITK world
//## coordinate (including the rotation) into a coordinate that
//## can be used with the ITK image as a ITK physical coordinate
//## (excluding the rotation).
template<class TCoordRep>
void WorldToItkPhysicalPoint(const mitk::Point3D& pt_mm,
itk::Point<TCoordRep, 3>& itkPhysicalPoint) const
{
mitk::vtk2itk(pt_mm, itkPhysicalPoint);
}
//##Documentation
//## @brief Deprecated for use with ITK version 3.10 or newer.
//## Convert ITK physical coordinates of a \em point (in mm,
//## but without a rotation) into MITK world coordinates (in mm)
//##
//## For more information, see WorldToItkPhysicalPoint.
template<class TCoordRep>
void ItkPhysicalPointToWorld(const itk::Point<TCoordRep, 3>& itkPhysicalPoint,
mitk::Point3D& pt_mm) const
{
mitk::vtk2itk(itkPhysicalPoint, pt_mm);
}
//##Documentation
//## @brief Initialize the Geometry3D
virtual void Initialize();
//##Documentation
//## @brief Is this an ImageGeometry?
//##
//## For more information, see SetImageGeometry
itkGetConstMacro(ImageGeometry, bool);
//##Documentation
//## @brief Define that this Geometry3D is refering to an Image
//##
//## A geometry referring to an Image needs a slightly different
//## definition of the position of the corners (see GetCornerPoint).
//## The position of a voxel is defined by the position of its center.
//## If we would use the origin (position of the (center of) the first
//## voxel) as a corner and display this point, it would seem to be
//## \em not at the corner but a bit within the image. Even worse for
//## the opposite corner of the image: here the corner would appear
//## outside the image (by half of the voxel diameter). Thus, we have
//## to correct for this and to be able to do that, we need to know
//## that the Geometry3D is referring to an Image.
itkSetMacro(ImageGeometry, bool);
itkBooleanMacro(ImageGeometry);
//##Documentation
//## @brief Is this Geometry3D in a state that is valid?
virtual bool IsValid() const
{
return m_Valid;
}
//##Documentation
//## @brief Test whether the point \a p (world coordinates in mm) is
//## inside the bounding box
bool IsInside(const mitk::Point3D& p) const
{
mitk::Point3D index;
WorldToIndex(p, index);
return IsIndexInside(index);
}
//##Documentation
//## @brief Test whether the point \a p ((continous!)index coordinates in units) is
//## inside the bounding box
bool IsIndexInside(const mitk::Point3D& index) const
{
bool inside = false;
//if it is an image geometry, we need to convert the index to discrete values
//this is done by applying the rounding function also used in WorldToIndex (see line 323)
if (m_ImageGeometry)
{
mitk::Point3D discretIndex;
discretIndex[0]=itk::Math::RoundHalfIntegerUp( index[0] );
discretIndex[1]=itk::Math::RoundHalfIntegerUp( index[1] );
discretIndex[2]=itk::Math::RoundHalfIntegerUp( index[2] );
inside = m_BoundingBox->IsInside(discretIndex);
//we have to check if the index is at the upper border of each dimension,
// because the boundingbox is not centerbased
if (inside)
{
const BoundingBox::BoundsArrayType& bounds = m_BoundingBox->GetBounds();
if((discretIndex[0] == bounds[1]) ||
(discretIndex[1] == bounds[3]) ||
(discretIndex[2] == bounds[5]))
inside = false;
}
}
else
inside = m_BoundingBox->IsInside(index);
return inside;
}
//##Documentation
//## @brief Convenience method for working with ITK indices
template <unsigned int VIndexDimension>
bool IsIndexInside(const itk::Index<VIndexDimension> &index) const
{
int i, dim=index.GetIndexDimension();
Point3D pt_index;
pt_index.Fill(0);
for ( i = 0; i < dim; ++i )
{
pt_index[i] = index[i];
}
return IsIndexInside(pt_index);
}
//##Documentation
//## @brief Get the spacing (size of a pixel).
//##
itkGetConstReferenceMacro(Spacing, mitk::Vector3D);
//##Documentation
//## @brief Get the spacing as a float[3] array.
const float* GetFloatSpacing() const;
//##Documentation
//## @brief Set the spacing (m_Spacing)
virtual void SetSpacing(const mitk::Vector3D& aSpacing);
//##Documentation
//## @brief Get the DICOM FrameOfReferenceID referring to the
//## used world coordinate system
itkGetConstMacro(FrameOfReferenceID, unsigned int);
//##Documentation
//## @brief Set the DICOM FrameOfReferenceID referring to the
//## used world coordinate system
itkSetMacro(FrameOfReferenceID, unsigned int);
//##Documentation
//## @brief Copy the ITK transform
//## (m_IndexToWorldTransform) to the VTK transform
//## \sa SetIndexToWorldTransform
void TransferItkToVtkTransform();
//##Documentation
//## @brief Copy the VTK transform
//## to the ITK transform (m_IndexToWorldTransform)
//## \sa SetIndexToWorldTransform
void TransferVtkToItkTransform();
//##Documentation
//## @brief Get the parametric bounding-box
//##
//## See AbstractTransformGeometry for an example usage of this.
itkGetConstObjectMacro(ParametricBoundingBox, BoundingBox);
//##Documentation
//## @brief Get the parametric bounds
//##
//## See AbstractTransformGeometry for an example usage of this.
const BoundingBox::BoundsArrayType& GetParametricBounds() const
{
assert(m_ParametricBoundingBox.IsNotNull());
return m_ParametricBoundingBox->GetBounds();
}
//##Documentation
//## @brief Get the parametric extent
//##
//## See AbstractTransformGeometry for an example usage of this.
mitk::ScalarType GetParametricExtent(int direction) const
{
assert(direction>=0 && direction<3);
assert(m_ParametricBoundingBox.IsNotNull());
BoundingBoxType::BoundsArrayType bounds = m_ParametricBoundingBox->GetBounds();
return bounds[direction*2+1]-bounds[direction*2];
}
//##Documentation
//## @brief Get the parametric extent in mm
//##
//## See AbstractTransformGeometry for an example usage of this.
virtual mitk::ScalarType GetParametricExtentInMM(int direction) const
{
return GetExtentInMM(direction);
}
//##Documentation
//## @brief Get the parametric transform
//##
//## See AbstractTransformGeometry for an example usage of this.
virtual const Transform3D* GetParametricTransform() const
{
return m_IndexToWorldTransform;
}
//##Documentation
//## @brief Calculates a bounding-box around the geometry relative
//## to a coordinate system defined by a transform
//##
mitk::BoundingBox::Pointer CalculateBoundingBoxRelativeToTransform(const mitk::AffineTransform3D* transform) const;
//##Documentation
//## @brief clones the geometry
//##
//## Overwrite in all sub-classes.
//## Normally looks like:
//## \code
//## Self::Pointer newGeometry = new Self(*this);
//## newGeometry->UnRegister();
//## return newGeometry.GetPointer();
//## \endcode
virtual AffineGeometryFrame3D::Pointer Clone() const;
//##Documentation
//##@brief executes affine operations (translate, rotate, scale)
virtual void ExecuteOperation(Operation* operation);
protected:
Geometry3D();
Geometry3D(const Geometry3D& other);
static const std::string GetTransformAsString( TransformType* transformType );
virtual ~Geometry3D();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
virtual void BackTransform(const mitk::Point3D& in, mitk::Point3D& out) const;
//##Documentation
//## @brief Deprecated
virtual void BackTransform(const mitk::Point3D& at, const mitk::Vector3D& in, mitk::Vector3D& out) const;
//Without redundant parameter Point3D
virtual void BackTransform(const mitk::Vector3D& in, mitk::Vector3D& out) const;
//##Documentation
//## @brief Set the parametric bounds
//##
//## Protected in this class, made public in some sub-classes, e.g.,
//## ExternAbstractTransformGeometry.
virtual void SetParametricBounds(const BoundingBox::BoundsArrayType& bounds);
/** Resets sub-transforms that compose m_IndexToWorldTransform, by using
* the current value of m_IndexToWorldTransform and setting the rotation
* component to zero. */
virtual void ResetSubTransforms();
mutable mitk::BoundingBox::Pointer m_ParametricBoundingBox;
mutable mitk::TimeBounds m_TimeBounds;
vtkMatrix4x4* m_VtkMatrix;
bool m_ImageGeometry;
//##Documentation
//## @brief Spacing of the data. Only significant if the geometry describes
//## an Image (m_ImageGeometry==true).
mitk::Vector3D m_Spacing;
bool m_Valid;
unsigned int m_FrameOfReferenceID;
static const std::string INDEX_TO_OBJECT_TRANSFORM;
static const std::string OBJECT_TO_NODE_TRANSFORM;
static const std::string INDEX_TO_NODE_TRANSFORM;
static const std::string INDEX_TO_WORLD_TRANSFORM;
private:
mutable TransformType::Pointer m_InvertedTransform;
mutable unsigned long m_IndexToWorldTransformLastModified;
VnlQuaternionType m_RotationQuaternion;
float m_FloatSpacing[3];
vtkMatrixToLinearTransform* m_VtkIndexToWorldTransform;
//##Documentation
//## @brief Origin, i.e. upper-left corner of the plane
//##
Point3D m_Origin;
};
} // namespace mitk
#endif /* GEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD */
diff --git a/Core/Code/DataManagement/mitkGeometryData.cpp b/Core/Code/DataManagement/mitkGeometryData.cpp
index 03d2d3ed7a..5c816051fa 100644
--- a/Core/Code/DataManagement/mitkGeometryData.cpp
+++ b/Core/Code/DataManagement/mitkGeometryData.cpp
@@ -1,65 +1,64 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGeometryData.h"
#include "mitkBaseProcess.h"
mitk::GeometryData::GeometryData()
{
}
mitk::GeometryData::~GeometryData()
{
}
void mitk::GeometryData::UpdateOutputInformation()
{
Superclass::UpdateOutputInformation();
}
void mitk::GeometryData::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::GeometryData::RequestedRegionIsOutsideOfTheBufferedRegion()
{
if(GetGeometry()!=NULL) return true;
return false;
}
bool mitk::GeometryData::VerifyRequestedRegion()
{
if(GetGeometry()==NULL) return false;
return true;
}
void mitk::GeometryData::SetRequestedRegion(itk::DataObject *)
{
}
void mitk::GeometryData::CopyInformation(const itk::DataObject *)
{
}
diff --git a/Core/Code/DataManagement/mitkGeometryData.h b/Core/Code/DataManagement/mitkGeometryData.h
index 0cb6f8a934..c9b7e15eb9 100644
--- a/Core/Code/DataManagement/mitkGeometryData.h
+++ b/Core/Code/DataManagement/mitkGeometryData.h
@@ -1,58 +1,57 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGEOMETRYDATA_H_HEADER_INCLUDED_C19C01E2
#define MITKGEOMETRYDATA_H_HEADER_INCLUDED_C19C01E2
#include "mitkBaseData.h"
namespace mitk {
//##Documentation
//## @brief Data class only having a Geometry3D but not containing
//## any specific data.
//##
//## Only implements pipeline methods which are abstract in BaseData.
//## @ingroup Geometry
class MITK_CORE_EXPORT GeometryData : public BaseData
{
public:
mitkClassMacro(GeometryData, BaseData);
itkNewMacro(Self);
virtual void UpdateOutputInformation();
virtual void SetRequestedRegionToLargestPossibleRegion();
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
virtual bool VerifyRequestedRegion();
virtual void SetRequestedRegion(itk::DataObject *data);
virtual void CopyInformation(const itk::DataObject *data);
protected:
GeometryData();
virtual ~GeometryData();
};
} // namespace mitk
#endif /* MITKGEOMETRYDATA_H_HEADER_INCLUDED_C19C01E2 */
diff --git a/Core/Code/DataManagement/mitkGroupTagProperty.cpp b/Core/Code/DataManagement/mitkGroupTagProperty.cpp
index 97367bff8c..7787f8ebac 100644
--- a/Core/Code/DataManagement/mitkGroupTagProperty.cpp
+++ b/Core/Code/DataManagement/mitkGroupTagProperty.cpp
@@ -1,36 +1,35 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGroupTagProperty.h"
mitk::GroupTagProperty::GroupTagProperty()
: mitk::BaseProperty()
{
}
bool mitk::GroupTagProperty::IsEqual(const BaseProperty& /*property*/) const
{
// if other property is also a GroupTagProperty, then it is equal to us, because tags have no value themselves
return true;
}
bool mitk::GroupTagProperty::Assign(const BaseProperty& /*property*/)
{
return true;
}
diff --git a/Core/Code/DataManagement/mitkGroupTagProperty.h b/Core/Code/DataManagement/mitkGroupTagProperty.h
index ea5076ece1..3dd4fd3421 100644
--- a/Core/Code/DataManagement/mitkGroupTagProperty.h
+++ b/Core/Code/DataManagement/mitkGroupTagProperty.h
@@ -1,68 +1,67 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 GROUPTAGPROPERTY_H_HEADER_INCLUDED_C1F4DF54
#define GROUPTAGPROPERTY_H_HEADER_INCLUDED_C1F4DF54
#include <mitkBaseProperty.h>
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/*! @brief Property class that has no value.
@ingroup DataManagement
The GroupTag property is used to tag a datatree node to show, that it is member of a
group of datatree nodes. This can be used to build groups of datatreenodes without the
need to contain them in a specific hiearchic order in the datatree
*/
class MITK_CORE_EXPORT GroupTagProperty : public BaseProperty
{
public:
mitkClassMacro(GroupTagProperty, BaseProperty);
itkNewMacro(GroupTagProperty);
using BaseProperty::operator=;
protected:
GroupTagProperty();
private:
// purposely not implemented
GroupTagProperty(const GroupTagProperty&);
GroupTagProperty& operator=(const GroupTagProperty&);
virtual bool IsEqual(const BaseProperty& property) const;
virtual bool Assign(const BaseProperty& property);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif /* GROUPTAGPROPERTY_H_HEADER_INCLUDED_C1F4DF54 */
diff --git a/Core/Code/DataManagement/mitkImage.cpp b/Core/Code/DataManagement/mitkImage.cpp
index c4e1929abb..ca542d10fd 100644
--- a/Core/Code/DataManagement/mitkImage.cpp
+++ b/Core/Code/DataManagement/mitkImage.cpp
@@ -1,1279 +1,1278 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkImageStatisticsHolder.h"
#include "mitkPixelTypeMultiplex.h"
#include <vtkImageData.h>
#define FILL_C_ARRAY( _arr, _size, _value) for(unsigned int i=0u; i<_size; i++) \
{ _arr[i] = _value; }
mitk::Image::Image() :
m_Dimension(0), m_Dimensions(NULL), m_ImageDescriptor(NULL), m_OffsetTable(NULL), m_CompleteData(NULL),
m_ImageStatistics(NULL)
{
m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS];
FILL_C_ARRAY( m_Dimensions, MAX_IMAGE_DIMENSIONS, 0u);
m_Initialized = false;
}
mitk::Image::Image(const Image &other) : SlicedData(other), m_Dimension(0), m_Dimensions(NULL),
m_ImageDescriptor(NULL), m_OffsetTable(NULL), m_CompleteData(NULL), m_ImageStatistics(NULL)
{
m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS];
FILL_C_ARRAY( m_Dimensions, MAX_IMAGE_DIMENSIONS, 0u);
this->Initialize( other.GetPixelType(), other.GetDimension(), other.GetDimensions());
//Since the above called "Initialize" method doesn't take the geometry into account we need to set it
//here manually
this->SetGeometry(dynamic_cast<mitk::Geometry3D*>(other.GetGeometry()->Clone().GetPointer()));
if (this->GetDimension() > 3)
{
const unsigned int time_steps = this->GetDimension(3);
for (unsigned int i = 0u; i < time_steps; ++i)
{
ImageDataItemPointer volume = const_cast<Image&>(other).GetVolumeData(i);
this->SetVolume(volume->GetData(), i);
}
}
else
{
ImageDataItemPointer volume = const_cast<Image&>(other).GetVolumeData(0);
this->SetVolume(volume->GetData(), 0);
}
}
mitk::Image::~Image()
{
Clear();
m_ReferenceCountLock.Lock();
m_ReferenceCount = 3;
m_ReferenceCountLock.Unlock();
m_ReferenceCountLock.Lock();
m_ReferenceCount = 0;
m_ReferenceCountLock.Unlock();
if(m_OffsetTable != NULL)
delete [] m_OffsetTable;
if(m_ImageStatistics != NULL)
delete m_ImageStatistics;
}
const mitk::PixelType mitk::Image::GetPixelType(int n) const
{
return this->m_ImageDescriptor->GetChannelTypeById(n);
}
unsigned int mitk::Image::GetDimension() const
{
return m_Dimension;
}
unsigned int mitk::Image::GetDimension(int i) const
{
if((i>=0) && (i<(int)m_Dimension))
return m_Dimensions[i];
return 1;
}
void* mitk::Image::GetData()
{
if(m_Initialized==false)
{
if(GetSource().IsNull())
return NULL;
if(GetSource()->Updating()==false)
GetSource()->UpdateOutputInformation();
}
m_CompleteData=GetChannelData();
// update channel's data
// if data was not available at creation point, the m_Data of channel descriptor is NULL
// if data present, it won't be overwritten
m_ImageDescriptor->GetChannelDescriptor(0).SetData(m_CompleteData->GetData());
return m_CompleteData->GetData();
}
template <class T>
void AccessPixel( const mitk::PixelType ptype, void* data, const unsigned int offset, double& value )
{
value = 0.0;
if( data == NULL ) return;
if(ptype.GetBpe() != 24)
{
value = (double) (((T*) data)[ offset ]);
}
else
{
const unsigned int rgboffset = 3 * offset;
double returnvalue = (((T*) data)[rgboffset ]);
returnvalue += (((T*) data)[rgboffset + 1]);
returnvalue += (((T*) data)[rgboffset + 2]);
value = returnvalue;
}
}
double mitk::Image::GetPixelValueByIndex(const mitk::Index3D &position, unsigned int timestep)
{
double value = 0;
if (this->GetTimeSteps() < timestep)
{
timestep = this->GetTimeSteps();
}
value = 0.0;
const unsigned int* imageDims = this->m_ImageDescriptor->GetDimensions();
const mitk::PixelType ptype = this->m_ImageDescriptor->GetChannelTypeById(0);
// Comparison ?>=0 not needed since all position[i] and timestep are unsigned int
// (position[0]>=0 && position[1] >=0 && position[2]>=0 && timestep>=0)
// &&
if ( (unsigned int)position[0] < imageDims[0] && (unsigned int)position[1] < imageDims[1] &&
( (imageDims[2] == 0) || (unsigned int)position[2] < imageDims[2]) // in case a 2D Image passed in, the third dimension could be set to 0 causing the if() to fail
/*&& (unsigned int)timestep < imageDims[3]*/ )
{
const unsigned int offset = position[0] + position[1]*imageDims[0] + position[2]*imageDims[0]*imageDims[1] + timestep*imageDims[0]*imageDims[1]*imageDims[2];
mitkPixelTypeMultiplex3( AccessPixel, ptype, this->GetData(), offset, value );
}
return value;
}
double mitk::Image::GetPixelValueByWorldCoordinate(const mitk::Point3D& position, unsigned int timestep)
{
double value = 0.0;
if (this->GetTimeSteps() < timestep)
{
timestep = this->GetTimeSteps();
}
Index3D itkIndex;
this->GetGeometry()->WorldToIndex(position, itkIndex);
const unsigned int* imageDims = this->m_ImageDescriptor->GetDimensions();
const mitk::PixelType ptype = this->m_ImageDescriptor->GetChannelTypeById(0);
//if ( (itkIndex[0]>=0 && itkIndex[1] >=0 && itkIndex[2]>=0 && timestep>=0)
// &&
// lines above taken from comparison since always true due to unsigned type
if (((unsigned int)itkIndex[0] < imageDims[0] &&
(unsigned int)itkIndex[1] < imageDims[1] &&
(imageDims[2] == 0) ) || ((unsigned int)itkIndex[2] < imageDims[2])) // in case a 2D Image passed in, the third dimension could be set to 0 causing the if() to fail
{
const unsigned int offset = itkIndex[0] + itkIndex[1]*imageDims[0] + itkIndex[2]*imageDims[0]*imageDims[1] + timestep*imageDims[0]*imageDims[1]*imageDims[2];
mitkPixelTypeMultiplex3( AccessPixel, ptype, this->GetData(), offset, value );
}
return value;
}
vtkImageData* mitk::Image::GetVtkImageData(int t, int n)
{
if(m_Initialized==false)
{
if(GetSource().IsNull())
return NULL;
if(GetSource()->Updating()==false)
GetSource()->UpdateOutputInformation();
}
ImageDataItemPointer volume=GetVolumeData(t, n);
if(volume.GetPointer()==NULL || volume->GetVtkImageData() == NULL)
return NULL;
float *fspacing = const_cast<float *>(GetSlicedGeometry(t)->GetFloatSpacing());
double dspacing[3] = {fspacing[0],fspacing[1],fspacing[2]};
volume->GetVtkImageData()->SetSpacing( dspacing );
return volume->GetVtkImageData();
}
mitk::Image::ImageDataItemPointer mitk::Image::GetSliceData(int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement)
{
if(IsValidSlice(s,t,n)==false) return NULL;
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
// slice directly available?
int pos=GetSliceIndex(s,t,n);
if(m_Slices[pos].GetPointer()!=NULL)
return m_Slices[pos];
// is slice available as part of a volume that is available?
ImageDataItemPointer sl, ch, vol;
vol=m_Volumes[GetVolumeIndex(t,n)];
if((vol.GetPointer()!=NULL) && (vol->IsComplete()))
{
sl=new ImageDataItem(*vol, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(ptypeSize));
sl->SetComplete(true);
return m_Slices[pos]=sl;
}
// is slice available as part of a channel that is available?
ch=m_Channels[n];
if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
{
sl=new ImageDataItem(*ch, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, (((size_t) s)*m_OffsetTable[2]+((size_t) t)*m_OffsetTable[3])*(ptypeSize));
sl->SetComplete(true);
return m_Slices[pos]=sl;
}
// slice is unavailable. Can we calculate it?
if((GetSource().IsNotNull()) && (GetSource()->Updating()==false))
{
// ... wir mussen rechnen!!! ....
m_RequestedRegion.SetIndex(0, 0);
m_RequestedRegion.SetIndex(1, 0);
m_RequestedRegion.SetIndex(2, s);
m_RequestedRegion.SetIndex(3, t);
m_RequestedRegion.SetIndex(4, n);
m_RequestedRegion.SetSize(0, m_Dimensions[0]);
m_RequestedRegion.SetSize(1, m_Dimensions[1]);
m_RequestedRegion.SetSize(2, 1);
m_RequestedRegion.SetSize(3, 1);
m_RequestedRegion.SetSize(4, 1);
m_RequestedRegionInitialized=true;
GetSource()->Update();
if(IsSliceSet(s,t,n))
//yes: now we can call ourselves without the risk of a endless loop (see "if" above)
return GetSliceData(s,t,n,data,importMemoryManagement);
else
return NULL;
}
else
{
ImageDataItemPointer item = AllocateSliceData(s,t,n,data,importMemoryManagement);
item->SetComplete(true);
return item;
}
}
mitk::Image::ImageDataItemPointer mitk::Image::GetVolumeData(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement)
{
if(IsValidVolume(t,n)==false) return NULL;
ImageDataItemPointer ch, vol;
// volume directly available?
int pos=GetVolumeIndex(t,n);
vol=m_Volumes[pos];
if((vol.GetPointer()!=NULL) && (vol->IsComplete()))
return vol;
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
// is volume available as part of a channel that is available?
ch=m_Channels[n];
if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
{
vol=new ImageDataItem(*ch, m_ImageDescriptor, 3, data, importMemoryManagement == ManageMemory, (((size_t) t)*m_OffsetTable[3])*(ptypeSize));
vol->SetComplete(true);
return m_Volumes[pos]=vol;
}
// let's see if all slices of the volume are set, so that we can (could) combine them to a volume
bool complete=true;
unsigned int s;
for(s=0;s<m_Dimensions[2];++s)
{
if(m_Slices[GetSliceIndex(s,t,n)].GetPointer()==NULL)
{
complete=false;
break;
}
}
if(complete)
{
// if there is only single slice we do not need to combine anything
if(m_Dimensions[2]<=1)
{
ImageDataItemPointer sl;
sl=GetSliceData(0,t,n,data,importMemoryManagement);
vol=new ImageDataItem(*sl, m_ImageDescriptor, 3, data, importMemoryManagement == ManageMemory);
vol->SetComplete(true);
}
else
{
mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(n);
vol=m_Volumes[pos];
// ok, let's combine the slices!
if(vol.GetPointer()==NULL)
vol=new ImageDataItem( chPixelType, 3, m_Dimensions, NULL, true);
vol->SetComplete(true);
size_t size=m_OffsetTable[2]*(ptypeSize);
for(s=0;s<m_Dimensions[2];++s)
{
int posSl;
ImageDataItemPointer sl;
posSl=GetSliceIndex(s,t,n);
sl=m_Slices[posSl];
if(sl->GetParent()!=vol)
{
// copy data of slices in volume
size_t offset = ((size_t) s)*size;
std::memcpy(static_cast<char*>(vol->GetData())+offset, sl->GetData(), size);
// FIXME mitkIpPicDescriptor * pic = sl->GetPicDescriptor();
// replace old slice with reference to volume
sl=new ImageDataItem(*vol, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*size);
sl->SetComplete(true);
//mitkIpFuncCopyTags(sl->GetPicDescriptor(), pic);
m_Slices[posSl]=sl;
}
}
//if(vol->GetPicDescriptor()->info->tags_head==NULL)
// mitkIpFuncCopyTags(vol->GetPicDescriptor(), m_Slices[GetSliceIndex(0,t,n)]->GetPicDescriptor());
}
return m_Volumes[pos]=vol;
}
// volume is unavailable. Can we calculate it?
if((GetSource().IsNotNull()) && (GetSource()->Updating()==false))
{
// ... wir muessen rechnen!!! ....
m_RequestedRegion.SetIndex(0, 0);
m_RequestedRegion.SetIndex(1, 0);
m_RequestedRegion.SetIndex(2, 0);
m_RequestedRegion.SetIndex(3, t);
m_RequestedRegion.SetIndex(4, n);
m_RequestedRegion.SetSize(0, m_Dimensions[0]);
m_RequestedRegion.SetSize(1, m_Dimensions[1]);
m_RequestedRegion.SetSize(2, m_Dimensions[2]);
m_RequestedRegion.SetSize(3, 1);
m_RequestedRegion.SetSize(4, 1);
m_RequestedRegionInitialized=true;
GetSource()->Update();
if(IsVolumeSet(t,n))
//yes: now we can call ourselves without the risk of a endless loop (see "if" above)
return GetVolumeData(t,n,data,importMemoryManagement);
else
return NULL;
}
else
{
ImageDataItemPointer item = AllocateVolumeData(t,n,data,importMemoryManagement);
item->SetComplete(true);
return item;
}
}
mitk::Image::ImageDataItemPointer mitk::Image::GetChannelData(int n, void *data, ImportMemoryManagementType importMemoryManagement)
{
if(IsValidChannel(n)==false) return NULL;
ImageDataItemPointer ch, vol;
ch=m_Channels[n];
if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
return ch;
// let's see if all volumes are set, so that we can (could) combine them to a channel
if(IsChannelSet(n))
{
// if there is only one time frame we do not need to combine anything
if(m_Dimensions[3]<=1)
{
vol=GetVolumeData(0,n,data,importMemoryManagement);
ch=new ImageDataItem(*vol, m_ImageDescriptor, m_ImageDescriptor->GetNumberOfDimensions(), data, importMemoryManagement == ManageMemory);
ch->SetComplete(true);
}
else
{
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
ch=m_Channels[n];
// ok, let's combine the volumes!
if(ch.GetPointer()==NULL)
ch=new ImageDataItem(this->m_ImageDescriptor, NULL, true);
ch->SetComplete(true);
size_t size=m_OffsetTable[m_Dimension-1]*(ptypeSize);
unsigned int t;
ImageDataItemPointerArray::iterator slicesIt = m_Slices.begin()+n*m_Dimensions[2]*m_Dimensions[3];
for(t=0;t<m_Dimensions[3];++t)
{
int posVol;
ImageDataItemPointer vol;
posVol=GetVolumeIndex(t,n);
vol=GetVolumeData(t,n,data,importMemoryManagement);
if(vol->GetParent()!=ch)
{
// copy data of volume in channel
size_t offset = ((size_t) t)*m_OffsetTable[3]*(ptypeSize);
std::memcpy(static_cast<char*>(ch->GetData())+offset, vol->GetData(), size);
// REVEIW FIX mitkIpPicDescriptor * pic = vol->GetPicDescriptor();
// replace old volume with reference to channel
vol=new ImageDataItem(*ch, m_ImageDescriptor, 3, data, importMemoryManagement == ManageMemory, offset);
vol->SetComplete(true);
//mitkIpFuncCopyTags(vol->GetPicDescriptor(), pic);
m_Volumes[posVol]=vol;
// get rid of slices - they may point to old volume
ImageDataItemPointer dnull=NULL;
for(unsigned int i = 0; i < m_Dimensions[2]; ++i, ++slicesIt)
{
assert(slicesIt != m_Slices.end());
*slicesIt = dnull;
}
}
}
// REVIEW FIX
// if(ch->GetPicDescriptor()->info->tags_head==NULL)
// mitkIpFuncCopyTags(ch->GetPicDescriptor(), m_Volumes[GetVolumeIndex(0,n)]->GetPicDescriptor());
}
return m_Channels[n]=ch;
}
// channel is unavailable. Can we calculate it?
if((GetSource().IsNotNull()) && (GetSource()->Updating()==false))
{
// ... wir muessen rechnen!!! ....
m_RequestedRegion.SetIndex(0, 0);
m_RequestedRegion.SetIndex(1, 0);
m_RequestedRegion.SetIndex(2, 0);
m_RequestedRegion.SetIndex(3, 0);
m_RequestedRegion.SetIndex(4, n);
m_RequestedRegion.SetSize(0, m_Dimensions[0]);
m_RequestedRegion.SetSize(1, m_Dimensions[1]);
m_RequestedRegion.SetSize(2, m_Dimensions[2]);
m_RequestedRegion.SetSize(3, m_Dimensions[3]);
m_RequestedRegion.SetSize(4, 1);
m_RequestedRegionInitialized=true;
GetSource()->Update();
// did it work?
if(IsChannelSet(n))
//yes: now we can call ourselves without the risk of a endless loop (see "if" above)
return GetChannelData(n,data,importMemoryManagement);
else
return NULL;
}
else
{
ImageDataItemPointer item = AllocateChannelData(n,data,importMemoryManagement);
item->SetComplete(true);
return item;
}
}
bool mitk::Image::IsSliceSet(int s, int t, int n) const
{
if(IsValidSlice(s,t,n)==false) return false;
if(m_Slices[GetSliceIndex(s,t,n)].GetPointer()!=NULL)
return true;
ImageDataItemPointer ch, vol;
vol=m_Volumes[GetVolumeIndex(t,n)];
if((vol.GetPointer()!=NULL) && (vol->IsComplete()))
return true;
ch=m_Channels[n];
if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
return true;
return false;
}
bool mitk::Image::IsVolumeSet(int t, int n) const
{
if(IsValidVolume(t,n)==false) return false;
ImageDataItemPointer ch, vol;
// volume directly available?
vol=m_Volumes[GetVolumeIndex(t,n)];
if((vol.GetPointer()!=NULL) && (vol->IsComplete()))
return true;
// is volume available as part of a channel that is available?
ch=m_Channels[n];
if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
return true;
// let's see if all slices of the volume are set, so that we can (could) combine them to a volume
unsigned int s;
for(s=0;s<m_Dimensions[2];++s)
if(m_Slices[GetSliceIndex(s,t,n)].GetPointer()==NULL)
return false;
return true;
}
bool mitk::Image::IsChannelSet(int n) const
{
if(IsValidChannel(n)==false) return false;
ImageDataItemPointer ch, vol;
ch=m_Channels[n];
if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
return true;
// let's see if all volumes are set, so that we can (could) combine them to a channel
unsigned int t;
for(t=0;t<m_Dimensions[3];++t)
if(IsVolumeSet(t,n)==false)
return false;
return true;
}
bool mitk::Image::SetSlice(const void *data, int s, int t, int n)
{
// const_cast is no risk for ImportMemoryManagementType == CopyMemory
return SetImportSlice(const_cast<void*>(data), s, t, n, CopyMemory);
}
bool mitk::Image::SetVolume(const void *data, int t, int n)
{
// const_cast is no risk for ImportMemoryManagementType == CopyMemory
return SetImportVolume(const_cast<void*>(data), t, n, CopyMemory);
}
bool mitk::Image::SetChannel(const void *data, int n)
{
// const_cast is no risk for ImportMemoryManagementType == CopyMemory
return SetImportChannel(const_cast<void*>(data), n, CopyMemory);
}
bool mitk::Image::SetImportSlice(void *data, int s, int t, int n, ImportMemoryManagementType importMemoryManagement)
{
if(IsValidSlice(s,t,n)==false) return false;
ImageDataItemPointer sl;
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
if(IsSliceSet(s,t,n))
{
sl=GetSliceData(s,t,n,data,importMemoryManagement);
if(sl->GetManageMemory()==false)
{
sl=AllocateSliceData(s,t,n,data,importMemoryManagement);
if(sl.GetPointer()==NULL) return false;
}
if ( sl->GetData() != data )
std::memcpy(sl->GetData(), data, m_OffsetTable[2]*(ptypeSize));
sl->Modified();
//we have changed the data: call Modified()!
Modified();
}
else
{
sl=AllocateSliceData(s,t,n,data,importMemoryManagement);
if(sl.GetPointer()==NULL) return false;
if ( sl->GetData() != data )
std::memcpy(sl->GetData(), data, m_OffsetTable[2]*(ptypeSize));
//we just added a missing slice, which is not regarded as modification.
//Therefore, we do not call Modified()!
}
return true;
}
bool mitk::Image::SetImportVolume(void *data, int t, int n, ImportMemoryManagementType importMemoryManagement)
{
if(IsValidVolume(t,n)==false) return false;
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
ImageDataItemPointer vol;
if(IsVolumeSet(t,n))
{
vol=GetVolumeData(t,n,data,importMemoryManagement);
if(vol->GetManageMemory()==false)
{
vol=AllocateVolumeData(t,n,data,importMemoryManagement);
if(vol.GetPointer()==NULL) return false;
}
if ( vol->GetData() != data )
std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(ptypeSize));
vol->Modified();
vol->SetComplete(true);
//we have changed the data: call Modified()!
Modified();
}
else
{
vol=AllocateVolumeData(t,n,data,importMemoryManagement);
if(vol.GetPointer()==NULL) return false;
if ( vol->GetData() != data )
{
std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(ptypeSize));
}
vol->SetComplete(true);
this->m_ImageDescriptor->GetChannelDescriptor(n).SetData( vol->GetData() );
//we just added a missing Volume, which is not regarded as modification.
//Therefore, we do not call Modified()!
}
return true;
}
bool mitk::Image::SetImportChannel(void *data, int n, ImportMemoryManagementType importMemoryManagement)
{
if(IsValidChannel(n)==false) return false;
// channel descriptor
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
ImageDataItemPointer ch;
if(IsChannelSet(n))
{
ch=GetChannelData(n,data,importMemoryManagement);
if(ch->GetManageMemory()==false)
{
ch=AllocateChannelData(n,data,importMemoryManagement);
if(ch.GetPointer()==NULL) return false;
}
if ( ch->GetData() != data )
std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(ptypeSize));
ch->Modified();
ch->SetComplete(true);
//we have changed the data: call Modified()!
Modified();
}
else
{
ch=AllocateChannelData(n,data,importMemoryManagement);
if(ch.GetPointer()==NULL) return false;
if ( ch->GetData() != data )
std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(ptypeSize));
ch->SetComplete(true);
this->m_ImageDescriptor->GetChannelDescriptor(n).SetData( ch->GetData() );
//we just added a missing Channel, which is not regarded as modification.
//Therefore, we do not call Modified()!
}
return true;
}
void mitk::Image::Initialize()
{
ImageDataItemPointerArray::iterator it, end;
for( it=m_Slices.begin(), end=m_Slices.end(); it!=end; ++it )
{
(*it)=NULL;
}
for( it=m_Volumes.begin(), end=m_Volumes.end(); it!=end; ++it )
{
(*it)=NULL;
}
for( it=m_Channels.begin(), end=m_Channels.end(); it!=end; ++it )
{
(*it)=NULL;
}
m_CompleteData = NULL;
if( m_ImageStatistics == NULL)
{
m_ImageStatistics = new mitk::ImageStatisticsHolder( this );
}
SetRequestedRegionToLargestPossibleRegion();
}
void mitk::Image::Initialize(const mitk::ImageDescriptor::Pointer inDesc)
{
// store the descriptor
this->m_ImageDescriptor = inDesc;
// initialize image
this->Initialize( inDesc->GetChannelDescriptor(0).GetPixelType(), inDesc->GetNumberOfDimensions(), inDesc->GetDimensions(), 1 );
}
void mitk::Image::Initialize(const mitk::PixelType& type, unsigned int dimension, const unsigned int *dimensions, unsigned int channels)
{
Clear();
m_Dimension=dimension;
if(!dimensions)
itkExceptionMacro(<< "invalid zero dimension image");
unsigned int i;
for(i=0;i<dimension;++i)
{
if(dimensions[i]<1)
itkExceptionMacro(<< "invalid dimension[" << i << "]: " << dimensions[i]);
}
// create new array since the old was deleted
m_Dimensions = new unsigned int[MAX_IMAGE_DIMENSIONS];
// initialize the first four dimensions to 1, the remaining 4 to 0
FILL_C_ARRAY(m_Dimensions, 4, 1u);
FILL_C_ARRAY((m_Dimensions+4), 4, 0u);
// copy in the passed dimension information
std::memcpy(m_Dimensions, dimensions, sizeof(unsigned int)*m_Dimension);
this->m_ImageDescriptor = mitk::ImageDescriptor::New();
this->m_ImageDescriptor->Initialize( this->m_Dimensions, this->m_Dimension );
for(i=0;i<4;++i)
{
m_LargestPossibleRegion.SetIndex(i, 0);
m_LargestPossibleRegion.SetSize (i, m_Dimensions[i]);
}
m_LargestPossibleRegion.SetIndex(i, 0);
m_LargestPossibleRegion.SetSize(i, channels);
if(m_LargestPossibleRegion.GetNumberOfPixels()==0)
{
delete [] m_Dimensions;
m_Dimensions = NULL;
return;
}
for( unsigned int i=0u; i<channels; i++)
{
this->m_ImageDescriptor->AddNewChannel( type );
}
PlaneGeometry::Pointer planegeometry = PlaneGeometry::New();
planegeometry->InitializeStandardPlane(m_Dimensions[0], m_Dimensions[1]);
SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New();
slicedGeometry->InitializeEvenlySpaced(planegeometry, m_Dimensions[2]);
if(dimension>=4)
{
TimeBounds timebounds;
timebounds[0] = 0.0;
timebounds[1] = 1.0;
slicedGeometry->SetTimeBounds(timebounds);
}
TimeSlicedGeometry::Pointer timeSliceGeometry = TimeSlicedGeometry::New();
timeSliceGeometry->InitializeEvenlyTimed(slicedGeometry, m_Dimensions[3]);
timeSliceGeometry->ImageGeometryOn();
SetGeometry(timeSliceGeometry);
ImageDataItemPointer dnull=NULL;
m_Channels.assign(GetNumberOfChannels(), dnull);
m_Volumes.assign(GetNumberOfChannels()*m_Dimensions[3], dnull);
m_Slices.assign(GetNumberOfChannels()*m_Dimensions[3]*m_Dimensions[2], dnull);
ComputeOffsetTable();
Initialize();
m_Initialized = true;
}
void mitk::Image::Initialize(const mitk::PixelType& type, const mitk::Geometry3D& geometry, unsigned int channels, int tDim )
{
unsigned int dimensions[5];
dimensions[0] = (unsigned int)(geometry.GetExtent(0)+0.5);
dimensions[1] = (unsigned int)(geometry.GetExtent(1)+0.5);
dimensions[2] = (unsigned int)(geometry.GetExtent(2)+0.5);
dimensions[3] = 0;
dimensions[4] = 0;
unsigned int dimension = 2;
if ( dimensions[2] > 1 )
dimension = 3;
if ( tDim > 0)
{
dimensions[3] = tDim;
}
else
{
const mitk::TimeSlicedGeometry* timeGeometry = dynamic_cast<const mitk::TimeSlicedGeometry*>(&geometry);
if ( timeGeometry != NULL )
{
dimensions[3] = timeGeometry->GetTimeSteps();
}
}
if ( dimensions[3] > 1 )
dimension = 4;
Initialize( type, dimension, dimensions, channels );
SetGeometry(static_cast<Geometry3D*>(geometry.Clone().GetPointer()));
mitk::BoundingBox::BoundsArrayType bounds = geometry.GetBoundingBox()->GetBounds();
if( (bounds[0] != 0.0) || (bounds[2] != 0.0) || (bounds[4] != 0.0) )
{
SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0);
mitk::Point3D origin; origin.Fill(0.0);
slicedGeometry->IndexToWorld(origin, origin);
bounds[1]-=bounds[0]; bounds[3]-=bounds[2]; bounds[5]-=bounds[4];
bounds[0] = 0.0; bounds[2] = 0.0; bounds[4] = 0.0;
this->m_ImageDescriptor->Initialize( this->m_Dimensions, this->m_Dimension );
slicedGeometry->SetBounds(bounds);
slicedGeometry->GetIndexToWorldTransform()->SetOffset(origin.Get_vnl_vector().data_block());
GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, m_Dimensions[3]);
}
}
void mitk::Image::Initialize(const mitk::PixelType& type, int sDim, const mitk::Geometry2D& geometry2d, bool flipped, unsigned int channels, int tDim )
{
SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New();
slicedGeometry->InitializeEvenlySpaced(static_cast<Geometry2D*>(geometry2d.Clone().GetPointer()), sDim, flipped);
Initialize(type, *slicedGeometry, channels, tDim);
}
void mitk::Image::Initialize(const mitk::Image* image)
{
Initialize(image->GetPixelType(), *image->GetTimeSlicedGeometry());
}
void mitk::Image::Initialize(vtkImageData* vtkimagedata, int channels, int tDim, int sDim)
{
if(vtkimagedata==NULL) return;
m_Dimension=vtkimagedata->GetDataDimension();
unsigned int i, *tmpDimensions=new unsigned int[m_Dimension>4?m_Dimension:4];
for(i=0;i<m_Dimension;++i) tmpDimensions[i]=vtkimagedata->GetDimensions()[i];
if(m_Dimension<4)
{
unsigned int *p;
for(i=0,p=tmpDimensions+m_Dimension;i<4-m_Dimension;++i, ++p)
*p=1;
}
if(sDim>=0)
{
tmpDimensions[2]=sDim;
if(m_Dimension < 3)
m_Dimension = 3;
}
if(tDim>=0)
{
tmpDimensions[3]=tDim;
if(m_Dimension < 4)
m_Dimension = 4;
}
switch ( vtkimagedata->GetScalarType() )
{
case VTK_BIT:
case VTK_CHAR:
//pixelType.Initialize(typeid(char), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<char>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_UNSIGNED_CHAR:
//pixelType.Initialize(typeid(unsigned char), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<unsigned char>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_SHORT:
//pixelType.Initialize(typeid(short), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<short>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_UNSIGNED_SHORT:
//pixelType.Initialize(typeid(unsigned short), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<unsigned short>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_INT:
//pixelType.Initialize(typeid(int), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<int>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_UNSIGNED_INT:
//pixelType.Initialize(typeid(unsigned int), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<unsigned int>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_LONG:
//pixelType.Initialize(typeid(long), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<long>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_UNSIGNED_LONG:
//pixelType.Initialize(typeid(unsigned long), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<unsigned long>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_FLOAT:
//pixelType.Initialize(typeid(float), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<float>(), m_Dimension, tmpDimensions, channels);
break;
case VTK_DOUBLE:
//pixelType.Initialize(typeid(double), vtkimagedata->GetNumberOfScalarComponents());
Initialize(mitk::MakeScalarPixelType<double>(), m_Dimension, tmpDimensions, channels);
break;
default:
break;
}
/*
Initialize(pixelType,
m_Dimension,
tmpDimensions,
channels);
*/
const double *spacinglist = vtkimagedata->GetSpacing();
Vector3D spacing;
FillVector3D(spacing, spacinglist[0], 1.0, 1.0);
if(m_Dimension>=2)
spacing[1]=spacinglist[1];
if(m_Dimension>=3)
spacing[2]=spacinglist[2];
// access origin of vtkImage
Point3D origin;
vtkFloatingPointType vtkorigin[3];
vtkimagedata->GetOrigin(vtkorigin);
FillVector3D(origin, vtkorigin[0], 0.0, 0.0);
if(m_Dimension>=2)
origin[1]=vtkorigin[1];
if(m_Dimension>=3)
origin[2]=vtkorigin[2];
SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0);
// re-initialize PlaneGeometry with origin and direction
PlaneGeometry* planeGeometry = static_cast<PlaneGeometry*>(slicedGeometry->GetGeometry2D(0));
planeGeometry->SetOrigin(origin);
// re-initialize SlicedGeometry3D
slicedGeometry->SetOrigin(origin);
slicedGeometry->SetSpacing(spacing);
GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, m_Dimensions[3]);
delete [] tmpDimensions;
}
bool mitk::Image::IsValidSlice(int s, int t, int n) const
{
if(m_Initialized)
return ((s>=0) && (s<(int)m_Dimensions[2]) && (t>=0) && (t< (int) m_Dimensions[3]) && (n>=0) && (n< (int)GetNumberOfChannels()));
else
return false;
}
bool mitk::Image::IsValidVolume(int t, int n) const
{
if(m_Initialized)
return IsValidSlice(0, t, n);
else
return false;
}
bool mitk::Image::IsValidChannel(int n) const
{
if(m_Initialized)
return IsValidSlice(0, 0, n);
else
return false;
}
void mitk::Image::ComputeOffsetTable()
{
if(m_OffsetTable!=NULL)
delete [] m_OffsetTable;
m_OffsetTable=new size_t[m_Dimension>4 ? m_Dimension+1 : 4+1];
unsigned int i;
size_t num=1;
m_OffsetTable[0] = 1;
for (i=0; i < m_Dimension; ++i)
{
num *= m_Dimensions[i];
m_OffsetTable[i+1] = num;
}
for (;i < 4; ++i)
m_OffsetTable[i+1] = num;
}
bool mitk::Image::IsValidTimeStep(int t) const
{
return ( ( m_Dimension >= 4 && t <= (int)m_Dimensions[3] && t > 0 ) || (t == 0) );
}
void mitk::Image::Expand(unsigned int timeSteps)
{
if(timeSteps < 1) itkExceptionMacro(<< "Invalid timestep in Image!");
Superclass::Expand(timeSteps);
}
int mitk::Image::GetSliceIndex(int s, int t, int n) const
{
if(IsValidSlice(s,t,n)==false) return false;
return ((size_t)s)+((size_t) t)*m_Dimensions[2]+((size_t) n)*m_Dimensions[3]*m_Dimensions[2]; //??
}
int mitk::Image::GetVolumeIndex(int t, int n) const
{
if(IsValidVolume(t,n)==false) return false;
return ((size_t)t)+((size_t) n)*m_Dimensions[3]; //??
}
mitk::Image::ImageDataItemPointer mitk::Image::AllocateSliceData(int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement)
{
int pos;
pos=GetSliceIndex(s,t,n);
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
// is slice available as part of a volume that is available?
ImageDataItemPointer sl, ch, vol;
vol=m_Volumes[GetVolumeIndex(t,n)];
if(vol.GetPointer()!=NULL)
{
sl=new ImageDataItem(*vol, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(ptypeSize));
sl->SetComplete(true);
return m_Slices[pos]=sl;
}
// is slice available as part of a channel that is available?
ch=m_Channels[n];
if(ch.GetPointer()!=NULL)
{
sl=new ImageDataItem(*ch, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, (((size_t) s)*m_OffsetTable[2]+((size_t) t)*m_OffsetTable[3])*(ptypeSize));
sl->SetComplete(true);
return m_Slices[pos]=sl;
}
// allocate new volume (instead of a single slice to keep data together!)
m_Volumes[GetVolumeIndex(t,n)]=vol=AllocateVolumeData(t,n,NULL,importMemoryManagement);
sl=new ImageDataItem(*vol, m_ImageDescriptor, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(ptypeSize));
sl->SetComplete(true);
return m_Slices[pos]=sl;
////ALTERNATIVE:
//// allocate new slice
//sl=new ImageDataItem(*m_PixelType, 2, m_Dimensions);
//m_Slices[pos]=sl;
//return vol;
}
mitk::Image::ImageDataItemPointer mitk::Image::AllocateVolumeData(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement)
{
int pos;
pos=GetVolumeIndex(t,n);
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
// is volume available as part of a channel that is available?
ImageDataItemPointer ch, vol;
ch=m_Channels[n];
if(ch.GetPointer()!=NULL)
{
vol=new ImageDataItem(*ch, m_ImageDescriptor, 3, data,importMemoryManagement == ManageMemory, (((size_t) t)*m_OffsetTable[3])*(ptypeSize));
return m_Volumes[pos]=vol;
}
mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(n);
// allocate new volume
if(importMemoryManagement == CopyMemory)
{
vol=new ImageDataItem( chPixelType, 3, m_Dimensions, NULL, true);
if(data != NULL)
std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(ptypeSize));
}
else
{
vol=new ImageDataItem( chPixelType, 3, m_Dimensions, data, importMemoryManagement == ManageMemory);
}
m_Volumes[pos]=vol;
return vol;
}
mitk::Image::ImageDataItemPointer mitk::Image::AllocateChannelData(int n, void *data, ImportMemoryManagementType importMemoryManagement)
{
ImageDataItemPointer ch;
// allocate new channel
if(importMemoryManagement == CopyMemory)
{
const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize();
ch=new ImageDataItem(this->m_ImageDescriptor, NULL, true);
if(data != NULL)
std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(ptypeSize));
}
else
{
ch=new ImageDataItem(this->m_ImageDescriptor, data, importMemoryManagement == ManageMemory);
}
m_Channels[n]=ch;
return ch;
}
unsigned int* mitk::Image::GetDimensions() const
{
return m_Dimensions;
}
void mitk::Image::Clear()
{
Superclass::Clear();
delete [] m_Dimensions;
m_Dimensions = NULL;
}
void mitk::Image::SetGeometry(Geometry3D* aGeometry3D)
{
// Please be aware of the 0.5 offset/pixel-center issue! See Geometry documentation for further information
if(aGeometry3D->GetImageGeometry()==false)
{
MITK_INFO << "WARNING: Applied a non-image geometry onto an image. Please be SURE that this geometry is pixel-center-based! If it is not, you need to call Geometry3D->ChangeImageGeometryConsideringOriginOffset(true) before calling image->setGeometry(..)\n";
}
Superclass::SetGeometry(aGeometry3D);
GetTimeSlicedGeometry()->ImageGeometryOn();
}
void mitk::Image::PrintSelf(std::ostream& os, itk::Indent indent) const
{
unsigned char i;
if(m_Initialized)
{
os << indent << " Dimension: " << m_Dimension << std::endl;
os << indent << " Dimensions: ";
for(i=0; i < m_Dimension; ++i)
os << GetDimension(i) << " ";
os << std::endl;
for(unsigned int ch=0; ch < this->m_ImageDescriptor->GetNumberOfChannels(); ch++)
{
mitk::PixelType chPixelType = this->m_ImageDescriptor->GetChannelTypeById(ch);
os << indent << " Channel: " << this->m_ImageDescriptor->GetChannelName(ch) << std::endl;
os << indent << " PixelType: " << chPixelType.GetTypeId().name() << std::endl;
os << indent << " BitsPerElement: " << chPixelType.GetSize() << std::endl;
os << indent << " NumberOfComponents: " << chPixelType.GetNumberOfComponents() << std::endl;
os << indent << " BitsPerComponent: " << chPixelType.GetBitsPerComponent() << std::endl;
}
}
else
{
os << indent << " Image not initialized: m_Initialized: false" << std::endl;
}
Superclass::PrintSelf(os,indent);
}
bool mitk::Image::IsRotated() const
{
const mitk::Geometry3D* geo = this->GetGeometry();
bool ret = false;
if(geo)
{
const vnl_matrix_fixed<float, 3, 3> & mx = geo->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
float ref = 0;
for(short k = 0; k < 3; ++k)
ref += mx[k][k];
ref/=1000; // Arbitrary value; if a non-diagonal (nd) element is bigger then this, matrix is considered nd.
for(short i = 0; i < 3; ++i)
{
for(short j = 0; j < 3; ++j)
{
if(i != j)
{
if(abs(mx[i][j]) > ref) // matrix is nd
ret = true;
}
}
}
}
return ret;
}
#include "mitkImageStatisticsHolder.h"
//##Documentation
mitk::ScalarType mitk::Image::GetScalarValueMin(int t) const
{
return m_ImageStatistics->GetScalarValueMin(t);
}
//##Documentation
//## \brief Get the maximum for scalar images
mitk::ScalarType mitk::Image::GetScalarValueMax(int t) const
{
return m_ImageStatistics->GetScalarValueMax(t);
}
//##Documentation
//## \brief Get the second smallest value for scalar images
mitk::ScalarType mitk::Image::GetScalarValue2ndMin(int t) const
{
return m_ImageStatistics->GetScalarValue2ndMin(t);
}
mitk::ScalarType mitk::Image::GetScalarValueMinNoRecompute( unsigned int t ) const
{
return m_ImageStatistics->GetScalarValueMinNoRecompute(t);
}
mitk::ScalarType mitk::Image::GetScalarValue2ndMinNoRecompute( unsigned int t ) const
{
return m_ImageStatistics->GetScalarValue2ndMinNoRecompute(t);
}
mitk::ScalarType mitk::Image::GetScalarValue2ndMax(int t) const
{
return m_ImageStatistics->GetScalarValue2ndMax(t);
}
mitk::ScalarType mitk::Image::GetScalarValueMaxNoRecompute( unsigned int t) const
{
return m_ImageStatistics->GetScalarValueMaxNoRecompute(t);
}
mitk::ScalarType mitk::Image::GetScalarValue2ndMaxNoRecompute( unsigned int t ) const
{
return m_ImageStatistics->GetScalarValue2ndMaxNoRecompute(t);
}
mitk::ScalarType mitk::Image::GetCountOfMinValuedVoxels(int t ) const
{
return m_ImageStatistics->GetCountOfMinValuedVoxels(t);
}
mitk::ScalarType mitk::Image::GetCountOfMaxValuedVoxels(int t) const
{
return m_ImageStatistics->GetCountOfMaxValuedVoxels(t);
}
unsigned int mitk::Image::GetCountOfMaxValuedVoxelsNoRecompute( unsigned int t ) const
{
return m_ImageStatistics->GetCountOfMaxValuedVoxelsNoRecompute(t);
}
unsigned int mitk::Image::GetCountOfMinValuedVoxelsNoRecompute( unsigned int t ) const
{
return m_ImageStatistics->GetCountOfMinValuedVoxelsNoRecompute(t);
}
diff --git a/Core/Code/DataManagement/mitkImage.h b/Core/Code/DataManagement/mitkImage.h
index de9279f611..707baf2bfe 100644
--- a/Core/Code/DataManagement/mitkImage.h
+++ b/Core/Code/DataManagement/mitkImage.h
@@ -1,647 +1,646 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2
#define MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2
#include <MitkExports.h>
#include "mitkSlicedData.h"
#include "mitkBaseData.h"
#include "mitkLevelWindow.h"
#include "mitkPlaneGeometry.h"
#include "mitkImageDataItem.h"
#include "mitkImageDescriptor.h"
#ifndef __itkHistogram_h
#include <itkHistogram.h>
#endif
class vtkImageData;
namespace mitk {
class SubImageSelector;
class ImageTimeSelector;
class ImageStatisticsHolder;
//##Documentation
//## @brief Image class for storing images
//##
//## Can be asked for header information, the data vector,
//## the mitkIpPicDescriptor struct or vtkImageData objects. If not the complete
//## data is required, the appropriate SubImageSelector class should be used
//## for access.
//## Image organizes sets of slices (s x 2D), volumes (t x 3D) and channels (n
//## x ND). Channels are for different kind of data, e.g., morphology in
//## channel 0, velocities in channel 1. All channels must have the same Geometry! In
//## particular, the dimensions of all channels are the same, only the pixel-type
//## may differ between channels.
//##
//## For importing ITK images use of mitk::ITKImageImport is recommended, see
//## \ref Adaptor.
//##
//## For ITK v3.8 and older: Converting coordinates from the ITK physical
//## coordinate system (which does not support rotated images) to the MITK world
//## coordinate system should be performed via the Geometry3D of the Image, see
//## Geometry3D::WorldToItkPhysicalPoint.
//## @ingroup Data
class MITK_CORE_EXPORT Image : public SlicedData
{
friend class SubImageSelector;
public:
mitkClassMacro(Image, SlicedData);
itkNewMacro(Self);
mitkCloneMacro(Image);
/** Smart Pointer type to a ImageDataItem. */
typedef itk::SmartPointer<ImageDataItem> ImageDataItemPointer;
typedef itk::Statistics::Histogram<double> HistogramType;
typedef mitk::ImageStatisticsHolder* StatisticsHolderPointer;
//## @param ImportMemoryManagementType This parameter is evaluated when setting new data to an image.
//## The different options are:
//## CopyMemory: Data to be set is copied and assigned to a new memory block. Data memory block will be freed on deletion of mitk::Image.
//## MamageMemory: Data to be set will be referenced, and Data memory block will be freed on deletion of mitk::Image.
//## Reference Memory: Data to be set will be referenced, but Data memory block will not be freed on deletion of mitk::Image.
//## DontManageMemory = ReferenceMemory.
enum ImportMemoryManagementType { CopyMemory, ManageMemory, ReferenceMemory, DontManageMemory = ReferenceMemory };
//##Documentation
//## @brief Vector container of SmartPointers to ImageDataItems;
//## Class is only for internal usage to allow convenient access to all slices over iterators;
//## See documentation of ImageDataItem for details.
typedef std::vector<ImageDataItemPointer> ImageDataItemPointerArray;
public:
//##Documentation
//## @brief Returns the PixelType of channel @a n.
const mitk::PixelType GetPixelType(int n = 0) const;
//##Documentation
//## @brief Get dimension of the image
//##
unsigned int GetDimension() const;
//##Documentation
//## @brief Get the size of dimension @a i (e.g., i=0 results in the number of pixels in x-direction).
//##
//## @sa GetDimensions()
unsigned int GetDimension(int i) const;
//## @brief Get the data vector of the complete image, i.e., of all channels linked together.
//##
//## If you only want to access a slice, volume at a specific time or single channel
//## use one of the SubImageSelector classes.
virtual void* GetData();
//## @brief Get the pixel value at one specific index position.
//## @brief Get the pixel value at one specific position.
//##
//## The pixel type is always being converted to double.
double GetPixelValueByIndex(const mitk::Index3D& position, unsigned int timestep = 0);
//## @brief Get the pixel value at one specific world position.
//##
//## The pixel type is always being converted to double.
double GetPixelValueByWorldCoordinate(const mitk::Point3D& position, unsigned int timestep = 0);
//##Documentation
//## @brief Get a volume at a specific time @a t of channel @a n as a vtkImageData.
virtual vtkImageData* GetVtkImageData(int t = 0, int n = 0);
//##Documentation
//## @brief Get the complete image, i.e., all channels linked together, as a @a mitkIpPicDescriptor.
//##
//## If you only want to access a slice, volume at a specific time or single channel
//## use one of the SubImageSelector classes.
//virtual mitkIpPicDescriptor* GetPic();
//##Documentation
//## @brief Check whether slice @a s at time @a t in channel @a n is set
virtual bool IsSliceSet(int s = 0, int t = 0, int n = 0) const;
//##Documentation
//## @brief Check whether volume at time @a t in channel @a n is set
virtual bool IsVolumeSet(int t = 0, int n = 0) const;
//##Documentation
//## @brief Check whether the channel @a n is set
virtual bool IsChannelSet(int n = 0) const;
//##Documentation
//## @brief Set @a data as slice @a s at time @a t in channel @a n. It is in
//## the responsibility of the caller to ensure that the data vector @a data
//## is really a slice (at least is not smaller than a slice), since there is
//## no chance to check this.
//##
//## The data is copied to an array managed by the image. If the image shall
//## reference the data, use SetImportSlice with ImportMemoryManagementType
//## set to ReferenceMemory. For importing ITK images use of mitk::
//## ITKImageImport is recommended.
//## @sa SetPicSlice, SetImportSlice, SetImportVolume
virtual bool SetSlice(const void *data, int s = 0, int t = 0, int n = 0);
//##Documentation
//## @brief Set @a data as volume at time @a t in channel @a n. It is in
//## the responsibility of the caller to ensure that the data vector @a data
//## is really a volume (at least is not smaller than a volume), since there is
//## no chance to check this.
//##
//## The data is copied to an array managed by the image. If the image shall
//## reference the data, use SetImportVolume with ImportMemoryManagementType
//## set to ReferenceMemory. For importing ITK images use of mitk::
//## ITKImageImport is recommended.
//## @sa SetPicVolume, SetImportVolume
virtual bool SetVolume(const void *data, int t = 0, int n = 0);
//##Documentation
//## @brief Set @a data in channel @a n. It is in
//## the responsibility of the caller to ensure that the data vector @a data
//## is really a channel (at least is not smaller than a channel), since there is
//## no chance to check this.
//##
//## The data is copied to an array managed by the image. If the image shall
//## reference the data, use SetImportChannel with ImportMemoryManagementType
//## set to ReferenceMemory. For importing ITK images use of mitk::
//## ITKImageImport is recommended.
//## @sa SetPicChannel, SetImportChannel
virtual bool SetChannel(const void *data, int n = 0);
//##Documentation
//## @brief Set @a data as slice @a s at time @a t in channel @a n. It is in
//## the responsibility of the caller to ensure that the data vector @a data
//## is really a slice (at least is not smaller than a slice), since there is
//## no chance to check this.
//##
//## The data is managed according to the parameter \a importMemoryManagement.
//## @sa SetPicSlice
virtual bool SetImportSlice(void *data, int s = 0, int t = 0, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory );
//##Documentation
//## @brief Set @a data as volume at time @a t in channel @a n. It is in
//## the responsibility of the caller to ensure that the data vector @a data
//## is really a volume (at least is not smaller than a volume), since there is
//## no chance to check this.
//##
//## The data is managed according to the parameter \a importMemoryManagement.
//## @sa SetPicVolume
virtual bool SetImportVolume(void *data, int t = 0, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory );
//##Documentation
//## @brief Set @a data in channel @a n. It is in
//## the responsibility of the caller to ensure that the data vector @a data
//## is really a channel (at least is not smaller than a channel), since there is
//## no chance to check this.
//##
//## The data is managed according to the parameter \a importMemoryManagement.
//## @sa SetPicChannel
virtual bool SetImportChannel(void *data, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory );
//##Documentation
//## initialize new (or re-initialize) image information
//## @warning Initialize() by pic assumes a plane, evenly spaced geometry starting at (0,0,0).
virtual void Initialize(const mitk::PixelType& type, unsigned int dimension, const unsigned int *dimensions, unsigned int channels = 1);
//##Documentation
//## initialize new (or re-initialize) image information by a Geometry3D
//##
//## @param tDim override time dimension (@a n[3]) if @a geometry is a TimeSlicedGeometry (if >0)
virtual void Initialize(const mitk::PixelType& type, const mitk::Geometry3D& geometry, unsigned int channels = 1, int tDim=-1);
//##Documentation
//## initialize new (or re-initialize) image information by a Geometry2D and number of slices
//##
//## Initializes the bounding box according to the width/height of the
//## Geometry2D and @a sDim via SlicedGeometry3D::InitializeEvenlySpaced.
//## The spacing is calculated from the Geometry2D.
//## @param tDim override time dimension (@a n[3]) if @a geometry is a TimeSlicedGeometry (if >0)
//## \sa SlicedGeometry3D::InitializeEvenlySpaced
virtual void Initialize(const mitk::PixelType& type, int sDim, const mitk::Geometry2D& geometry2d, bool flipped = false, unsigned int channels = 1, int tDim=-1);
//##Documentation
//## initialize new (or re-initialize) image information by another
//## mitk-image.
//## Only the header is used, not the data vector!
//##
virtual void Initialize(const mitk::Image* image);
virtual void Initialize(const mitk::ImageDescriptor::Pointer inDesc);
//##Documentation
//## initialize new (or re-initialize) image information by @a pic.
//## Dimensions and @a Geometry3D /@a Geometry2D are set according
//## to the tags in @a pic.
//## Only the header is used, not the data vector! Use SetPicVolume(pic)
//## to set the data vector.
//##
//## @param tDim override time dimension (@a n[3]) in @a pic (if >0)
//## @param sDim override z-space dimension (@a n[2]) in @a pic (if >0)
//## @warning Initialize() by pic assumes a plane, evenly spaced geometry starting at (0,0,0).
//virtual void Initialize(const mitkIpPicDescriptor* pic, int channels = 1, int tDim = -1, int sDim = -1);
//##Documentation
//## initialize new (or re-initialize) image information by @a vtkimagedata,
//## a vtk-image.
//## Only the header is used, not the data vector! Use
//## SetVolume(vtkimage->GetScalarPointer()) to set the data vector.
//##
//## @param tDim override time dimension in @a vtkimagedata (if >0 and <)
//## @param sDim override z-space dimension in @a vtkimagedata (if >0 and <)
virtual void Initialize(vtkImageData* vtkimagedata, int channels = 1, int tDim = -1, int sDim = -1);
//##Documentation
//## initialize new (or re-initialize) image information by @a itkimage,
//## a templated itk-image.
//## Only the header is used, not the data vector! Use
//## SetVolume(itkimage->GetBufferPointer()) to set the data vector.
//##
//## @param tDim override time dimension in @a itkimage (if >0 and <)
//## @param sDim override z-space dimension in @a itkimage (if >0 and <)
template <typename itkImageType> void InitializeByItk(const itkImageType* itkimage, int channels = 1, int tDim = -1, int sDim=-1)
{
if(itkimage==NULL) return;
MITK_DEBUG << "Initializing MITK image from ITK image.";
// build array with dimensions in each direction with at least 4 entries
m_Dimension=itkimage->GetImageDimension();
unsigned int i, *tmpDimensions=new unsigned int[m_Dimension>4?m_Dimension:4];
for(i=0;i<m_Dimension;++i)
tmpDimensions[i]=itkimage->GetLargestPossibleRegion().GetSize().GetSize()[i];
if(m_Dimension<4)
{
unsigned int *p;
for(i=0,p=tmpDimensions+m_Dimension;i<4-m_Dimension;++i, ++p)
*p=1;
}
// overwrite number of slices if sDim is set
if((m_Dimension>2) && (sDim>=0))
tmpDimensions[2]=sDim;
// overwrite number of time points if tDim is set
if((m_Dimension>3) && (tDim>=0))
tmpDimensions[3]=tDim;
// rough initialization of Image
// mitk::PixelType importType = ImportItkPixelType( itkimage::PixelType );
Initialize(MakePixelType<itkImageType>(),
m_Dimension,
tmpDimensions,
channels);
const typename itkImageType::SpacingType & itkspacing = itkimage->GetSpacing();
MITK_DEBUG << "ITK spacing " << itkspacing;
// access spacing of itk::Image
Vector3D spacing;
FillVector3D(spacing, itkspacing[0], 1.0, 1.0);
if(m_Dimension >= 2)
spacing[1]=itkspacing[1];
if(m_Dimension >= 3)
spacing[2]=itkspacing[2];
// access origin of itk::Image
Point3D origin;
const typename itkImageType::PointType & itkorigin = itkimage->GetOrigin();
MITK_DEBUG << "ITK origin " << itkorigin;
FillVector3D(origin, itkorigin[0], 0.0, 0.0);
if(m_Dimension>=2)
origin[1]=itkorigin[1];
if(m_Dimension>=3)
origin[2]=itkorigin[2];
// access direction of itk::Imagm_PixelType = new mitk::PixelType(type);e and include spacing
const typename itkImageType::DirectionType & itkdirection = itkimage->GetDirection();
MITK_DEBUG << "ITK direction " << itkdirection;
mitk::Matrix3D matrix;
matrix.SetIdentity();
unsigned int j, itkDimMax3 = (m_Dimension >= 3? 3 : m_Dimension);
// check if spacing has no zero entry and itkdirection has no zero columns
bool itkdirectionOk = true;
mitk::ScalarType columnSum;
for( j=0; j < itkDimMax3; ++j )
{
columnSum = 0.0;
for ( i=0; i < itkDimMax3; ++i)
{
columnSum += fabs(itkdirection[i][j]);
}
if(columnSum < mitk::eps)
{
itkdirectionOk = false;
}
if ( (spacing[j] < - mitk::eps) // (normally sized) negative value
&& (j==2) && (m_Dimensions[2] == 1) )
{
// Negative spacings can occur when reading single DICOM slices with ITK via GDCMIO
// In these cases spacing is not determind by ITK correctly (because it distinguishes correctly
// between slice thickness and inter slice distance -- slice distance is meaningless for
// single slices).
// I experienced that ITK produced something meaningful nonetheless because is is
// evaluating the tag "(0018,0088) Spacing between slices" as a fallback. This tag is not
// reliable (http://www.itk.org/pipermail/insight-users/2005-September/014711.html)
// but gives at least a hint.
// In real world cases I experienced that this tag contained the correct inter slice distance
// with a negative sign, so we just invert such negative spacings.
MITK_WARN << "Illegal value of itk::Image::GetSpacing()[" << j <<"]=" << spacing[j] << ". Using inverted value " << -spacing[j];
spacing[j] = -spacing[j];
}
else if (spacing[j] < mitk::eps) // value near zero
{
MITK_ERROR << "Illegal value of itk::Image::GetSpacing()[" << j <<"]=" << spacing[j] << ". Using 1.0 instead.";
spacing[j] = 1.0;
}
}
if(itkdirectionOk == false)
{
MITK_ERROR << "Illegal matrix returned by itk::Image::GetDirection():" << itkdirection << " Using identity instead.";
for ( i=0; i < itkDimMax3; ++i)
for( j=0; j < itkDimMax3; ++j )
if ( i == j )
matrix[i][j] = spacing[j];
else
matrix[i][j] = 0.0;
}
else
{
for ( i=0; i < itkDimMax3; ++i)
for( j=0; j < itkDimMax3; ++j )
matrix[i][j] = itkdirection[i][j]*spacing[j];
}
// re-initialize PlaneGeometry with origin and direction
PlaneGeometry* planeGeometry = static_cast<PlaneGeometry*>(GetSlicedGeometry(0)->GetGeometry2D(0));
planeGeometry->SetOrigin(origin);
planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix);
// re-initialize SlicedGeometry3D
SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0);
slicedGeometry->InitializeEvenlySpaced(planeGeometry, m_Dimensions[2]);
slicedGeometry->SetSpacing(spacing);
// re-initialize TimeSlicedGeometry
GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, m_Dimensions[3]);
// clean-up
delete [] tmpDimensions;
this->Initialize();
};
//##Documentation
//## @brief Check whether slice @a s at time @a t in channel @a n is valid, i.e.,
//## is (or can be) inside of the image
virtual bool IsValidSlice(int s = 0, int t = 0, int n = 0) const;
//##Documentation
//## @brief Check whether volume at time @a t in channel @a n is valid, i.e.,
//## is (or can be) inside of the image
virtual bool IsValidVolume(int t = 0, int n = 0) const;
//##Documentation
//## @brief Check whether the channel @a n is valid, i.e.,
//## is (or can be) inside of the image
virtual bool IsValidChannel(int n = 0) const;
//##Documentation
//## @brief Returns true if an image is rotated, i.e. its geometry's
//## transformation matrix has nonzero elements besides the diagonal.
//## Non-diagonal elements are checked if larger then 1/1000 of the matrix' trace.
bool IsRotated() const;
//##Documentation
//## @brief Get the sizes of all dimensions as an integer-array.
//##
//## @sa GetDimension(int i);
unsigned int* GetDimensions() const;
ImageDescriptor::Pointer GetImageDescriptor() const
{ return m_ImageDescriptor; }
ChannelDescriptor GetChannelDescriptor( int id = 0 ) const
{ return m_ImageDescriptor->GetChannelDescriptor(id); }
/** \brief Sets a geometry to an image.
*/
virtual void SetGeometry(Geometry3D* aGeometry3D);
/**
* @warning for internal use only
*/
virtual ImageDataItemPointer GetSliceData(int s = 0, int t = 0, int n = 0, void *data = NULL, ImportMemoryManagementType importMemoryManagement = CopyMemory);
/**
* @warning for internal use only
*/
virtual ImageDataItemPointer GetVolumeData(int t = 0, int n = 0, void *data = NULL, ImportMemoryManagementType importMemoryManagement = CopyMemory);
/**
* @warning for internal use only
*/
virtual ImageDataItemPointer GetChannelData(int n = 0, void *data = NULL, ImportMemoryManagementType importMemoryManagement = CopyMemory);
/**
\brief (DEPRECATED) Get the minimum for scalar images
*/
DEPRECATED (ScalarType GetScalarValueMin(int t=0) const);
/**
\brief (DEPRECATED) Get the maximum for scalar images
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetScalarValueMax(int t=0) const);
/**
\brief (DEPRECATED) Get the second smallest value for scalar images
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetScalarValue2ndMin(int t=0) const);
/**
\brief (DEPRECATED) Get the smallest value for scalar images, but do not recompute it first
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetScalarValueMinNoRecompute( unsigned int t = 0 ) const);
/**
\brief (DEPRECATED) Get the second smallest value for scalar images, but do not recompute it first
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetScalarValue2ndMinNoRecompute( unsigned int t = 0 ) const);
/**
\brief (DEPRECATED) Get the second largest value for scalar images
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetScalarValue2ndMax(int t=0) const);
/**
\brief (DEPRECATED) Get the largest value for scalar images, but do not recompute it first
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetScalarValueMaxNoRecompute( unsigned int t = 0 ) const );
/**
\brief (DEPRECATED) Get the second largest value for scalar images, but do not recompute it first
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetScalarValue2ndMaxNoRecompute( unsigned int t = 0 ) const);
/**
\brief (DEPRECATED) Get the count of voxels with the smallest scalar value in the dataset
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetCountOfMinValuedVoxels(int t = 0) const);
/**
\brief (DEPRECATED) Get the count of voxels with the largest scalar value in the dataset
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (ScalarType GetCountOfMaxValuedVoxels(int t = 0) const);
/**
\brief (DEPRECATED) Get the count of voxels with the largest scalar value in the dataset
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (unsigned int GetCountOfMaxValuedVoxelsNoRecompute( unsigned int t = 0 ) const);
/**
\brief (DEPRECATED) Get the count of voxels with the smallest scalar value in the dataset
\warning This method is deprecated and will not be available in the future. Use the \a GetStatistics instead
*/
DEPRECATED (unsigned int GetCountOfMinValuedVoxelsNoRecompute( unsigned int t = 0 ) const);
/**
\brief Returns a pointer to the ImageStatisticsHolder object that holds all statistics information for the image.
All Get-methods for statistics properties formerly accessible directly from an Image object are now moved to the
new \a ImageStatisticsHolder object.
*/
StatisticsHolderPointer GetStatistics() const
{
return m_ImageStatistics;
}
protected:
int GetSliceIndex(int s = 0, int t = 0, int n = 0) const;
int GetVolumeIndex(int t = 0, int n = 0) const;
void ComputeOffsetTable();
virtual bool IsValidTimeStep(int t) const;
virtual void Expand( unsigned int timeSteps );
virtual ImageDataItemPointer AllocateSliceData(int s = 0, int t = 0, int n = 0, void *data = NULL, ImportMemoryManagementType importMemoryManagement = CopyMemory);
virtual ImageDataItemPointer AllocateVolumeData(int t = 0, int n = 0, void *data = NULL, ImportMemoryManagementType importMemoryManagement = CopyMemory);
virtual ImageDataItemPointer AllocateChannelData(int n = 0, void *data = NULL, ImportMemoryManagementType importMemoryManagement = CopyMemory);
Image();
Image(const Image &other);
virtual ~Image();
virtual void Clear();
//## @warning Has to be called by every Initialize method!
virtual void Initialize();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
mutable ImageDataItemPointerArray m_Channels;
mutable ImageDataItemPointerArray m_Volumes;
mutable ImageDataItemPointerArray m_Slices;
unsigned int m_Dimension;
unsigned int* m_Dimensions;
ImageDescriptor::Pointer m_ImageDescriptor;
size_t *m_OffsetTable;
ImageDataItemPointer m_CompleteData;
// Image statistics Holder replaces the former implementation directly inside this class
friend class ImageStatisticsHolder;
StatisticsHolderPointer m_ImageStatistics;
};
//##Documentation
//## @brief Cast an itk::Image (with a specific type) to an mitk::Image.
//##
//## CastToMitkImage does not cast pixel types etc., just image data
//## Needs "mitkImage.h" header included.
//## If you get a compile error, try image.GetPointer();
//## @ingroup Adaptor
//## \sa mitkITKImageImport
template <typename ItkOutputImageType>
void CastToMitkImage(const itk::SmartPointer<ItkOutputImageType>& itkimage, itk::SmartPointer<mitk::Image>& mitkoutputimage)
{
if(mitkoutputimage.IsNull())
{
mitkoutputimage = mitk::Image::New();
}
mitkoutputimage->InitializeByItk(itkimage.GetPointer());
mitkoutputimage->SetChannel(itkimage->GetBufferPointer());
}
//##Documentation
//## @brief Cast an itk::Image (with a specific type) to an mitk::Image.
//##
//## CastToMitkImage does not cast pixel types etc., just image data
//## Needs "mitkImage.h" header included.
//## If you get a compile error, try image.GetPointer();
//## @ingroup Adaptor
//## \sa mitkITKImageImport
template <typename ItkOutputImageType>
void CastToMitkImage(const ItkOutputImageType* itkimage, itk::SmartPointer<mitk::Image>& mitkoutputimage)
{
if(mitkoutputimage.IsNull())
{
mitkoutputimage = mitk::Image::New();
}
mitkoutputimage->InitializeByItk(itkimage);
mitkoutputimage->SetChannel(itkimage->GetBufferPointer());
}
} // namespace mitk
#endif /* MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 */
diff --git a/Core/Code/DataManagement/mitkImageDataItem.cpp b/Core/Code/DataManagement/mitkImageDataItem.cpp
index df2d0b9b98..ff4d315625 100644
--- a/Core/Code/DataManagement/mitkImageDataItem.cpp
+++ b/Core/Code/DataManagement/mitkImageDataItem.cpp
@@ -1,259 +1,258 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageDataItem.h"
#include "mitkMemoryUtilities.h"
#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkBitArray.h>
#include <vtkCharArray.h>
#include <vtkDoubleArray.h>
#include <vtkFloatArray.h>
#include <vtkIntArray.h>
#include <vtkLongArray.h>
#include <vtkShortArray.h>
#include <vtkUnsignedCharArray.h>
#include <vtkUnsignedIntArray.h>
#include <vtkUnsignedLongArray.h>
#include <vtkUnsignedShortArray.h>
mitk::ImageDataItem::ImageDataItem(const ImageDataItem& aParent, const mitk::ImageDescriptor::Pointer desc, unsigned int dimension, void *data, bool manageMemory, size_t offset) :
m_Data(NULL), m_ManageMemory(false), m_VtkImageData(NULL), m_Offset(offset), m_IsComplete(false), m_Size(0),
m_Parent(&aParent)
{
m_PixelType = new mitk::PixelType(aParent.GetPixelType());
m_Data = static_cast<unsigned char*>(aParent.GetData())+offset;
// compute size
//const unsigned int *dims = desc->GetDimensions();
m_Dimension = dimension;
for( unsigned int i=0; i<dimension; i++)
m_Dimensions[i] = desc->GetDimensions()[i];
this->ComputeItemSize(m_Dimensions,dimension);
if(data != NULL)
{
memcpy(m_Data, data, m_Size);
if(manageMemory)
{
delete [] (unsigned char*) data;
}
}
m_ReferenceCountLock.Lock();
m_ReferenceCount = 0;
m_ReferenceCountLock.Unlock();
}
mitk::ImageDataItem::~ImageDataItem()
{
if(m_VtkImageData!=NULL)
m_VtkImageData->Delete();
if(m_Parent.IsNull())
{
if(m_ManageMemory)
delete [] m_Data;
}
delete m_PixelType;
}
mitk::ImageDataItem::ImageDataItem(const mitk::ImageDescriptor::Pointer desc, void *data, bool manageMemory)
: m_Data((unsigned char*)data), m_ManageMemory(manageMemory), m_VtkImageData(NULL), m_Offset(0), m_IsComplete(false), m_Size(0)
{
m_PixelType = new mitk::PixelType(desc->GetChannelDescriptor(0).GetPixelType());
// compute size
const unsigned int *dimensions = desc->GetDimensions();
m_Dimension = desc->GetNumberOfDimensions();
for( unsigned int i=0; i<m_Dimension; i++)
m_Dimensions[i] = dimensions[i];
this->ComputeItemSize(m_Dimensions, m_Dimension );
if(m_Data == NULL)
{
m_Data = mitk::MemoryUtilities::AllocateElements<unsigned char>( m_Size );
m_ManageMemory = true;
}
m_ReferenceCountLock.Lock();
m_ReferenceCount = 0;
m_ReferenceCountLock.Unlock();
}
mitk::ImageDataItem::ImageDataItem(const mitk::PixelType& type, unsigned int dimension, unsigned int *dimensions, void *data, bool manageMemory) :
m_Data((unsigned char*)data), m_ManageMemory(manageMemory), m_VtkImageData(NULL), m_Offset(0), m_IsComplete(false), m_Size(0),
m_Parent(NULL)
{
m_PixelType = new mitk::PixelType(type);
m_Dimension = dimension;
for( unsigned int i=0; i<m_Dimension; i++)
m_Dimensions[i] = dimensions[i];
this->ComputeItemSize(dimensions, dimension);
if(m_Data == NULL)
{
m_Data = mitk::MemoryUtilities::AllocateElements<unsigned char>( m_Size );
m_ManageMemory = true;
}
m_ReferenceCountLock.Lock();
m_ReferenceCount = 0;
m_ReferenceCountLock.Unlock();
}
mitk::ImageDataItem::ImageDataItem(const ImageDataItem &other)
: itk::LightObject(), m_PixelType(other.m_PixelType), m_ManageMemory(other.m_ManageMemory), m_Offset(other.m_Offset),
m_IsComplete(other.m_IsComplete), m_Size(other.m_Size)
{
}
void mitk::ImageDataItem::ComputeItemSize(const unsigned int *dimensions, unsigned int dimension)
{
m_Size = m_PixelType->GetSize();
for( unsigned int i=0; i<dimension; i++)
{
m_Size *= *(dimensions+i);
}
}
void mitk::ImageDataItem::ConstructVtkImageData() const
{
vtkImageData *inData = vtkImageData::New();
vtkDataArray *scalars = NULL;
const unsigned int *dims = m_Dimensions;
const unsigned int dim = m_Dimension;
unsigned long size = 0;
if ( dim == 1 )
{
inData->SetDimensions( dims[0] -1, 1, 1);
size = dims[0];
inData->SetOrigin( ((float) dims[0]) / 2.0f, 0, 0 );
}
else
if ( dim == 2 )
{
inData->SetDimensions( dims[0] , dims[1] , 1 );
size = dims[0] * dims[1];
inData->SetOrigin( ((float) dims[0]) / 2.0f, ((float) dims[1]) / 2.0f, 0 );
}
else
if ( dim >= 3 )
{
inData->SetDimensions( dims[0], dims[1], dims[2] );
size = dims[0] * dims[1] * dims[2];
// Test
//inData->SetOrigin( (float) dims[0] / 2.0f, (float) dims[1] / 2.0f, (float) dims[2] / 2.0f );
inData->SetOrigin( 0, 0, 0 );
}
else
{
inData->Delete () ;
return;
}
inData->SetNumberOfScalarComponents(m_PixelType->GetNumberOfComponents());
/* if ( ( m_PixelType.GetType() == mitkIpPicInt || m_PixelType.GetType() == mitkIpPicUInt ) && m_PixelType.GetBitsPerComponent() == 1 )
{
inData->SetScalarType( VTK_BIT );
scalars = vtkBitArray::New();
}
else*/ if ( m_PixelType->GetTypeId() == typeid(char) )
{
inData->SetScalarType( VTK_CHAR );
scalars = vtkCharArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(unsigned char))
{
inData->SetScalarType( VTK_UNSIGNED_CHAR );
scalars = vtkUnsignedCharArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(short) )
{
inData->SetScalarType( VTK_SHORT );
scalars = vtkShortArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(unsigned short) )
{
inData->SetScalarType( VTK_UNSIGNED_SHORT );
scalars = vtkUnsignedShortArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(int) )
{
inData->SetScalarType( VTK_INT );
scalars = vtkIntArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(unsigned int) )
{
inData->SetScalarType( VTK_UNSIGNED_INT );
scalars = vtkUnsignedIntArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(long int) )
{
inData->SetScalarType( VTK_LONG );
scalars = vtkLongArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(unsigned long int) )
{
inData->SetScalarType( VTK_UNSIGNED_LONG );
scalars = vtkUnsignedLongArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(float) )
{
inData->SetScalarType( VTK_FLOAT );
scalars = vtkFloatArray::New();
}
else if ( m_PixelType->GetTypeId() == typeid(double) )
{
inData->SetScalarType( VTK_DOUBLE );
scalars = vtkDoubleArray::New();
}
else
{
inData->Delete();
return;
}
m_VtkImageData = inData;
// allocate the new scalars
scalars->SetNumberOfComponents(m_VtkImageData->GetNumberOfScalarComponents());
scalars->SetVoidArray(m_Data, size * m_VtkImageData->GetNumberOfScalarComponents(), 1);
m_VtkImageData->GetPointData()->SetScalars(scalars);
scalars->Delete();
}
void mitk::ImageDataItem::Modified() const
{
if(m_VtkImageData)
m_VtkImageData->Modified();
}
diff --git a/Core/Code/DataManagement/mitkImageDataItem.h b/Core/Code/DataManagement/mitkImageDataItem.h
index 9b8aaa5ec6..8ab8f37386 100644
--- a/Core/Code/DataManagement/mitkImageDataItem.h
+++ b/Core/Code/DataManagement/mitkImageDataItem.h
@@ -1,161 +1,160 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 IMAGEDATAITEM_H
#define IMAGEDATAITEM_H
#include "mitkCommon.h"
#include <MitkExports.h>
//#include <mitkIpPic.h>
//#include "mitkPixelType.h"
#include "mitkImageDescriptor.h"
class vtkImageData;
namespace mitk {
class PixelType;
//##Documentation
//## @brief Internal class for managing references on sub-images
//##
//## ImageDataItem is a container for image data which is used internal in
//## mitk::Image to handle the communication between the different data types for images
//## used in MITK (ipPicDescriptor, mitk::Image, vtkImageData). Common for these image data
//## types is the actual image data, but they differ in representation of pixel type etc.
//## The class is also used to convert ipPic images to vtkImageData.
//##
//## The class is mainly used to extract sub-images inside of mitk::Image, like single slices etc.
//## It should not be used outside of this.
//##
//## @param manageMemory Determines if image data is removed while destruction of ImageDataItem or not.
//## @ingroup Data
class MITK_CORE_EXPORT ImageDataItem : public itk::LightObject
{
public:
mitkClassMacro(ImageDataItem, itk::LightObject);
ImageDataItem(const ImageDataItem& aParent, const mitk::ImageDescriptor::Pointer desc, unsigned int dimension, void *data = NULL, bool manageMemory = false, size_t offset = 0);
~ImageDataItem();
ImageDataItem(const mitk::ImageDescriptor::Pointer desc, void *data, bool manageMemory);
ImageDataItem(const mitk::PixelType& type, unsigned int dimension, unsigned int* dimensions, void* data, bool manageMemory);
ImageDataItem(const ImageDataItem &other);
void* GetData() const
{
return m_Data;
}
bool IsComplete() const
{
return m_IsComplete;
}
void SetComplete(bool complete)
{
m_IsComplete = complete;
}
int GetOffset() const
{
return m_Offset;
}
PixelType GetPixelType() const
{
return *m_PixelType;
}
int GetDimension() const
{
return m_Dimension;
}
int GetDimension(int i) const
{
int returnValue = 0;
// return the true size if dimension available
if (i< (int) m_Dimension)
returnValue = m_Dimensions[i];
return returnValue;
}
ImageDataItem::ConstPointer GetParent() const
{
return m_Parent;
}
//## Returns a vtkImageData; if non is present, a new one is constructed.
vtkImageData* GetVtkImageData() const
{
if(m_VtkImageData==NULL)
ConstructVtkImageData();
return m_VtkImageData;
}
// Returns if image data should be deleted on destruction of ImageDataItem.
bool GetManageMemory() const
{
return m_ManageMemory;
}
virtual void ConstructVtkImageData() const;
unsigned long GetSize() const
{
return m_Size;
}
virtual void Modified() const;
protected:
unsigned char* m_Data;
PixelType *m_PixelType;
bool m_ManageMemory;
mutable vtkImageData* m_VtkImageData;
int m_Offset;
bool m_IsComplete;
unsigned long m_Size;
private:
void ComputeItemSize( const unsigned int* dimensions, unsigned int dimension);
ImageDataItem::ConstPointer m_Parent;
template <class TPixeltype>
unsigned char *ConvertTensorsToRGB() const;
unsigned int m_Dimension;
unsigned int m_Dimensions[MAX_IMAGE_DIMENSIONS];
};
} // namespace mitk
#endif /* IMAGEDATAITEM_H */
diff --git a/Core/Code/DataManagement/mitkImageDescriptor.h b/Core/Code/DataManagement/mitkImageDescriptor.h
index 296bd1fa82..82195bff26 100644
--- a/Core/Code/DataManagement/mitkImageDescriptor.h
+++ b/Core/Code/DataManagement/mitkImageDescriptor.h
@@ -1,134 +1,133 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKIMAGEDESCRIPTOR_H
#define MITKIMAGEDESCRIPTOR_H
#include <itkObjectFactory.h>
#include <vector>
#include <string>
#include "mitkChannelDescriptor.h"
#include "mitkCommon.h"
/// Defines the maximum of 8 dimensions per image channel taken from ipPicDescriptor
#define MAX_IMAGE_DIMENSIONS 8
namespace mitk
{
/** \brief An object to hold all essential information about an Image object
The ImageDescriptor holds an std::vector of pointers to ChannelDescriptor together with the
information about the image's dimensions. The general assumption ist, that each channel of an image
has to have the same geometry.
\sa Image, ChannelDescriptor
*/
class MITK_CORE_EXPORT ImageDescriptor : public itk::Object
{
public:
mitkClassMacro(ImageDescriptor, itk::Object);
itkNewMacro(Self);
/** Insert new channel
@param chDesc Channel Descriptor
@param name channel's name
*/
void AddNewChannel( mitk::PixelType ptype, const char* name = 0);
/** \brief Initialize the image descriptor by the dimensions */
void Initialize( const unsigned int* dims, const unsigned int dim);
/** \brief Initialize the descriptor by an referenced Descriptor */
void Initialize( const ImageDescriptor::Pointer refDescriptor, unsigned int channel = 0);
/** \brief Get the C-array of unsigned int holding the size for each dimension of the image
The C-array has allways lenght of MAX_IMAGE_DIMENSIONS
*/
const unsigned int* GetDimensions() const
{ return m_Dimensions; }
/** \brief Get the number dimensions used (e.g. non-zero size)
The return value does not exceed MAX_IMAGE_DIMENSIONS
*/
unsigned int GetNumberOfDimensions() const
{ return m_NumberOfDimensions; }
/** \brief Get the name of selected channel
If the name of the channel wasn't initialized, the string returned is set to "Unnamed [ <PixelTypeName> ]"
\sa PixelType, ChannelDescriptor
*/
const std::string GetChannelName( unsigned int id ) const;
/** \brief Get the pixel type of a channel specified by its name
Returns an uninitialized PixelType object if no channel with given name was found
*/
PixelType GetChannelTypeByName( const char* name) const;
/** \brief Get the pixel type of a channel specified by its id
Returns an uninitialized PixelType object if no channel with given id was found
*/
PixelType GetChannelTypeById( unsigned int id) const;
/** \brief Get the ChannelDescriptor for a channel specified by its id */
ChannelDescriptor GetChannelDescriptor( unsigned int id = 0) const;
/** \brief Get the count of channels used */
unsigned int GetNumberOfChannels() const
{ return m_NumberOfChannels; }
protected:
/** Protected constructor */
ImageDescriptor();
/** Protected desctructor */
~ImageDescriptor(){};
private:
/** A std::vector holding a pointer to a ChannelDescriptor for each active channel of the image */
std::vector<ChannelDescriptor> m_ChannelDesc;
/** A vector holding the names of corresponding channels */
std::vector<std::string> m_ChannelNames;
/** Constant iterator for traversing the vector of channel's names */
typedef std::vector<std::string>::const_iterator ConstChannelNamesIter;
/** Constant iterator for traversing the vector of ChannelDescriptors */
typedef std::vector<ChannelDescriptor>::const_iterator ConstChannelsIter;
unsigned int m_NumberOfChannels;
unsigned int m_NumberOfDimensions;
unsigned int m_Dimensions[MAX_IMAGE_DIMENSIONS];
};
} // end namespace
#endif // MITKIMAGEDESCRIPTOR_H
diff --git a/Core/Code/DataManagement/mitkItkMatrixHack.h b/Core/Code/DataManagement/mitkItkMatrixHack.h
index 80614f6f38..c8464c0649 100644
--- a/Core/Code/DataManagement/mitkItkMatrixHack.h
+++ b/Core/Code/DataManagement/mitkItkMatrixHack.h
@@ -1,48 +1,47 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 ITKMATRIXHACK_H_HEADER_INCLUDED_C1EBD0AD
#define ITKMATRIXHACK_H_HEADER_INCLUDED_C1EBD0AD
namespace mitk {
//##Documentation
//## @brief Internal hack to set m_MatrixMTime of
//## itk::MatrixOffsetTransformBase correctly after changing
//## the matrix. For internal use only.
//##
//## Usage: static_cast object of type itk::MatrixOffsetTransformBase
//## (or derived from this) to this and call MatrixChanged().
//## itk::MatrixOffsetTransformBase::SetParameters does not set
//## m_MatrixMTime thus m_InverseMatrixMTime is the same
//## as m_MatrixMTime and the inverse is not recalculated.
//## @warning Use with care!
//## @ingroup Geometry
template <class TTransformType>
class ItkMatrixHack : public TTransformType
{
public:
void MatrixChanged()
{
this->SetVarMatrix(this->GetMatrix());
}
};
} // namespace mitk
#endif /* ITKMATRIXHACK_H_HEADER_INCLUDED_C1EBD0AD */
diff --git a/Core/Code/DataManagement/mitkLandmarkBasedCurvedGeometry.cpp b/Core/Code/DataManagement/mitkLandmarkBasedCurvedGeometry.cpp
index 61a36914e4..5f3f2977c8 100644
--- a/Core/Code/DataManagement/mitkLandmarkBasedCurvedGeometry.cpp
+++ b/Core/Code/DataManagement/mitkLandmarkBasedCurvedGeometry.cpp
@@ -1,36 +1,35 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLandmarkBasedCurvedGeometry.h"
#include <vtkAbstractTransform.h>
mitk::LandmarkBasedCurvedGeometry::LandmarkBasedCurvedGeometry()
: m_TargetLandmarks(NULL)
{
}
mitk::LandmarkBasedCurvedGeometry::LandmarkBasedCurvedGeometry(const LandmarkBasedCurvedGeometry& other)
: Superclass(other)
{
SetTargetLandmarks(other.m_TargetLandmarks);
}
mitk::LandmarkBasedCurvedGeometry::~LandmarkBasedCurvedGeometry()
{
}
diff --git a/Core/Code/DataManagement/mitkLandmarkBasedCurvedGeometry.h b/Core/Code/DataManagement/mitkLandmarkBasedCurvedGeometry.h
index 584a4a4aae..0f9c32cf39 100644
--- a/Core/Code/DataManagement/mitkLandmarkBasedCurvedGeometry.h
+++ b/Core/Code/DataManagement/mitkLandmarkBasedCurvedGeometry.h
@@ -1,61 +1,60 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKLANDMARKBASEDCURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#define MITKLANDMARKBASEDCURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#include "mitkAbstractTransformGeometry.h"
#include "mitkPointSet.h"
namespace mitk {
//##Documentation
//## @brief Superclass of AbstractTransformGeometry sub-classes defined
//## by a set of landmarks.
//##
//## @ingroup Geometry
class MITK_CORE_EXPORT LandmarkBasedCurvedGeometry : public AbstractTransformGeometry
{
public:
mitkClassMacro(LandmarkBasedCurvedGeometry, AbstractTransformGeometry);
//##Documentation
//## @brief Set the landmarks through which the geometry shall pass
itkSetConstObjectMacro(TargetLandmarks, mitk::PointSet::DataType::PointsContainer);
//##Documentation
//## @brief Get the landmarks through which the geometry shall pass
itkGetConstObjectMacro(TargetLandmarks, mitk::PointSet::DataType::PointsContainer);
virtual void ComputeGeometry() = 0;
virtual AffineGeometryFrame3D::Pointer Clone() const = 0;
protected:
LandmarkBasedCurvedGeometry();
LandmarkBasedCurvedGeometry(const LandmarkBasedCurvedGeometry& other);
virtual ~LandmarkBasedCurvedGeometry();
mitk::PointSet::DataType::PointsContainer::ConstPointer m_TargetLandmarks;
};
} // namespace mitk
#endif /* MITKLANDMARKBASEDCURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Core/Code/DataManagement/mitkLandmarkProjector.cpp b/Core/Code/DataManagement/mitkLandmarkProjector.cpp
index d246acbafd..084148b65a 100644
--- a/Core/Code/DataManagement/mitkLandmarkProjector.cpp
+++ b/Core/Code/DataManagement/mitkLandmarkProjector.cpp
@@ -1,48 +1,47 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLandmarkProjector.h"
#include <vtkAbstractTransform.h>
mitk::LandmarkProjector::LandmarkProjector()
: m_InterpolatingAbstractTransform(NULL), m_CompleteAbstractTransform(NULL), m_FrameGeometry(NULL), m_ParameterPlane(NULL)
{
m_FinalTargetLandmarks = m_WritableFinalTargetLandmarks = mitk::PointSet::DataType::PointsContainer::New();
m_ProjectedLandmarks = mitk::PointSet::DataType::PointsContainer::New();
}
mitk::LandmarkProjector::~LandmarkProjector()
{
if(m_InterpolatingAbstractTransform != NULL)
m_InterpolatingAbstractTransform->Delete();
}
void mitk::LandmarkProjector::SetInterpolatingAbstractTransform(vtkAbstractTransform* anInterpolatingAbstractTransform)
{
if(m_InterpolatingAbstractTransform != anInterpolatingAbstractTransform)
{
m_InterpolatingAbstractTransform = anInterpolatingAbstractTransform;
m_InterpolatingAbstractTransform->Register(NULL);
Modified();
ComputeCompleteAbstractTransform();
}
}
vtkAbstractTransform* mitk::LandmarkProjector::GetCompleteAbstractTransform() const
{
return m_CompleteAbstractTransform;
}
diff --git a/Core/Code/DataManagement/mitkLandmarkProjector.h b/Core/Code/DataManagement/mitkLandmarkProjector.h
index aa7bf5df38..17d8d0ea35 100644
--- a/Core/Code/DataManagement/mitkLandmarkProjector.h
+++ b/Core/Code/DataManagement/mitkLandmarkProjector.h
@@ -1,118 +1,117 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKLANDMARKPROJECTOR_H_HEADER_INCLUDED_C1C68A2C
#define MITKLANDMARKPROJECTOR_H_HEADER_INCLUDED_C1C68A2C
#include <MitkExports.h>
#include "itkObject.h"
#include "mitkPlaneGeometry.h"
#include "mitkPointSet.h"
class vtkAbstractTransform;
namespace mitk {
//##Documentation
//## @brief Base-class of landmark-projectors, which project the target landmarks
//## to create source landmarks.
//##
//## @ingroup Geometry
class MITK_CORE_EXPORT LandmarkProjector : public itk::Object
{
public:
mitkClassMacro(LandmarkProjector, itk::Object);
//##Documentation
//## @brief Set the interpolating (world-space-to-world-space) transform,
//## which uses the landmarks.
//##
//## \sa GetCompleteAbstractTransform
virtual void SetInterpolatingAbstractTransform(vtkAbstractTransform* anInterpolatingAbstractTransform);
//##Documentation
//## @brief Get the interpolating (world-space-to-world-space) transform,
//## which uses the landmarks.
//##
//## \sa GetCompleteAbstractTransform
//## \sa ComputeCompleteAbstractTransform
itkGetConstMacro(InterpolatingAbstractTransform, vtkAbstractTransform*);
//##Documentation
//## @brief Set frame geometry within which the interpolation shall occur.
//##
//## Used as a hint, may be ignored depending on the concrete sub-classes.
itkSetConstObjectMacro(FrameGeometry, mitk::Geometry3D);
//##Documentation
//## @brief Get frame geometry within which the interpolation shall occur.
//##
//## Used as a hint, may be ignored depending on the concrete sub-classes.
itkGetConstObjectMacro(FrameGeometry, mitk::Geometry3D);
//##Documentation
//## @brief Get the parameter plane for use in AbstractTransformGeometry::SetPlane.
//##
itkGetConstObjectMacro(ParameterPlane, mitk::PlaneGeometry);
//##Documentation
//## @brief Get the projected landmarks.
//##
//## @note Valid only after calling ProjectLandmarks.
itkGetConstObjectMacro(ProjectedLandmarks, mitk::PointSet::DataType::PointsContainer);
//##Documentation
//## @brief Get the final target landmarks to use for the interpolating transform.
//##
//## @note Valid only after calling ProjectLandmarks.
itkGetConstObjectMacro(FinalTargetLandmarks, mitk::PointSet::DataType::PointsContainer);
//##Documentation
//## @brief Get the transform from parameter space to world space incorporating
//## the given interpolating transform, which uses the landmarks.
//##
//## \sa ComputeCompleteAbstractTransform
//## \sa SetInterpolatingAbstractTransform
virtual vtkAbstractTransform* GetCompleteAbstractTransform() const;
virtual void ProjectLandmarks(const mitk::PointSet::DataType::PointsContainer* targetLandmarks) = 0;
protected:
LandmarkProjector();
virtual ~LandmarkProjector();
//##Documentation
//## @brief Compute the transform from parameter space to world space incorporating
//## the given interpolating transform, which uses the landmarks.
//##
//## Called after a new interpolating transform is set via
//## SetInterpolatingAbstractTransform().
//## \sa SetInterpolatingAbstractTransform
//## \sa GetCompleteAbstractTransform
virtual void ComputeCompleteAbstractTransform() = 0;
vtkAbstractTransform* m_InterpolatingAbstractTransform;
vtkAbstractTransform* m_CompleteAbstractTransform;
mitk::Geometry3D::ConstPointer m_FrameGeometry;
mutable mitk::PlaneGeometry::ConstPointer m_ParameterPlane;
mitk::PointSet::DataType::PointsContainer::Pointer m_WritableFinalTargetLandmarks;
mitk::PointSet::DataType::PointsContainer::ConstPointer m_FinalTargetLandmarks;
mitk::PointSet::DataType::PointsContainer::Pointer m_ProjectedLandmarks;
};
} // namespace mitk
#endif /* MITKLANDMARKPROJECTOR_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Core/Code/DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp b/Core/Code/DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp
index 6511906f82..5b328cf106 100644
--- a/Core/Code/DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp
+++ b/Core/Code/DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp
@@ -1,83 +1,82 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLandmarkProjectorBasedCurvedGeometry.h"
#include <vtkAbstractTransform.h>
mitk::LandmarkProjectorBasedCurvedGeometry::LandmarkProjectorBasedCurvedGeometry()
: m_LandmarkProjector(NULL), m_InterpolatingAbstractTransform(NULL)
{
}
mitk::LandmarkProjectorBasedCurvedGeometry::LandmarkProjectorBasedCurvedGeometry(const mitk::LandmarkProjectorBasedCurvedGeometry& other) : Superclass(other)
{
this->SetLandmarkProjector(other.m_LandmarkProjector);
this->ComputeGeometry();
}
mitk::LandmarkProjectorBasedCurvedGeometry::~LandmarkProjectorBasedCurvedGeometry()
{
if(m_InterpolatingAbstractTransform!=NULL)
m_InterpolatingAbstractTransform->Delete();
}
void mitk::LandmarkProjectorBasedCurvedGeometry::SetLandmarkProjector(mitk::LandmarkProjector* aLandmarkProjector)
{
itkDebugMacro("setting LandmarkProjector to " << aLandmarkProjector );
if(m_LandmarkProjector != aLandmarkProjector)
{
m_LandmarkProjector = aLandmarkProjector;
if(m_LandmarkProjector.IsNotNull())
{
if(m_FrameGeometry.IsNotNull())
m_LandmarkProjector->SetFrameGeometry(m_FrameGeometry);
if(m_InterpolatingAbstractTransform == NULL)
{
itkWarningMacro(<<"m_InterpolatingAbstractTransform not set.");
}
m_LandmarkProjector->SetInterpolatingAbstractTransform(GetInterpolatingAbstractTransform());
SetVtkAbstractTransform(m_LandmarkProjector->GetCompleteAbstractTransform());
}
Modified();
}
}
void mitk::LandmarkProjectorBasedCurvedGeometry::SetFrameGeometry(const mitk::Geometry3D* frameGeometry)
{
Superclass::SetFrameGeometry(frameGeometry);
if(m_LandmarkProjector.IsNotNull())
m_LandmarkProjector->SetFrameGeometry(frameGeometry);
}
void mitk::LandmarkProjectorBasedCurvedGeometry::ComputeGeometry()
{
if(m_LandmarkProjector.IsNull())
{
itkExceptionMacro(<< "m_LandmarkProjector is not set.");
}
m_LandmarkProjector->ProjectLandmarks(m_TargetLandmarks);
SetPlane(m_LandmarkProjector->GetParameterPlane());
}
mitk::AffineGeometryFrame3D::Pointer mitk::LandmarkProjectorBasedCurvedGeometry::Clone() const
{
mitk::AffineGeometryFrame3D::Pointer newGeometry = new LandmarkProjectorBasedCurvedGeometry(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
diff --git a/Core/Code/DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.h b/Core/Code/DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.h
index 9381f90d0b..21e85038d0 100644
--- a/Core/Code/DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.h
+++ b/Core/Code/DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.h
@@ -1,62 +1,61 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKLANDMARKPROJECTORBASEDCURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#define MITKLANDMARKPROJECTORBASEDCURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#include "mitkLandmarkBasedCurvedGeometry.h"
#include "mitkLandmarkProjector.h"
namespace mitk {
//##Documentation
//## @brief Superclass of AbstractTransformGeometry sub-classes defined
//## by a set of landmarks.
//##
//## @ingroup Geometry
class MITK_CORE_EXPORT LandmarkProjectorBasedCurvedGeometry : public LandmarkBasedCurvedGeometry
{
public:
mitkClassMacro(LandmarkProjectorBasedCurvedGeometry, LandmarkBasedCurvedGeometry);
void SetLandmarkProjector(mitk::LandmarkProjector* aLandmarkProjector);
itkGetConstObjectMacro(LandmarkProjector, mitk::LandmarkProjector);
virtual void SetFrameGeometry(const mitk::Geometry3D* frameGeometry);
virtual void ComputeGeometry();
itkGetConstMacro(InterpolatingAbstractTransform, vtkAbstractTransform*);
mitk::AffineGeometryFrame3D::Pointer Clone() const;
protected:
LandmarkProjectorBasedCurvedGeometry();
LandmarkProjectorBasedCurvedGeometry(const LandmarkProjectorBasedCurvedGeometry& other);
virtual ~LandmarkProjectorBasedCurvedGeometry();
mitk::LandmarkProjector::Pointer m_LandmarkProjector;
vtkAbstractTransform* m_InterpolatingAbstractTransform;
};
} // namespace mitk
#endif /* MITKLANDMARKPROJECTORBASEDCURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Core/Code/DataManagement/mitkLevelWindow.cpp b/Core/Code/DataManagement/mitkLevelWindow.cpp
index 49f9aefaf3..e35ab93b6a 100644
--- a/Core/Code/DataManagement/mitkLevelWindow.cpp
+++ b/Core/Code/DataManagement/mitkLevelWindow.cpp
@@ -1,415 +1,414 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLevelWindow.h"
#include "mitkImageSliceSelector.h"
#include "mitkImageStatisticsHolder.h"
#include <algorithm>
void mitk::LevelWindow::EnsureConsistency()
{
// Check if total range is ok
{
if ( m_RangeMin > m_RangeMax )
std::swap(m_RangeMin,m_RangeMax);
if (m_RangeMin == m_RangeMax )
m_RangeMin = m_RangeMax - 1;
}
// Check if current window is ok
{
if ( m_LowerWindowBound > m_UpperWindowBound )
std::swap(m_LowerWindowBound,m_UpperWindowBound);
if ( m_LowerWindowBound < m_RangeMin ) m_LowerWindowBound = m_RangeMin;
if ( m_UpperWindowBound < m_RangeMin ) m_UpperWindowBound = m_RangeMin;
if ( m_LowerWindowBound > m_RangeMax ) m_LowerWindowBound = m_RangeMax;
if ( m_UpperWindowBound > m_RangeMax ) m_UpperWindowBound = m_RangeMax;
if (m_LowerWindowBound == m_UpperWindowBound )
{
if(m_LowerWindowBound == m_RangeMin )
m_UpperWindowBound++;
else
m_LowerWindowBound--;
}
}
}
mitk::LevelWindow::LevelWindow(mitk::ScalarType level, mitk::ScalarType window)
: m_LowerWindowBound( level - window / 2.0 ), m_UpperWindowBound( level + window / 2.0 ),
m_RangeMin( -2048.0 ), m_RangeMax( 4096.0 ),
m_DefaultLowerBound( -2048.0 ), m_DefaultUpperBound( 4096.0 ),
m_Fixed( false )
{
SetDefaultLevelWindow(level, window);
}
mitk::LevelWindow::LevelWindow(const mitk::LevelWindow& levWin)
: m_LowerWindowBound( levWin.GetLowerWindowBound() )
, m_UpperWindowBound( levWin.GetUpperWindowBound() )
, m_RangeMin( levWin.GetRangeMin() )
, m_RangeMax( levWin.GetRangeMax() )
, m_DefaultLowerBound( levWin.GetDefaultLowerBound() )
, m_DefaultUpperBound( levWin.GetDefaultUpperBound() )
, m_Fixed( levWin.GetFixed() )
{
}
mitk::LevelWindow::~LevelWindow()
{
}
mitk::ScalarType mitk::LevelWindow::GetLevel() const
{
return (m_UpperWindowBound-m_LowerWindowBound) / 2.0 + m_LowerWindowBound;
}
mitk::ScalarType mitk::LevelWindow::GetWindow() const
{
return (m_UpperWindowBound-m_LowerWindowBound);
}
mitk::ScalarType mitk::LevelWindow::GetDefaultLevel() const
{
return ((m_DefaultUpperBound+m_DefaultLowerBound)/2.0);
}
mitk::ScalarType mitk::LevelWindow::GetDefaultWindow() const
{
return ((m_DefaultUpperBound-m_DefaultLowerBound));
}
void mitk::LevelWindow::ResetDefaultLevelWindow()
{
SetLevelWindow(GetDefaultLevel(), GetDefaultWindow());
}
mitk::ScalarType mitk::LevelWindow::GetLowerWindowBound() const
{
return m_LowerWindowBound;
}
mitk::ScalarType mitk::LevelWindow::GetUpperWindowBound() const
{
return m_UpperWindowBound;
}
void mitk::LevelWindow::SetDefaultLevelWindow(mitk::ScalarType level, mitk::ScalarType window)
{
SetDefaultBoundaries((level-(window/2)), (level+(window/2)));
}
void mitk::LevelWindow::SetLevelWindow(mitk::ScalarType level, mitk::ScalarType window)
{
SetWindowBounds((level-(window/2.0)), (level+(window/2.0)));
}
void mitk::LevelWindow::SetWindowBounds(mitk::ScalarType lowerBound, mitk::ScalarType upperBound)
{
if ( IsFixed() ) return;
m_LowerWindowBound = lowerBound;
m_UpperWindowBound = upperBound;
EnsureConsistency();
}
void mitk::LevelWindow::SetRangeMinMax(mitk::ScalarType min, mitk::ScalarType max)
{
if ( IsFixed() ) return;
m_RangeMin = min;
m_RangeMax = max;
EnsureConsistency();
}
void mitk::LevelWindow::SetDefaultBoundaries(mitk::ScalarType low, mitk::ScalarType up)
{
if ( IsFixed() ) return;
m_DefaultLowerBound = low;
m_DefaultUpperBound = up;
// Check if default window is ok
{
if ( m_DefaultLowerBound > m_DefaultUpperBound )
std::swap(m_DefaultLowerBound,m_DefaultUpperBound);
if (m_DefaultLowerBound == m_DefaultUpperBound )
m_DefaultLowerBound--;
}
EnsureConsistency();
}
void mitk::LevelWindow::SetToMaxWindowSize()
{
SetWindowBounds( m_RangeMin , m_RangeMax );
}
mitk::ScalarType mitk::LevelWindow::GetRangeMin() const
{
return m_RangeMin;
}
mitk::ScalarType mitk::LevelWindow::GetRangeMax() const
{
return m_RangeMax;
}
mitk::ScalarType mitk::LevelWindow::GetRange() const
{
return m_RangeMax - m_RangeMin;
}
mitk::ScalarType mitk::LevelWindow::GetDefaultUpperBound() const
{
return m_DefaultUpperBound;
}
mitk::ScalarType mitk::LevelWindow::GetDefaultLowerBound() const
{
return m_DefaultLowerBound;
}
void mitk::LevelWindow::ResetDefaultRangeMinMax()
{
SetRangeMinMax(m_DefaultLowerBound, m_DefaultUpperBound);
}
/*!
This method initializes a mitk::LevelWindow from an mitk::Image. The algorithm is as follows:
Default to taking the central image slice for quick analysis.
Compute the smallest (minValue), second smallest (min2ndValue), second largest (max2ndValue), and
largest (maxValue) data value by traversing the pixel values only once. In the
same scan it also computes the count of minValue values and maxValue values.
After that a basic histogram with specific information about the
extrems is complete.
If minValue == maxValue, the center slice is uniform and the above scan is repeated for
the complete image, not just one slice
Next, special cases of images with only 1, 2 or 3 distinct data values
have hand assigned level window ranges.
Next the level window is set relative to the inner range IR = lengthOf([min2ndValue, max2ndValue])
For count(minValue) > 20% the smallest values are frequent and should be
distinct from the min2ndValue and larger values (minValue may be std:min, may signify
something special) hence the lower end of the level window is set to min2ndValue - 0.5 * IR
For count(minValue) <= 20% the smallest values are not so important and can
blend with the next ones => min(level window) = min2ndValue
And analog for max(level window):
count(max2ndValue) > 20%: max(level window) = max2ndValue + 0.5 * IR
count(max2ndValue) < 20%: max(level window) = max2ndValue
In both 20%+ cases the level window bounds are clamped to the [minValue, maxValue] range
In consequence the level window maximizes contrast with minimal amount of
computation and does do useful things if the data contains std::min or
std:max values or has only 1 or 2 or 3 data values.
*/
void mitk::LevelWindow::SetAuto(const mitk::Image* image, bool /*tryPicTags*/, bool guessByCentralSlice)
{
if ( IsFixed() )
return;
if ( image == NULL || !image->IsInitialized() ) return;
const mitk::Image* wholeImage = image;
ScalarType minValue = 0.0;
ScalarType maxValue = 0.0;
ScalarType min2ndValue = 0.0;
ScalarType max2ndValue = 0.0;
mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New();
if ( guessByCentralSlice )
{
sliceSelector->SetInput(image);
sliceSelector->SetSliceNr(image->GetDimension(2)/2);
sliceSelector->SetTimeNr(image->GetDimension(3)/2);
sliceSelector->SetChannelNr(image->GetDimension(4)/2);
sliceSelector->Update();
image = sliceSelector->GetOutput();
if ( image == NULL || !image->IsInitialized() ) return;
minValue = image->GetStatistics()->GetScalarValueMin();
maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute();
min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute();
max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute();
if ( minValue == maxValue )
{
// guessByCentralSlice seems to have failed, lets look at all data
image = wholeImage;
minValue = image->GetStatistics()->GetScalarValueMin();
maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute();
min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute();
max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute();
}
}
else
{
const_cast<Image*>(image)->Update();
minValue = image->GetStatistics()->GetScalarValueMin(0);
maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute(0);
min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute(0);
max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute(0);
for (unsigned int i = 1; i < image->GetDimension(3); ++i)
{
ScalarType minValueTemp = image->GetStatistics()->GetScalarValueMin(i);
if (minValue > minValueTemp)
minValue = minValueTemp;
ScalarType maxValueTemp = image->GetStatistics()->GetScalarValueMaxNoRecompute(i);
if (maxValue < maxValueTemp)
maxValue = maxValueTemp;
ScalarType min2ndValueTemp = image->GetStatistics()->GetScalarValue2ndMinNoRecompute(i);
if (min2ndValue > min2ndValueTemp)
min2ndValue = min2ndValueTemp;
ScalarType max2ndValueTemp = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute(i);
if (max2ndValue > max2ndValueTemp)
max2ndValue = max2ndValueTemp;
}
}
// Fix for bug# 344 Level Window wird bei Eris Cut bildern nicht richtig gesetzt
if (image->GetPixelType()== typeid(int) && image->GetPixelType().GetBpe() >= 8)
{
// the windows compiler complains about ambiguos 'pow' call, therefore static casting to (double, int)
if (minValue == -( pow( (double) 2.0, static_cast<int>(image->GetPixelType().GetBpe()/2) ) ) )
{
minValue = min2ndValue;
}
}
// End fix
//// uniform image
if ( minValue == maxValue )
{
minValue = maxValue-1;
}
SetRangeMinMax(minValue, maxValue);
SetDefaultBoundaries(minValue, maxValue);
/*
if ( tryPicTags ) // level and window will be set by informations provided directly by the mitkIpPicDescriptor
{
if ( SetAutoByPicTags(const_cast<Image*>(image)->GetPic()) )
{
return;
}
}
*/
unsigned int numPixelsInDataset = image->GetDimensions()[0];
for ( unsigned int k=0; k<image->GetDimension(); ++k ) numPixelsInDataset *= image->GetDimensions()[k];
unsigned int minCount = image->GetStatistics()->GetCountOfMinValuedVoxelsNoRecompute();
unsigned int maxCount = image->GetStatistics()->GetCountOfMaxValuedVoxelsNoRecompute();
float minCountFraction = minCount/float(numPixelsInDataset);
float maxCountFraction = maxCount/float(numPixelsInDataset);
//// binary image
if ( min2ndValue == maxValue )
{
// noop; full range is fine
}
//// triple value image, put middle value in center of gray level ramp
else if ( min2ndValue == max2ndValue )
{
ScalarType minDelta = std::min(min2ndValue-minValue, maxValue-min2ndValue);
minValue = min2ndValue - minDelta;
maxValue = min2ndValue + minDelta;
}
// now we can assume more than three distict scalar values
else
{
ScalarType innerRange = max2ndValue - min2ndValue;
if ( minCountFraction > 0.2 ) //// lots of min values -> make different from rest, but not miles away
{
ScalarType halfInnerRangeGapMinValue = min2ndValue - innerRange/2.0;
minValue = std::max(minValue, halfInnerRangeGapMinValue);
}
else //// few min values -> focus on innerRange
{
minValue = min2ndValue;
}
if ( maxCountFraction > 0.2 ) //// lots of max values -> make different from rest
{
ScalarType halfInnerRangeGapMaxValue = max2ndValue + innerRange/2.0;
maxValue = std::min(maxValue, halfInnerRangeGapMaxValue);
}
else //// few max values -> focus on innerRange
{
maxValue = max2ndValue;
}
}
SetWindowBounds(minValue, maxValue);
SetDefaultLevelWindow((maxValue - minValue) / 2 + minValue, maxValue - minValue);
}
void mitk::LevelWindow::SetFixed( bool fixed )
{
m_Fixed = fixed;
}
bool mitk::LevelWindow::GetFixed() const
{
return m_Fixed;
}
bool mitk::LevelWindow::IsFixed() const
{
return m_Fixed;
}
bool mitk::LevelWindow::operator==(const mitk::LevelWindow& levWin) const
{
if ( m_RangeMin == levWin.GetRangeMin() &&
m_RangeMax == levWin.GetRangeMax() &&
m_LowerWindowBound == levWin.GetLowerWindowBound() && m_UpperWindowBound == levWin.GetUpperWindowBound() &&
m_DefaultLowerBound == levWin.GetDefaultLowerBound() && m_DefaultUpperBound == levWin.GetDefaultUpperBound() && m_Fixed == levWin.IsFixed() ) {
return true;
}
else {
return false;
}
}
bool mitk::LevelWindow::operator!=(const mitk::LevelWindow& levWin) const
{
return ! ( (*this) == levWin);
}
mitk::LevelWindow& mitk::LevelWindow::operator=(const mitk::LevelWindow& levWin)
{
if (this == &levWin) {
return *this;
}
else {
m_RangeMin = levWin.GetRangeMin();
m_RangeMax = levWin.GetRangeMax();
m_LowerWindowBound= levWin.GetLowerWindowBound();
m_UpperWindowBound= levWin.GetUpperWindowBound();
m_DefaultLowerBound = levWin.GetDefaultLowerBound();
m_DefaultUpperBound = levWin.GetDefaultUpperBound();
m_Fixed = levWin.GetFixed();
return *this;
}
}
diff --git a/Core/Code/DataManagement/mitkLevelWindow.h b/Core/Code/DataManagement/mitkLevelWindow.h
index 9db13797be..0c087f73e8 100644
--- a/Core/Code/DataManagement/mitkLevelWindow.h
+++ b/Core/Code/DataManagement/mitkLevelWindow.h
@@ -1,240 +1,239 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 LEVELWINDOW_H_HEADER_INCLUDED_C1F4F02C
#define LEVELWINDOW_H_HEADER_INCLUDED_C1F4F02C
#include "mitkVector.h"
#include <MitkExports.h>
//struct mitkIpPicDescriptor;
namespace mitk {
class Image;
//##Documentation
//## @brief Class to store level/window values
//##
//## Current min and max value are stored in m_LowerWindowBound and m_UpperWindowBound.
//## The maximum and minimum of valid value range is stored in
//## m_RangeMin and m_RangeMax.
//## m_DefaultLevel amd m_DefaultWindow store the initial Level/Window values for the image.
//## m_DefaultRangeMin and m_DefaultRangeMax store the initial minrange and maxrange for the image.
//##
//## See documentation of SetAuto for information on how the
//## level window is initialized from an image.
//##
//## @ingroup DataManagement
class MITK_CORE_EXPORT LevelWindow
{
public:
LevelWindow(ScalarType level=127.5, ScalarType window=255.0);
LevelWindow(const mitk::LevelWindow& levWin);
virtual ~LevelWindow();
/*!
* \brief method that returns the level value, i.e. the center of
* the current grey value interval
*/
ScalarType GetLevel() const;
/*!
* \brief returns the current window size, i.e the range size of the current grey value interval
*/
ScalarType GetWindow() const;
/*!
* \brief method returns the default level value for the image
*/
ScalarType GetDefaultLevel() const;
/*!
* \brief returns the default window size for the image
*/
ScalarType GetDefaultWindow() const;
/*!
* \brief Resets the level and the window value to the default values
*/
void ResetDefaultLevelWindow();
/*!
* Returns the minimum Value of the window
*/
ScalarType GetLowerWindowBound() const;
/*!
* Returns the upper window bound value of the window
*/
ScalarType GetUpperWindowBound() const;
/*!
* To set the level and the window value
*/
void SetLevelWindow(ScalarType level, ScalarType window);
/*!
* Set the lower and upper bound of the window
*/
void SetWindowBounds(ScalarType lowerBound, ScalarType upperBound);
/*!
* sets the window to its maximum Size in scaleRange
*/
void SetToMaxWindowSize();
/*!
* Set the range minimum and maximum value
*/
void SetRangeMinMax(ScalarType min, ScalarType max);
/*!
* Get the range minimum value
*/
ScalarType GetRangeMin() const;
/*!
* Get the range maximum value
*/
ScalarType GetRangeMax() const;
/*!
* Get the default range minimum value
*/
ScalarType GetDefaultLowerBound() const;
/*!
* Get the default range maximum value
*/
ScalarType GetDefaultUpperBound() const;
/*!
* \brief the default min and max range for image will be reset
*/
void ResetDefaultRangeMinMax();
/**!
* \brief returns the size of the grey value range
*/
ScalarType GetRange() const;
/*!
* set the default level and window value
*/
void SetDefaultLevelWindow(ScalarType level, ScalarType window);
/*!
* set the default Bounderies
*/
void SetDefaultBoundaries(ScalarType low, ScalarType up);
/**!
* \brief sets level/window to the min/max greyvalues of the given Image
*/
void SetAuto(const mitk::Image* image, bool tryPicTags = true, bool guessByCentralSlice = true);
/**
* If a level window is set to fixed, the set and get methods won't accept
* modifications to the level window settings anymore. This behaviour can
* be turned of by setting fixed to false;
*/
void SetFixed( bool fixed );
/**
* Returns whether the level window settings are fixed (@see SetFixed(bool)) or not
*/
bool GetFixed() const;
/**
* Returns whether the level window settings are fixed (@see SetFixed(bool)) or not
*/
bool IsFixed() const;
/*!
* \brief equality operator implementation that allows to compare two level windows
*/
virtual bool operator==(const LevelWindow& levWin) const;
/*!
* \brief non equality operator implementation that allows to compare two level windows
*/
virtual bool operator!=(const LevelWindow& levWin) const;
/*!
* \brief implementation necessary because operator made
* private in itk::Object
*/
virtual LevelWindow& operator=(const LevelWindow& levWin);
protected:
/*!
* lower bound of current window
*/
ScalarType m_LowerWindowBound;
/*!
* upper bound of current window
*/
ScalarType m_UpperWindowBound;
/*!
* minimum gray value of the window
*/
ScalarType m_RangeMin;
/*!
* maximum gray value of the window
*/
ScalarType m_RangeMax;
/*!
* default minimum gray value of the window
*/
ScalarType m_DefaultLowerBound;
/*!
* default maximum gray value of the window
*/
ScalarType m_DefaultUpperBound;
/*!
* Defines whether the level window settings may be changed after
* initialization or not.
*/
bool m_Fixed;
/*!
* confidence tests
*
* if m_LowerWindowBound > m_UpperWindowBound, then the values for m_LowerWindowBound and m_UpperWindowBound will be exchanged
*
* if m_LowerWindowBound < m_RangeMin, m_LowerWindowBound will be set to m_RangeMin. m_UpperWindowBound will be decreased the same as m_LowerWindowBound will be increased, but minimum value for m_UpperWindowBound is also m_RangeMin.
*
* if m_UpperWindowBound > m_RangeMax, m_UpperWindowBound will be set to m_RangeMax. m_LowerWindowBound will be increased the same as m_UpperWindowBound will be decreased, but maximum value for m_LowerWindowBound is also m_RangeMax.
*
*/
inline void EnsureConsistency();
};
} // namespace mitk
#endif /* LEVELWINDOW_H_HEADER_INCLUDED_C1F4F02C */
diff --git a/Core/Code/DataManagement/mitkLevelWindowManager.cpp b/Core/Code/DataManagement/mitkLevelWindowManager.cpp
index 9ad68bd693..b2c7ace5e9 100644
--- a/Core/Code/DataManagement/mitkLevelWindowManager.cpp
+++ b/Core/Code/DataManagement/mitkLevelWindowManager.cpp
@@ -1,389 +1,388 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLevelWindowManager.h"
#include <itkCommand.h>
#include "mitkDataStorage.h"
#include "mitkNodePredicateBase.h"
#include "mitkNodePredicateProperty.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateAnd.h"
#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateNot.h"
#include "mitkProperties.h"
#include "mitkMessage.h"
mitk::LevelWindowManager::LevelWindowManager()
: m_DataStorage(NULL)
, m_LevelWindowProperty(NULL)
, m_AutoTopMost(true)
, m_IsObserverTagSet(false)
, m_CurrentImage(NULL)
, m_IsPropertyModifiedTagSet(false)
{
}
mitk::LevelWindowManager::~LevelWindowManager()
{
if (m_DataStorage.IsNotNull())
{
m_DataStorage->AddNodeEvent.RemoveListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageChanged ));
m_DataStorage->RemoveNodeEvent.RemoveListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageRemovedNode ));
m_DataStorage = NULL;
}
if (m_IsPropertyModifiedTagSet && m_LevelWindowProperty.IsNotNull())
{
m_LevelWindowProperty->RemoveObserver(m_PropertyModifiedTag);
m_IsPropertyModifiedTagSet = false;
}
for( std::map<unsigned long, mitk::BaseProperty::Pointer>::iterator iter = m_PropObserverToNode.begin();
iter != m_PropObserverToNode.end();
++iter )
{
(*iter).second->RemoveObserver((*iter).first);
}
for( std::map<unsigned long, mitk::BaseProperty::Pointer>::iterator iter = m_PropObserverToNode2.begin();
iter != m_PropObserverToNode2.end();
++iter )
{
(*iter).second->RemoveObserver((*iter).first);
}
}
void mitk::LevelWindowManager::SetDataStorage( mitk::DataStorage* ds )
{
if (ds == NULL) return;
/* remove listeners of old DataStorage */
if (m_DataStorage.IsNotNull())
{
m_DataStorage->AddNodeEvent.RemoveListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageChanged ));
m_DataStorage->RemoveNodeEvent.RemoveListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageRemovedNode ));
}
/* register listener for new DataStorage */
m_DataStorage = ds; // register
m_DataStorage->AddNodeEvent.AddListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageChanged ));
m_DataStorage->RemoveNodeEvent.AddListener(
MessageDelegate1<LevelWindowManager, const mitk::DataNode*>( this, &LevelWindowManager::DataStorageRemovedNode ));
this->DataStorageChanged(); // update us with new DataStorage
}
void mitk::LevelWindowManager::OnPropertyModified(const itk::EventObject& )
{
Modified();
}
void mitk::LevelWindowManager::SetAutoTopMostImage(bool autoTopMost, const mitk::DataNode* removedNode)
{
m_AutoTopMost = autoTopMost;
if (m_AutoTopMost == false)
return;
if (m_IsPropertyModifiedTagSet && m_LevelWindowProperty.IsNotNull())
{
m_LevelWindowProperty->RemoveObserver(m_PropertyModifiedTag);
m_IsPropertyModifiedTagSet = false;
}
/* search topmost image */
if (m_DataStorage.IsNull())
{
itkExceptionMacro("DataStorage not set");
}
int maxLayer = itk::NumericTraits<int>::min();
m_LevelWindowProperty = NULL;
mitk::DataNode::Pointer topLevelNode;
mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetRelevantNodes();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
{
mitk::DataNode::Pointer node = it->Value();
if (node.IsNull() || (removedNode != NULL && node == removedNode))
continue;
node->SetBoolProperty( "imageForLevelWindow", false );
if (node->IsVisible(NULL) == false)
continue;
int layer = 0;
node->GetIntProperty("layer", layer);
if ( layer < maxLayer )
continue;
mitk::LevelWindowProperty::Pointer levelWindowProperty = dynamic_cast<mitk::LevelWindowProperty*>(node->GetProperty("levelwindow"));
if (levelWindowProperty.IsNull())
continue;
m_LevelWindowProperty = levelWindowProperty;
m_CurrentImage = dynamic_cast<mitk::Image*>(node->GetData());
topLevelNode = node;
maxLayer = layer;
}
if (topLevelNode.IsNotNull())
{
topLevelNode->SetBoolProperty( "imageForLevelWindow", true );
}
this->SetLevelWindowProperty( m_LevelWindowProperty );
if ( m_LevelWindowProperty.IsNull() )
{
Modified();
}
// else SetLevelWindowProperty will call Modified();
}
// sets an specific LevelWindowProperty, all changes will affect the image belonging to this property.
void mitk::LevelWindowManager::SetLevelWindowProperty(LevelWindowProperty::Pointer levelWindowProperty)
{
if (levelWindowProperty.IsNull())
return;
if (m_IsPropertyModifiedTagSet) // remove listener for old property
{
m_LevelWindowProperty->RemoveObserver(m_PropertyModifiedTag);
m_IsPropertyModifiedTagSet = false;
}
m_LevelWindowProperty = levelWindowProperty;
itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command = itk::ReceptorMemberCommand<LevelWindowManager>::New(); // register listener for new property
command->SetCallbackFunction(this, &LevelWindowManager::OnPropertyModified);
m_PropertyModifiedTag = m_LevelWindowProperty->AddObserver( itk::ModifiedEvent(), command );
m_IsPropertyModifiedTagSet = true;
/* search image than belongs to the property */
mitk::NodePredicateProperty::Pointer p = mitk::NodePredicateProperty::New("levelwindow", m_LevelWindowProperty);
mitk::DataNode* n = m_DataStorage->GetNode(p);
if (n == NULL)
{
itkExceptionMacro("No Image in DataStorage that belongs to LevelWindow property " << m_LevelWindowProperty);
}
m_CurrentImage = dynamic_cast<mitk::Image*>(n->GetData());
n->SetBoolProperty( "imageForLevelWindow", true );
this->Modified();
}
// returns the current mitkLevelWindowProperty object from the image that is affected by changes
mitk::LevelWindowProperty::Pointer mitk::LevelWindowManager::GetLevelWindowProperty()
{
return m_LevelWindowProperty;
}
// returns Level/Window values for the current image
const mitk::LevelWindow& mitk::LevelWindowManager::GetLevelWindow()
{
if (m_LevelWindowProperty.IsNotNull())
{
return m_LevelWindowProperty->GetLevelWindow();
}
else
{
itkExceptionMacro("No LevelWindow available!");
}
}
// sets new Level/Window values and informs all listeners about changes
void mitk::LevelWindowManager::SetLevelWindow(const mitk::LevelWindow& levelWindow)
{
if (m_LevelWindowProperty.IsNotNull())
{
m_LevelWindowProperty->SetLevelWindow(levelWindow);
}
this->Modified();
}
void mitk::LevelWindowManager::DataStorageChanged( const mitk::DataNode* )
{
this->DataStorageRemovedNode();
}
void mitk::LevelWindowManager::DataStorageRemovedNode( const mitk::DataNode* removedNode )
{
/* remove old observers */
for (ObserverToPropertyMap::iterator iter = m_PropObserverToNode.begin();
iter != m_PropObserverToNode.end();
++iter)
{
(*iter).second->RemoveObserver((*iter).first);
}
m_PropObserverToNode.clear();
for (ObserverToPropertyMap::iterator iter = m_PropObserverToNode2.begin();
iter != m_PropObserverToNode2.end();
++iter)
{
(*iter).second->RemoveObserver((*iter).first);
}
m_PropObserverToNode2.clear();
if (m_DataStorage.IsNull())
{
itkExceptionMacro("DataStorage not set");
}
/* listen to changes in visible property of all images */
mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetRelevantNodes();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin();
it != all->End();
++it)
{
if (it->Value().IsNull())
continue;
/* register listener for changes in visible property */
itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command = itk::ReceptorMemberCommand<LevelWindowManager>::New();
command->SetCallbackFunction(this, &LevelWindowManager::Update);
m_PropObserverToNode[it->Value()->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command )] = it->Value()->GetProperty("visible");
}
/* listen to changes in layer property of all images */
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin();
it != all->End();
++it)
{
if (it->Value().IsNull())
continue;
/* register listener for changes in layer property */
itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command2 = itk::ReceptorMemberCommand<LevelWindowManager>::New();
command2->SetCallbackFunction(this, &LevelWindowManager::Update);
m_PropObserverToNode2[it->Value()->GetProperty("layer")->AddObserver( itk::ModifiedEvent(), command2 )] = it->Value()->GetProperty("layer");
}
/* search image than belongs to the property */
if (m_LevelWindowProperty.IsNull())
{
SetAutoTopMostImage(true, removedNode);
}
else
{
mitk::NodePredicateProperty::Pointer p2 = mitk::NodePredicateProperty::New("levelwindow", m_LevelWindowProperty);
mitk::DataNode* n = m_DataStorage->GetNode(p2);
if (n == NULL || m_AutoTopMost) // if node was deleted, change our behaviour to AutoTopMost, if AutoTopMost is true change level window to topmost node
SetAutoTopMostImage(true, removedNode);
}
}
mitk::DataStorage* mitk::LevelWindowManager::GetDataStorage()
{
return m_DataStorage.GetPointer();
}
// true if changes on slider or line-edits will affect always the topmost layer image
bool mitk::LevelWindowManager::isAutoTopMost()
{
return m_AutoTopMost;
}
void mitk::LevelWindowManager::Update(const itk::EventObject&) // visible property of a image has changed
{
if (m_AutoTopMost)
{
SetAutoTopMostImage(true);
return;
}
mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetRelevantNodes();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin();
it != all->End();
++it)
{
mitk::DataNode::Pointer node = it->Value();
if (node.IsNull())
continue;
node->SetBoolProperty( "imageForLevelWindow", false );
if (node->IsVisible(NULL) == false)
continue;
mitk::LevelWindowProperty::Pointer levelWindowProperty = dynamic_cast<mitk::LevelWindowProperty*>(node->GetProperty("levelwindow"));
if (levelWindowProperty.IsNull())
continue;
m_LevelWindowProperty = levelWindowProperty;
m_CurrentImage = dynamic_cast<mitk::Image*>(node->GetData());
node->SetBoolProperty( "imageForLevelWindow", true );
if (m_LevelWindowProperty.IsNull() && m_LevelWindowProperty.GetPointer() == levelWindowProperty) // we found our m_LevelWindowProperty
{
return;
}
}
Modified();
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::LevelWindowManager::GetRelevantNodes()
{
if (m_DataStorage.IsNull())
return mitk::DataStorage::SetOfObjects::ConstPointer(mitk::DataStorage::SetOfObjects::New()); // return empty set
mitk::BoolProperty::Pointer trueProp = mitk::BoolProperty::New(true);
mitk::NodePredicateProperty::Pointer notBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(false));
mitk::NodePredicateProperty::Pointer hasLevelWindow = mitk::NodePredicateProperty::New("levelwindow", NULL);
mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image");
mitk::NodePredicateDataType::Pointer isDImage = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isTImage = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isQImage = mitk::NodePredicateDataType::New("QBallImage");
mitk::NodePredicateOr::Pointer predicateTypes = mitk::NodePredicateOr::New();
predicateTypes->AddPredicate(isImage);
predicateTypes->AddPredicate(isDImage);
predicateTypes->AddPredicate(isTImage);
predicateTypes->AddPredicate(isQImage);
mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New();
predicate->AddPredicate(notBinary);
predicate->AddPredicate(hasLevelWindow);
predicate->AddPredicate(predicateTypes);
mitk::DataStorage::SetOfObjects::ConstPointer relevantNodes = m_DataStorage->GetSubset( predicate );
return relevantNodes;
}
mitk::Image* mitk::LevelWindowManager::GetCurrentImage()
{
return m_CurrentImage;
}
diff --git a/Core/Code/DataManagement/mitkLevelWindowManager.h b/Core/Code/DataManagement/mitkLevelWindowManager.h
index 316b6b56dc..543814986e 100644
--- a/Core/Code/DataManagement/mitkLevelWindowManager.h
+++ b/Core/Code/DataManagement/mitkLevelWindowManager.h
@@ -1,117 +1,116 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 mitkLevelWindowManager_h
#define mitkLevelWindowManager_h
#include "mitkDataStorage.h"
#include "mitkLevelWindowProperty.h"
#include "mitkBaseProperty.h"
#include <map>
namespace mitk
{
/**
\brief Provides access to the LevelWindowProperty object and LevelWindow of the "current" image.
- provides a LevelWindowProperty for purposes like GUI editors
- this property comes from one of two possible sources
- either something (e.g. the application) sets the property because of some user selection
- OR the "Auto top-most" logic is used to search a DataStorage for the image with the highest "layer" property value
Changes on Level/Window can be set with SetLevelWindow() and will affect either the topmost layer image,
if isAutoTopMost() returns true, or an image which is set by SetLevelWindowProperty(LevelWindowProperty::Pointer levelWindowProperty).
Changes to Level/Window, when another image gets active or by SetLevelWindow(const LevelWindow& levelWindow),
will be sent to all listeners by Modified().
DataStorageChanged() listens to the DataStorage for new or removed images. Depending on how m_AutoTopMost is set,
the new image becomes active or not. If an image is removed from the DataStorage and m_AutoTopMost is false,
there is a check to proof, if the active image is still available. If not, then m_AutoTopMost becomes true.
*/
class MITK_CORE_EXPORT LevelWindowManager : public itk::Object
{
public:
mitkClassMacro(LevelWindowManager, itk::Object)
itkNewMacro(Self);
void SetDataStorage(DataStorage* ds);
DataStorage* GetDataStorage(); ///< returns the datastorage
/// if autoTopMost == true: sets the topmost layer image to be affected by changes
/// if removedNode != NULL a node was removed from DataStorage
void SetAutoTopMostImage(bool autoTopMost, const DataNode* removedNode = NULL);
void Update(const itk::EventObject& e); ///< gets called if a visible property changes
/**
* Sets an specific LevelWindowProperty, all changes will affect the image belonging to this property.
*/
void SetLevelWindowProperty(LevelWindowProperty::Pointer levelWindowProperty);
/// sets new Level/Window values and informs all listeners about changes
void SetLevelWindow(const LevelWindow& levelWindow);
/// returns Level/Window values for the current image
const LevelWindow& GetLevelWindow();
/// returns the current mitkLevelWindowProperty object from the image that is affected by changes
LevelWindowProperty::Pointer GetLevelWindowProperty();
/// true if changes on slider or line-edits will affect always the topmost layer image
bool isAutoTopMost();
/// Change notifications from DataStorage
void DataStorageChanged(const DataNode* n = NULL);
/// Node removal notifications from DataStorage
void DataStorageRemovedNode(const DataNode* removedNode = NULL);
/// change notifications from mitkLevelWindowProperty
void OnPropertyModified(const itk::EventObject& e);
Image* GetCurrentImage(); ///< return the currently active image
/**
* returns all nodes in the DataStorage that have the following properties:
* "visible" == true, "binary" == false, "levelwindow", and DataType == Image
*/
DataStorage::SetOfObjects::ConstPointer GetRelevantNodes();
protected:
LevelWindowManager();
~LevelWindowManager();
DataStorage::Pointer m_DataStorage;
LevelWindowProperty::Pointer m_LevelWindowProperty; ///< pointer to the LevelWindowProperty of the current image
typedef std::map<unsigned long, BaseProperty::Pointer> ObserverToPropertyMap;
ObserverToPropertyMap m_PropObserverToNode; ///< map to hold observer ID´s to every visible property of DataNode´s BaseProperty
ObserverToPropertyMap m_PropObserverToNode2; ///< map to hold observer ID´s to every layer property of DataNode´s BaseProperty
bool m_AutoTopMost;
unsigned long m_ObserverTag;
bool m_IsObserverTagSet;
unsigned long m_PropertyModifiedTag;
Image* m_CurrentImage;
bool m_IsPropertyModifiedTagSet;
};
}
#endif
diff --git a/Core/Code/DataManagement/mitkLevelWindowPreset.cpp b/Core/Code/DataManagement/mitkLevelWindowPreset.cpp
index c266fd1bc4..21b51a03fe 100644
--- a/Core/Code/DataManagement/mitkLevelWindowPreset.cpp
+++ b/Core/Code/DataManagement/mitkLevelWindowPreset.cpp
@@ -1,133 +1,132 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLevelWindowPreset.h"
#include "mitkStandardFileLocations.h"
#include <vtkObjectFactory.h>
namespace mitk {
const std::string LevelWindowPreset::PRESET = "preset";
vtkStandardNewMacro(LevelWindowPreset);
LevelWindowPreset::LevelWindowPreset()
{
}
LevelWindowPreset::~LevelWindowPreset()
{
}
bool LevelWindowPreset::LoadPreset()
{
m_XmlFileName = mitk::StandardFileLocations::GetInstance()->FindFile("mitkLevelWindowPresets.xml", "Config");
if (!m_XmlFileName.empty())
return LoadPreset(m_XmlFileName);
else
return false;
}
bool LevelWindowPreset::LoadPreset(std::string fileName)
{
if ( fileName.empty() )
return false;
vtkXMLParser::SetFileName( fileName.c_str() );
if ( !vtkXMLParser::Parse() )
{
#ifdef INTERDEBUG
MITK_INFO<<"LevelWindowPreset::LoadPreset xml file cannot parse!"<<std::endl;
#endif
}
return true;
}
void LevelWindowPreset::StartElement (const char *elementName, const char **atts)
{
std::string elementNameString = elementName;
if ( elementNameString == PRESET )
{
std::string name = ReadXMLStringAttribut( "NAME", atts );
std::string level = ReadXMLStringAttribut( "LEVEL", atts );
double lev = atof(level.c_str());
std::string window = ReadXMLStringAttribut( "WINDOW", atts );
double win = atof(window.c_str());
m_Level[name] = lev;
m_Window[name] = win;
}
}
std::string LevelWindowPreset::ReadXMLStringAttribut( std::string name, const char** atts )
{
if(atts)
{
const char** attsIter = atts;
while(*attsIter)
{
if ( name == *attsIter )
{
attsIter++;
return *attsIter;
}
attsIter++;
attsIter++;
}
}
return std::string();
}
double LevelWindowPreset::getLevel(std::string name)
{
return m_Level[name];
}
double LevelWindowPreset::getWindow(std::string name)
{
return m_Window[name];
}
std::map<std::string, double>& LevelWindowPreset::getLevelPresets()
{
return m_Level;
}
std::map<std::string, double>& LevelWindowPreset::getWindowPresets()
{
return m_Window;
}
void LevelWindowPreset::save()
{
//XMLWriter writer(m_XmlFileName.c_str());
//saveXML(writer);
}
void LevelWindowPreset::newPresets(std::map<std::string, double> newLevel, std::map<std::string, double> newWindow)
{
m_Level = newLevel;
m_Window = newWindow;
save();
}
}
diff --git a/Core/Code/DataManagement/mitkLevelWindowPreset.h b/Core/Code/DataManagement/mitkLevelWindowPreset.h
index c5cf7144e4..26f6e4d013 100644
--- a/Core/Code/DataManagement/mitkLevelWindowPreset.h
+++ b/Core/Code/DataManagement/mitkLevelWindowPreset.h
@@ -1,63 +1,62 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 LEVELWINDOWPRESET_H_HEADER
#define LEVELWINDOWPRESET_H_HEADER
#include <vtkXMLParser.h>
#include <MitkExports.h>
#include <map>
#include <string>
namespace mitk {
class MITK_CORE_EXPORT LevelWindowPreset : public vtkXMLParser
{
public:
static LevelWindowPreset *New();
vtkTypeMacro(LevelWindowPreset,vtkXMLParser);
bool LoadPreset();
bool LoadPreset(std::string fileName);
double getLevel(std::string name);
double getWindow(std::string window);
std::map<std::string, double>& getLevelPresets();
std::map<std::string, double>& getWindowPresets();
void newPresets(std::map<std::string, double> newLevel, std::map<std::string, double> newWindow);
protected:
LevelWindowPreset();
~LevelWindowPreset();
private:
//##Documentation
//## @brief method used in XLM-Reading; gets called when a start-tag is read
void StartElement (const char *elementName, const char **atts);
//void saveXML(mitk::XMLWriter& xmlWriter);
void save();
//##Documentation
//## @brief reads an XML-String-Attribute
std::string ReadXMLStringAttribut( std::string name, const char** atts);
static const std::string PRESET;
std::map<std::string, double> m_Level;
std::map<std::string, double> m_Window;
std::string m_XmlFileName;
};
}
#endif
diff --git a/Core/Code/DataManagement/mitkLevelWindowProperty.cpp b/Core/Code/DataManagement/mitkLevelWindowProperty.cpp
index 7c014991aa..1b93f0781b 100755
--- a/Core/Code/DataManagement/mitkLevelWindowProperty.cpp
+++ b/Core/Code/DataManagement/mitkLevelWindowProperty.cpp
@@ -1,75 +1,74 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLevelWindowProperty.h"
mitk::LevelWindowProperty::LevelWindowProperty()
{
}
mitk::LevelWindowProperty::LevelWindowProperty(const mitk::LevelWindow &levWin)
{
SetLevelWindow(levWin);
}
mitk::LevelWindowProperty::~LevelWindowProperty()
{
}
bool mitk::LevelWindowProperty::IsEqual(const BaseProperty& property) const
{
return this->m_LevWin == static_cast<const Self&>(property).m_LevWin;
}
bool mitk::LevelWindowProperty::Assign(const BaseProperty& property)
{
this->m_LevWin = static_cast<const Self&>(property).m_LevWin;
return true;
}
const mitk::LevelWindow & mitk::LevelWindowProperty::GetLevelWindow() const
{
return m_LevWin;
}
const mitk::LevelWindow & mitk::LevelWindowProperty::GetValue() const
{
return GetLevelWindow();
}
void mitk::LevelWindowProperty::SetLevelWindow(const mitk::LevelWindow &levWin)
{
if(m_LevWin != levWin)
{
m_LevWin = levWin;
Modified();
}
}
void mitk::LevelWindowProperty::SetValue(const ValueType& levWin)
{
SetLevelWindow(levWin);
}
std::string mitk::LevelWindowProperty::GetValueAsString() const
{
std::stringstream myStr;
myStr << "L:" << m_LevWin.GetLevel() << " W:" << m_LevWin.GetWindow();
return myStr.str();
}
diff --git a/Core/Code/DataManagement/mitkLevelWindowProperty.h b/Core/Code/DataManagement/mitkLevelWindowProperty.h
index 6320fd1e37..7d1e48c02f 100755
--- a/Core/Code/DataManagement/mitkLevelWindowProperty.h
+++ b/Core/Code/DataManagement/mitkLevelWindowProperty.h
@@ -1,85 +1,84 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKLEVELWINDOWPROPERTY_H_HEADER_INCLUDED_C10EEAA8
#define MITKLEVELWINDOWPROPERTY_H_HEADER_INCLUDED_C10EEAA8
#include "mitkBaseProperty.h"
#include "mitkLevelWindow.h"
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
//##Documentation
//## @brief Property for level/window data
//##
//## @ingroup DataManagement
class MITK_CORE_EXPORT LevelWindowProperty : public BaseProperty
{
protected:
LevelWindow m_LevWin;
LevelWindowProperty();
LevelWindowProperty(const mitk::LevelWindow &levWin);
public:
mitkClassMacro(LevelWindowProperty, BaseProperty);
itkNewMacro(LevelWindowProperty);
mitkNewMacro1Param(LevelWindowProperty, const mitk::LevelWindow&);
typedef LevelWindow ValueType;
virtual ~LevelWindowProperty();
const mitk::LevelWindow & GetLevelWindow() const;
const mitk::LevelWindow & GetValue() const;
void SetLevelWindow(const LevelWindow &levWin);
void SetValue(const ValueType& levWin);
virtual std::string GetValueAsString() const;
using BaseProperty::operator=;
private:
// purposely not implemented
LevelWindowProperty(const LevelWindowProperty&);
LevelWindowProperty& operator=(const LevelWindowProperty&);
virtual bool IsEqual(const BaseProperty& property) const;
virtual bool Assign(const BaseProperty& property);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif /* MITKLEVELWINDOWPROPERTY_H_HEADER_INCLUDED_C10EEAA8 */
diff --git a/Core/Code/DataManagement/mitkLine.h b/Core/Code/DataManagement/mitkLine.h
index 14e9f1b7e9..8a9c24a6f5 100644
--- a/Core/Code/DataManagement/mitkLine.h
+++ b/Core/Code/DataManagement/mitkLine.h
@@ -1,429 +1,428 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKLINE_H_HEADER_INCLUDED_C19C01E2
#define MITKLINE_H_HEADER_INCLUDED_C19C01E2
#include "mitkVector.h"
#include <vnl/vnl_vector.h>
#include <vnl/vnl_cross.h>
#include <itkTransform.h>
#include <itkMatrix.h>
namespace mitk {
//##Documentation
//## @brief Descibes a line
//## @ingroup Geometry
template <class TCoordRep, unsigned int NPointDimension=3>
class Line
{
public:
Line()
{
m_Point.Fill(0);
m_Direction.Fill(0);
};
//##Documentation
//## @brief Define line by point and direction
//##
//## Length of direction defines the the length of the line
Line( const itk::Point<TCoordRep,NPointDimension>& point, const itk::Vector<TCoordRep,NPointDimension>& direction )
{
this->m_Point = point;
this->m_Direction = direction;
}
//##Documentation
//## @brief Get start point of the line
const itk::Point<TCoordRep,NPointDimension>& GetPoint() const
{
return m_Point;
}
//##Documentation
//## @brief Get start point of the line
itk::Point<TCoordRep,NPointDimension>& GetPoint()
{
return m_Point;
}
//##Documentation
//## @brief Get point on the line with parameter @a t
//##
//## @return m_Point+t*m_Direction
const itk::Point<TCoordRep,NPointDimension> GetPoint(TCoordRep t) const
{
return m_Point+m_Direction*t;
}
//##Documentation
//## @brief Set/change start point of the line
void SetPoint( const itk::Point<TCoordRep,NPointDimension>& point1 )
{
itk::Vector<TCoordRep,NPointDimension> point2;
point2 = m_Point + m_Direction;
m_Point = point1;
m_Direction = point2 - point1;
}
//##Documentation
//## @brief Get the direction vector of the line
const itk::Vector<TCoordRep,NPointDimension>& GetDirection() const
{
return m_Direction;
}
//##Documentation
//## @brief Get the direction vector of the line
itk::Vector<TCoordRep,NPointDimension>& GetDirection()
{
return m_Direction;
}
//##Documentation
//## @brief Set the direction vector of the line
void SetDirection( const itk::Vector<TCoordRep,NPointDimension>& direction )
{
m_Direction = direction;
}
//##Documentation
//## @brief Define line by point and direction
//##
//## Length of direction defines the the length of the line
void Set( const itk::Point<TCoordRep,NPointDimension>& point, const itk::Vector<TCoordRep,NPointDimension>& direction ) {
this->m_Point = point;
this->m_Direction = direction;
}
//##Documentation
//## @brief Define line by two points
void SetPoints( const itk::Point<TCoordRep,NPointDimension>& point1, const itk::Point<TCoordRep,NPointDimension>& point2 ) {
this->m_Point = point1;
//this->m_Direction.sub( point2, point1 );
m_Direction = point2 - point1;
}
//##Documentation
//## @brief Set/change start point of the line
void SetPoint1( const itk::Point<TCoordRep,NPointDimension>& point1 ) {
itk::Vector<TCoordRep,NPointDimension> point2;
point2 = m_Point + m_Direction;
m_Point = point1;
m_Direction = point2 - point1;
}
//##Documentation
//## @brief Get start point of the line
const itk::Point<TCoordRep,NPointDimension>& GetPoint1() const
{
return m_Point;
}
//##Documentation
//## @brief Set/change end point of the line
void SetPoint2( const itk::Point<TCoordRep,NPointDimension>& point2 )
{
m_Direction = point2 - m_Point;
}
//##Documentation
//## @brief Get end point of the line
itk::Point<TCoordRep,NPointDimension> GetPoint2() const
{
itk::Point<TCoordRep,NPointDimension> point2;
point2 = m_Point+m_Direction;
return point2;
}
//##Documentation
//## @brief Transform the line with a Transform
void Transform(itk::Transform<TCoordRep, NPointDimension, NPointDimension>& transform)
{
m_Direction = transform.TransformVector(m_Direction);
m_Point = transform.TransformPoint(m_Point);
}
//##Documentation
//## @brief Transform the line with a matrix
//##
//## Only the direction will be changed, not the start point.
void Transform( const itk::Matrix<TCoordRep, NPointDimension, NPointDimension>& matrix )
{
m_Direction = matrix*m_Direction;
}
//##Documentation
//## @brief Distance between two lines
double Distance( const Line<TCoordRep,NPointDimension>& line ) const;
//##Documentation
//## @brief Distance of a point from the line
double Distance( const itk::Point<TCoordRep,NPointDimension>& point ) const
{
itk::Vector<TCoordRep,NPointDimension> diff;
diff = Project(point)-point;
return diff.GetNorm();
}
//##Documentation
//## @brief Project a point on the line
itk::Point<TCoordRep,NPointDimension> Project( const itk::Point<TCoordRep,NPointDimension>& point ) const
{
if(m_Direction.GetNorm()==0)
return this->m_Point;
itk::Vector<TCoordRep,NPointDimension> diff;
diff = point-this->m_Point;
itk::Vector<TCoordRep,NPointDimension> normalizedDirection = m_Direction;
normalizedDirection.Normalize();
normalizedDirection *= dot_product(diff.Get_vnl_vector(), normalizedDirection.Get_vnl_vector());
return this->m_Point + normalizedDirection;
}
//##Documentation
//## @brief Test if a point is part of the line
//##
//## Length of the direction vector defines the length of the line
bool IsPartOfStraightLine( const itk::Point<TCoordRep,NPointDimension>& point ) const
{
if( Distance( point ) > eps )
return false;
itk::Vector<TCoordRep,NPointDimension> diff;
diff = point - this->m_Point;
if( diff*m_Direction < 0 )
return false;
if( diff.GetSquaredNorm() <= m_Direction.GetSquaredNorm() )
return true;
return false;
}
//##Documentation
//## @brief Test if a point is part of the line (line having infinite length)
bool IsPartOfLine( const itk::Point<TCoordRep,NPointDimension>& point ) const {
if ( Distance( point ) < eps )
return true;
return false;
}
//##Documentation
//## @brief Test if a lines is parallel to this line
bool IsParallel( const Line<TCoordRep,NPointDimension>& line) const
{
vnl_vector<TCoordRep> normal;
normal = vnl_cross_3d( m_Direction.Get_vnl_vector(), line.GetDirection().Get_vnl_vector() );
if ( normal.squared_magnitude() < eps )
return true;
return false;
}
//##Documentation
//## @brief Test if a line is part of the line (line having infinite length)
bool IsPartOfLine( const Line<TCoordRep,NPointDimension>& line ) const
{
return ( Distance( line.GetPoint() ) < 0 ) && ( IsParallel( line ) );
}
//##Documentation
//## @brief Test if the two lines are identical
//##
//## Start point and direction and length of direction vector must be
//## equal for identical lines.
bool operator==( const Line<TCoordRep,NPointDimension>& line ) const
{
itk::Vector<TCoordRep,NPointDimension> diff;
diff = GetPoint1()-line.GetPoint1();
if(diff.GetSquaredNorm() > eps)
return false;
diff = GetPoint2()-line.GetPoint2();
if(diff.GetSquaredNorm() > eps)
return false;
return true;
}
//##Documentation
//## @brief Set the line by another line
inline const Line<TCoordRep,NPointDimension>& operator=( const Line<TCoordRep,NPointDimension>& line )
{
m_Point = line.GetPoint();
m_Direction = line.GetDirection();
return *this;
}
//##Documentation
//## @brief Test if two lines are not identical
//##
//## \sa operator==
bool operator!=( const Line<TCoordRep,NPointDimension>& line ) const
{
return !((*this)==line);
}
//##Documentation
//## @brief Calculates the intersection points of a straight line in 2D
//## with a rectangle
//##
//## @param x1,y1,x2,y2 rectangle
//## @param p,d straight line: p point on it, d direction of line
//## @param s1 first intersection point (valid only if s_num>0)
//## @param s2 second intersection point (valid only if s_num==2)
//## @return number of intersection points (0<=s_num<=2)
static int RectangleLineIntersection(
TCoordRep x1, TCoordRep y1,
TCoordRep x2, TCoordRep y2,
itk::Point< TCoordRep, 2 > p, itk::Vector< TCoordRep, 2 > d,
itk::Point< TCoordRep, 2 > &s1, itk::Point< TCoordRep, 2 > &s2 )
{
int s_num;
TCoordRep t;
s_num=0;
/*test if intersecting with the horizontal axis*/
if(fabs(d[0])>eps)
{
t=(x1-p[0])/d[0];
itk::Point<TCoordRep,2> l=p+d*t;
if((l[1]>=y1) && (l[1]<y2))
{ // yes, intersection point within the bounds of the border-line
if(s_num) s2=l; else s1=l; ++s_num;
}
}
if(fabs(d[0])>eps)
{
t=(x2-p[0])/d[0];
itk::Point<TCoordRep,2> l=p+d*t;
if((l[1]>=y1) && (l[1]<y2))
{ // yes, intersection point within the bounds of the border-line
if(s_num) s2=l; else s1=l; ++s_num;
}
}
/*test if intersecting with the vertical axis*/
if(fabs(d[1])>eps)
{
t=(y1-p[1])/d[1];
itk::Point<TCoordRep,2> l=p+d*t;
if((l[0]>=x1) && (l[0]<x2))
{ // yes, intersection point within the bounds of the border-line
if(s_num) s2=l; else s1=l; ++s_num;
}
}
if(fabs(d[1])>eps)
{
t=(y2-p[1])/d[1];
itk::Point<TCoordRep,2> l=p+d*t;
if((l[0]>=x1) && (l[0]<x2))
{ // yes, intersection point within the bounds of the border-line
if(s_num) s2=l; else s1=l; ++s_num;
}
}
return s_num;
}
/**
* \brief Calculates the intersection points of a straight line in 3D with
* a box.
*
* \param x1,y1,z1 first corner of the box
* \param x2,y2,z2 second corner of the box
* \param p,d straight line: p point on it, d direction of line
* \param s1 first intersection point (valid only if s_num>0)
* \param s2 second intersection point (valid only if s_num==2)
* \return number of intersection points (0<=s_num<=2)
*/
static int BoxLineIntersection(
TCoordRep x1, TCoordRep y1, TCoordRep z1,
TCoordRep x2, TCoordRep y2, TCoordRep z2,
itk::Point< TCoordRep, 3 > p, itk::Vector< TCoordRep, 3 > d,
itk::Point< TCoordRep, 3 > &s1, itk::Point< TCoordRep, 3 > &s2 )
{
int num = 0;
ScalarType box[6];
box[0] = x1; box[1] = x2;
box[2] = y1; box[3] = y2;
box[4] = z1; box[5] = z2;
itk::Point< TCoordRep, 3 > point;
int i, j;
for ( i = 0; i < 6; ++i )
{
j = i / 2;
if ( fabs( d[j] ) > eps )
{
ScalarType lambda = (box[i] - p[j]) / d[j];
point = p + d * lambda;
int k = (j + 1) % 3;
int l = (j + 2) % 3;
if ( (point[k] >= box[k*2]) && (point[k] <= box[k*2+1])
&& (point[l] >= box[l*2]) && (point[l] <= box[l*2+1]) )
{
if ( num == 0 )
{
s1 = point;
}
else
{
s2 = point;
}
++num;
}
}
}
return num;
}
protected:
itk::Point<TCoordRep,NPointDimension> m_Point;
itk::Vector<TCoordRep,NPointDimension> m_Direction;
};
typedef Line<ScalarType, 3> Line3D;
} // namespace mitk
#endif /* MITKLINE_H_HEADER_INCLUDED_C19C01E2 */
diff --git a/Core/Code/DataManagement/mitkLookupTable.cpp b/Core/Code/DataManagement/mitkLookupTable.cpp
index ff98c8d220..002b2296e7 100644
--- a/Core/Code/DataManagement/mitkLookupTable.cpp
+++ b/Core/Code/DataManagement/mitkLookupTable.cpp
@@ -1,298 +1,297 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLookupTable.h"
#include <itkProcessObject.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
mitk::LookupTable::LookupTable()
{
m_LookupTable = vtkLookupTable::New();
this->SetRequestedRegionToLargestPossibleRegion();
}
mitk::LookupTable::~LookupTable()
{
if ( m_LookupTable )
{
m_LookupTable->Delete();
m_LookupTable = NULL;
}
}
void mitk::LookupTable::SetVtkLookupTable( vtkLookupTable* lut )
{
if(m_LookupTable == lut)
{
return;
}
if(m_LookupTable)
{
m_LookupTable->UnRegister(NULL);
m_LookupTable = NULL;
}
if(lut)
{
lut->Register(NULL);
}
m_LookupTable = lut;
this->Modified();
}
void mitk::LookupTable::ChangeOpacityForAll( float opacity )
{
int noValues = m_LookupTable->GetNumberOfTableValues ();
vtkFloatingPointType rgba[ 4 ];
for ( int i = 0;i < noValues;i++ )
{
m_LookupTable->GetTableValue ( i, rgba );
rgba[ 3 ] = opacity;
m_LookupTable->SetTableValue ( i, rgba );
}
this->Modified(); // need to call modiefied, since LookupTableProperty seems to be unchanged so no widget-updat is executed
}
void mitk::LookupTable::ChangeOpacity(int index, float opacity )
{
int noValues = m_LookupTable->GetNumberOfTableValues ();
if (index>noValues)
{
MITK_INFO << "could not change opacity. index exceed size of lut ... " << std::endl;
return;
}
vtkFloatingPointType rgba[ 4 ];
m_LookupTable->GetTableValue ( index, rgba );
rgba[ 3 ] = opacity;
m_LookupTable->SetTableValue ( index, rgba );
this->Modified(); // need to call modiefied, since LookupTableProperty seems to be unchanged so no widget-updat is executed
}
vtkLookupTable* mitk::LookupTable::GetVtkLookupTable() const
{
return m_LookupTable;
};
mitk::LookupTable::RawLookupTableType * mitk::LookupTable::GetRawLookupTable() const
{
if (m_LookupTable==NULL) MITK_INFO << "uuups..." << std::endl;
return m_LookupTable->GetPointer( 0 );
};
/*!
* \brief equality operator inplementation
*/
bool mitk::LookupTable::operator==( const mitk::LookupTable& other ) const
{
if ( m_LookupTable == other.GetVtkLookupTable())
return true;
vtkLookupTable* olut = other.GetVtkLookupTable();
if (olut == NULL)
return false;
bool equal = (m_LookupTable->GetNumberOfColors() == olut->GetNumberOfColors())
&& (m_LookupTable->GetTableRange()[0] == olut->GetTableRange()[0])
&& (m_LookupTable->GetTableRange()[1] == olut->GetTableRange()[1])
&& (m_LookupTable->GetHueRange()[0] == olut->GetHueRange()[0])
&& (m_LookupTable->GetHueRange()[1] == olut->GetHueRange()[1])
&& (m_LookupTable->GetSaturationRange()[0] == olut->GetSaturationRange()[0])
&& (m_LookupTable->GetSaturationRange()[1] == olut->GetSaturationRange()[1])
&& (m_LookupTable->GetValueRange()[0] == olut->GetValueRange()[0])
&& (m_LookupTable->GetValueRange()[1] == olut->GetValueRange()[1])
&& (m_LookupTable->GetAlphaRange()[0] == olut->GetAlphaRange()[0])
&& (m_LookupTable->GetAlphaRange()[1] == olut->GetAlphaRange()[1])
&& (m_LookupTable->GetRamp() == olut->GetRamp())
&& (m_LookupTable->GetScale() == olut->GetScale())
&& (m_LookupTable->GetAlpha() == olut->GetAlpha())
&& (m_LookupTable->GetTable()->GetNumberOfTuples() == olut->GetTable()->GetNumberOfTuples());
if (equal == false)
return false;
//for (vtkIdType i=0; i < m_LookupTable->GetTable()->GetNumberOfTuples(); i++)
//{
// if (m_LookupTable->GetTable()->GetTuple(i) != olut->GetTable()->GetTuple(i))
// return false;
//}
for (vtkIdType i=0; i < m_LookupTable->GetNumberOfTableValues(); i++)
{
//double v0_1 = m_LookupTable->GetTableValue(i)[0]; double v0_2 = olut->GetTableValue(i)[0];
//double v1_1 = m_LookupTable->GetTableValue(i)[1]; double v1_2 = olut->GetTableValue(i)[1];
//double v2_1 = m_LookupTable->GetTableValue(i)[2]; double v2_2 = olut->GetTableValue(i)[2];
//double v3_1 = m_LookupTable->GetTableValue(i)[3]; double v3_2 = olut->GetTableValue(i)[3];
bool tvequal = (m_LookupTable->GetTableValue(i)[0] == olut->GetTableValue(i)[0])
&& (m_LookupTable->GetTableValue(i)[1] == olut->GetTableValue(i)[1])
&& (m_LookupTable->GetTableValue(i)[2] == olut->GetTableValue(i)[2])
&& (m_LookupTable->GetTableValue(i)[3] == olut->GetTableValue(i)[3]);
if (tvequal == false)
return false;
}
return true;
}
/*!
* \brief un-equality operator implementation
*/
bool mitk::LookupTable::operator!=( const mitk::LookupTable& other ) const
{
return !(*this == other);
}
/*!
* \brief assignment operator implementation
*/
mitk::LookupTable& mitk::LookupTable::operator=( const mitk::LookupTable& LookupTable )
{
if ( this == &LookupTable )
{
return * this;
}
else
{
m_LookupTable = LookupTable.GetVtkLookupTable();
return *this;
}
}
void mitk::LookupTable::UpdateOutputInformation( )
{
if ( this->GetSource( ) )
{
this->GetSource( ) ->UpdateOutputInformation( );
}
}
void mitk::LookupTable::SetRequestedRegionToLargestPossibleRegion( )
{}
bool mitk::LookupTable::RequestedRegionIsOutsideOfTheBufferedRegion( )
{
return false;
}
bool mitk::LookupTable::VerifyRequestedRegion( )
{
//normally we should check if the requested region lies within the
//largest possible region. Since for lookup-tables we assume, that the
//requested region is always the largest possible region, we can always
//return true!
return true;
}
void mitk::LookupTable::SetRequestedRegion( itk::DataObject *)
{
//not implemented, since we always want to have the RequestedRegion
//to be set to LargestPossibleRegion
}
void mitk::LookupTable::CreateColorTransferFunction(vtkColorTransferFunction*& colorFunction)
{
if(colorFunction==NULL)
colorFunction = vtkColorTransferFunction::New();
mitk::LookupTable::RawLookupTableType *rgba = GetRawLookupTable();
int i, num_of_values=m_LookupTable->GetNumberOfTableValues();
vtkFloatingPointType *cols;
vtkFloatingPointType *colsHead;
colsHead=cols=(vtkFloatingPointType *)malloc(sizeof(vtkFloatingPointType)*num_of_values*3);
for(i=0;i<num_of_values;++i)
{
*cols=*rgba/255.0; ++cols; ++rgba;
*cols=*rgba/255.0; ++cols; ++rgba;
*cols=*rgba/255.0; ++cols; ++rgba;
++rgba;
}
colorFunction->BuildFunctionFromTable(m_LookupTable->GetTableRange()[0], m_LookupTable->GetTableRange()[1], num_of_values-1, colsHead);
free(colsHead);
}
void mitk::LookupTable::CreateOpacityTransferFunction(vtkPiecewiseFunction*& opacityFunction)
{
if(opacityFunction==NULL)
opacityFunction = vtkPiecewiseFunction::New();
mitk::LookupTable::RawLookupTableType *rgba = GetRawLookupTable();
int i, num_of_values=m_LookupTable->GetNumberOfTableValues();
vtkFloatingPointType *alphas;
vtkFloatingPointType *alphasHead;
alphasHead=alphas=(vtkFloatingPointType*)malloc(sizeof(vtkFloatingPointType)*num_of_values);
rgba+=3;
for(i=0;i<num_of_values;++i)
{
*alphas=*rgba * 1024.0; ++alphas; rgba+=4;
}
opacityFunction->BuildFunctionFromTable(m_LookupTable->GetTableRange()[0], m_LookupTable->GetTableRange()[1], num_of_values-1, alphasHead);
free(alphasHead);
}
void mitk::LookupTable::CreateGradientTransferFunction(vtkPiecewiseFunction*& gradientFunction)
{
if(gradientFunction==NULL)
gradientFunction = vtkPiecewiseFunction::New();
mitk::LookupTable::RawLookupTableType *rgba = GetRawLookupTable();
int i, num_of_values=m_LookupTable->GetNumberOfTableValues();
vtkFloatingPointType *alphas;
vtkFloatingPointType *alphasHead;
alphasHead=alphas=(vtkFloatingPointType*)malloc(sizeof(vtkFloatingPointType)*num_of_values);
rgba+=3;
for(i=0;i<num_of_values;++i)
{
*alphas=*rgba * 1024.0; ++alphas; rgba+=4;
}
gradientFunction->BuildFunctionFromTable(m_LookupTable->GetTableRange()[0], m_LookupTable->GetTableRange()[1], num_of_values-1, alphasHead);
free(alphasHead);
}
void mitk::LookupTable::PrintSelf(std::ostream &os, itk::Indent indent) const
{
os << indent;
m_LookupTable->PrintHeader(os, vtkIndent());
}
diff --git a/Core/Code/DataManagement/mitkLookupTable.h b/Core/Code/DataManagement/mitkLookupTable.h
index d3be30a1b8..c6dd27c3bb 100644
--- a/Core/Code/DataManagement/mitkLookupTable.h
+++ b/Core/Code/DataManagement/mitkLookupTable.h
@@ -1,135 +1,134 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKLookupTable_H_HEADER_INCLUDED_C1EBD53D
#define MITKLookupTable_H_HEADER_INCLUDED_C1EBD53D
#include <MitkExports.h>
#include <mitkCommon.h>
#include "vtkLookupTable.h"
#include <itkDataObject.h>
#include <itkObjectFactory.h>
class vtkColorTransferFunction;
class vtkPiecewiseFunction;
namespace mitk
{
//##
//##Documentation
//## @brief LookupTable containing a vtkLookupTable
//## @ingroup Data
//##
class MITK_CORE_EXPORT LookupTable : public itk::DataObject
{
public:
/**
*@brief Some convenient typedefs.
*/
typedef unsigned char RawLookupTableType;
mitkClassMacro( LookupTable, itk::DataObject );
itkNewMacro( Self );
/**
* @returns the associated vtkLookupTable
*/
virtual vtkLookupTable* GetVtkLookupTable() const;
virtual RawLookupTableType * GetRawLookupTable() const;
virtual void SetVtkLookupTable( vtkLookupTable* lut );
virtual void ChangeOpacityForAll( float opacity );
virtual void ChangeOpacity(int index, float opacity );
/*!
* \brief equality operator implementation
*/
virtual bool operator==( const mitk::LookupTable& LookupTable ) const;
/*!
* \brief non equality operator implementation
*/
virtual bool operator!=( const LookupTable& LookupTable ) const;
/*!
* \brief implementation necessary because operator made
* private in itk::Object
*/
virtual LookupTable& operator=( const LookupTable& LookupTable );
/**
* Updates the output information of the current object by calling
* updateOutputInformation of the data objects source object.
*/
virtual void UpdateOutputInformation( );
/**
* Sets the requested Region to the largest possible region.
* This method is not implemented, since this is the default
* behaviour of the itk pipeline and we do not support the
* requested-region mechanism for lookup-tables
*/
virtual void SetRequestedRegionToLargestPossibleRegion( );
/**
* Checks, if the requested region lies outside of the buffered region by
* calling verifyRequestedRegion().
*/
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion( );
/**
* Checks if the requested region is completely contained in
* the buffered region. Since we always want to process the lookup
* table as a whole, this method always returns true
*/
virtual bool VerifyRequestedRegion( );
/**
* This method has no effect for lookup tables, since we do
* not support the region-mechanism
*/
virtual void SetRequestedRegion( itk::DataObject *data );
LookupTable();
virtual ~LookupTable();
void CreateColorTransferFunction(vtkColorTransferFunction*& colorFunction);
void CreateOpacityTransferFunction(vtkPiecewiseFunction*& opacityFunction);
void CreateGradientTransferFunction(vtkPiecewiseFunction*& gradientFunction);
protected:
void PrintSelf(std::ostream &os, itk::Indent indent) const;
vtkLookupTable* m_LookupTable;
private:
};
} // namespace mitk
#endif /* LookupTable_H_HEADER_INCLUDED_C1EBD53D */
diff --git a/Core/Code/DataManagement/mitkLookupTables.cpp b/Core/Code/DataManagement/mitkLookupTables.cpp
index c4f4a9bf7b..4ef9464acc 100644
--- a/Core/Code/DataManagement/mitkLookupTables.cpp
+++ b/Core/Code/DataManagement/mitkLookupTables.cpp
@@ -1,30 +1,29 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:31:16 +0200 (Di, 12. Mai 2009) $
-Version: $Revision: 17175 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLookupTables.h"
template class mitk::GenericLookupTable<bool>;
template class mitk::GenericLookupTable<float>;
template class mitk::GenericLookupTable<int>;
template class mitk::GenericLookupTable<std::string>;
mitkSpecializeGenericLookupTableOperator(mitk::BoolLookupTable);
mitkSpecializeGenericLookupTableOperator(mitk::FloatLookupTable);
mitkSpecializeGenericLookupTableOperator(mitk::IntLookupTable);
mitkSpecializeGenericLookupTableOperator(mitk::StringLookupTable);
diff --git a/Core/Code/DataManagement/mitkLookupTables.h b/Core/Code/DataManagement/mitkLookupTables.h
index 6e94840fde..4778814dcf 100644
--- a/Core/Code/DataManagement/mitkLookupTables.h
+++ b/Core/Code/DataManagement/mitkLookupTables.h
@@ -1,41 +1,40 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:31:16 +0200 (Di, 12. Mai 2009) $
-Version: $Revision: 17175 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKLOOKUPTABLES_H_HEADER_INCLUDED
#define MITKLOOKUPTABLES_H_HEADER_INCLUDED
#include "mitkGenericLookupTable.h"
namespace mitk {
/**Documentation
* \brief specializations of GenericLookupTable
*
* This file contains specializations of mitk::GenericLookupTable
* for bool, float, int and std::string lookuptables
* \WARN: you have to call the mitkSpecializeGenericLookupTableOperator macro
* in mitkLookupTables.cpp with each specialization to add an ostream << operator
* for that lookuptable specialization.
*/
mitkSpecializeGenericLookupTable(BoolLookupTable, bool);
mitkSpecializeGenericLookupTable(FloatLookupTable, float);
mitkSpecializeGenericLookupTable(IntLookupTable, int);
mitkSpecializeGenericLookupTable(StringLookupTable, std::string);
} // namespace mitk
#endif /* MITKLOOKUPTABLES_H_HEADER_INCLUDED*/
diff --git a/Core/Code/DataManagement/mitkMaterial.cpp b/Core/Code/DataManagement/mitkMaterial.cpp
index c17e3e512d..313762703d 100644
--- a/Core/Code/DataManagement/mitkMaterial.cpp
+++ b/Core/Code/DataManagement/mitkMaterial.cpp
@@ -1,390 +1,389 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkMaterial.h"
#include "mitkProperties.h"
#include "mitkVtkInterpolationProperty.h"
#include "mitkVtkRepresentationProperty.h"
#include <vtkProperty.h>
#include "mitkDataNode.h"
#include "mitkBaseRenderer.h"
mitk::Material::Material( Color color, vtkFloatingPointType opacity )
{
InitializeStandardValues();
SetColor( color );
SetColorCoefficient( GetColorCoefficient() );
SetSpecularColor( GetSpecularColor() );
SetSpecularCoefficient( GetSpecularCoefficient() );
SetSpecularPower( GetSpecularPower() );
SetOpacity( opacity );
SetInterpolation( GetInterpolation() );
SetRepresentation( GetRepresentation() );
SetLineWidth( GetLineWidth() );
m_Name = "";
}
mitk::Material::Material( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue, vtkFloatingPointType opacity )
{
InitializeStandardValues();
SetColor( red, green, blue );
SetColorCoefficient( GetColorCoefficient() );
SetSpecularColor( GetSpecularColor() );
SetSpecularCoefficient( GetSpecularCoefficient() );
SetSpecularPower( GetSpecularPower() );
SetOpacity( opacity );
SetInterpolation( GetInterpolation() );
SetRepresentation( GetRepresentation() );
SetLineWidth( GetLineWidth() );
m_Name = "";
}
mitk::Material::Material( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue,
vtkFloatingPointType colorCoefficient, vtkFloatingPointType specularCoefficient,
vtkFloatingPointType specularPower, vtkFloatingPointType opacity )
{
InitializeStandardValues();
SetColor( red, green, blue );
SetColorCoefficient( colorCoefficient );
SetSpecularColor( GetSpecularColor() );
SetSpecularCoefficient( specularCoefficient );
SetSpecularPower( specularPower );
SetOpacity( opacity );
SetInterpolation( GetInterpolation() );
SetRepresentation( GetRepresentation() );
SetLineWidth( GetLineWidth() );
m_Name = "";
}
mitk::Material::Material( mitk::Material::Color color, vtkFloatingPointType colorCoefficient, vtkFloatingPointType specularCoefficient, vtkFloatingPointType specularPower, vtkFloatingPointType opacity )
{
InitializeStandardValues();
SetColor( color );
SetColorCoefficient( colorCoefficient );
SetSpecularColor( GetSpecularColor() );
SetSpecularCoefficient( specularCoefficient );
SetSpecularPower( specularPower );
SetOpacity( opacity );
SetInterpolation( GetInterpolation() );
SetRepresentation( GetRepresentation() );
SetLineWidth( GetLineWidth() );
}
mitk::Material::Material( )
{
InitializeStandardValues();
SetColor( GetColor() );
SetColorCoefficient( GetColorCoefficient() );
SetSpecularColor( GetSpecularColor() );
SetSpecularCoefficient( GetSpecularCoefficient() );
SetSpecularPower( GetSpecularPower() );
SetOpacity( GetOpacity() );
SetInterpolation( GetInterpolation() );
SetRepresentation( GetRepresentation() );
SetLineWidth( GetLineWidth() );
}
mitk::Material::Material( const Material& property ) : itk::Object()
{
Initialize( property );
}
mitk::Material::Material( const Material& property, vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue, vtkFloatingPointType opacity, std::string name )
{
Initialize( property );
SetColor( red, green, blue );
SetOpacity( opacity );
SetName( name );
}
bool mitk::Material::Assignable(const Material& other) const
{
try
{
const Material& otherinstance = dynamic_cast<const Self&>(other); // dear compiler, please don't optimize this away! Thanks.
otherinstance.GetOpacity();
return true;
}
catch (std::bad_cast)
{
}
return false;
}
mitk::Material& mitk::Material::operator=(const mitk::Material& other)
{
try
{
const Self& otherProp( dynamic_cast<const Self&>(other) );
Initialize(otherProp);
}
catch (std::bad_cast)
{
// nothing to do then
}
return *this;
}
void mitk::Material::SetColor( mitk::Material::Color color )
{
m_Color = color;
Modified();
}
void mitk::Material::SetColor( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue )
{
m_Color.Set( red, green, blue );
Modified();
}
void mitk::Material::SetColorCoefficient( vtkFloatingPointType coefficient )
{
m_ColorCoefficient = coefficient;
Modified();
}
void mitk::Material::SetSpecularColor( mitk::Material::Color specularColor )
{
m_SpecularColor = specularColor;
Modified();
}
void mitk::Material::SetSpecularColor( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue )
{
m_SpecularColor.Set( red, green, blue );
Modified();
}
void mitk::Material::SetSpecularCoefficient( vtkFloatingPointType specularCoefficient )
{
m_SpecularCoefficient = specularCoefficient;
Modified();
}
void mitk::Material::SetSpecularPower( vtkFloatingPointType specularPower )
{
m_SpecularPower = specularPower;
Modified();
}
void mitk::Material::SetOpacity( vtkFloatingPointType opacity )
{
m_Opacity = opacity;
Modified();
}
void mitk::Material::SetInterpolation( InterpolationType interpolation )
{
m_Interpolation = interpolation;
Modified();
}
void mitk::Material::SetRepresentation( RepresentationType representation )
{
m_Representation = representation;
Modified();
}
void mitk::Material::SetLineWidth( float lineWidth )
{
m_LineWidth = lineWidth;
Modified();
}
mitk::Material::Color mitk::Material::GetColor() const
{
return m_Color;
}
vtkFloatingPointType mitk::Material::GetColorCoefficient() const
{
return m_ColorCoefficient;
}
mitk::Material::Color mitk::Material::GetSpecularColor() const
{
return m_SpecularColor;
}
vtkFloatingPointType mitk::Material::GetSpecularCoefficient() const
{
return m_SpecularCoefficient;
}
vtkFloatingPointType mitk::Material::GetSpecularPower() const
{
return m_SpecularPower;
}
vtkFloatingPointType mitk::Material::GetOpacity() const
{
return m_Opacity;
}
mitk::Material::InterpolationType mitk::Material::GetInterpolation() const
{
return m_Interpolation;
}
mitk::Material::RepresentationType mitk::Material::GetRepresentation() const
{
return m_Representation;
}
int mitk::Material::GetVtkInterpolation() const
{
switch ( m_Interpolation )
{
case( Flat ) : return VTK_FLAT;
case( Gouraud ) : return VTK_GOURAUD;
case( Phong ) : return VTK_PHONG;
}
return VTK_GOURAUD;
}
int mitk::Material::GetVtkRepresentation() const
{
switch ( m_Representation )
{
case( Points ) : return VTK_POINTS;
case( Wireframe ) : return VTK_WIREFRAME;
case( Surface ) : return VTK_SURFACE;
}
return VTK_SURFACE;
}
float mitk::Material::GetLineWidth() const
{
return m_LineWidth;
}
void mitk::Material::Initialize( const Material& property )
{
this->SetColor( property.GetColor() );
this->SetColorCoefficient( property.GetColorCoefficient() );
this->SetSpecularColor( property.GetSpecularColor() );
this->SetSpecularCoefficient( property.GetSpecularCoefficient() );
this->SetSpecularPower( property.GetSpecularPower() );
this->SetOpacity( property.GetOpacity() );
this->SetInterpolation( property.GetInterpolation() );
this->SetRepresentation( property.GetRepresentation() );
this->SetLineWidth( property.GetLineWidth() );
this->SetName( property.GetName() );
}
bool mitk::Material::operator==( const Material& property ) const
{
const Self * other = dynamic_cast<const Self*>( &property );
if ( other == NULL )
return false;
else
return ( m_Color == other->GetColor() &&
m_ColorCoefficient == other->GetColorCoefficient() &&
m_SpecularColor == other->GetSpecularColor() &&
m_SpecularCoefficient == other->GetSpecularCoefficient() &&
m_SpecularPower == other->GetSpecularPower() &&
m_Opacity == other->GetOpacity() &&
m_Interpolation == other->GetInterpolation() &&
m_Name == other->GetName() &&
m_Representation == other->GetRepresentation() &&
m_LineWidth == other->GetLineWidth()
);
}
void mitk::Material::InitializeStandardValues()
{
m_Color.Set( 0.5, 0.5, 0.0 );
m_ColorCoefficient = 0.5 ;
m_SpecularColor.Set( 1.0, 1.0, 1.0 );
m_SpecularCoefficient = 0.5;
m_SpecularPower = 10.0;
m_Opacity = 1.0 ;
m_Interpolation = Gouraud;
m_Representation = Surface;
m_LineWidth = 1.0;
m_Name = "";
}
void mitk::Material::Update()
{
this->SetColor( this->GetColor() );
this->SetColorCoefficient( this->GetColorCoefficient() );
this->SetSpecularColor( this->GetSpecularColor() );
this->SetSpecularCoefficient( this->GetSpecularCoefficient() );
this->SetSpecularPower( this->GetSpecularPower() );
this->SetOpacity( this->GetOpacity() );
this->SetInterpolation( this->GetInterpolation() );
this->SetRepresentation( this->GetRepresentation() );
}
void mitk::Material::PrintSelf ( std::ostream &os, itk::Indent /* unused */ ) const
{
os << "Name: " << GetName() << std::endl;
os << "Color: " << GetColor() << std::endl;
os << "ColorCoefficient" << GetColorCoefficient() << std::endl;
os << "SpecularColor: " << GetSpecularColor() << std::endl;
os << "SpecularCoefficient: " << GetSpecularCoefficient() << std::endl;
os << "SpecularPower: " << GetSpecularPower() << std::endl;
os << "Opacity: " << GetOpacity() << std::endl;
os << "Line width: " << GetLineWidth() << std::endl;
switch ( GetInterpolation() )
{
case ( Flat ) : os << "Interpolation: Flat" << std::endl;
break;
case ( Gouraud ) : os << "Interpolation: Gouraud" << std::endl;
break;
case ( Phong ) : os << "Interpolation: Phong" << std::endl;
break;
}
switch ( GetRepresentation() )
{
case ( Points ) : os << "Representation: Points" << std::endl;
break;
case ( Wireframe ) : os << "Representation: Wireframe" << std::endl;
break;
case ( Surface ) : os << "Representation: Surface" << std::endl;
break;
}
}
diff --git a/Core/Code/DataManagement/mitkMaterial.h b/Core/Code/DataManagement/mitkMaterial.h
index 55ad4f155f..dda6fe4821 100644
--- a/Core/Code/DataManagement/mitkMaterial.h
+++ b/Core/Code/DataManagement/mitkMaterial.h
@@ -1,479 +1,478 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_MATERIAL_H_
#define _MITK_MATERIAL_H_
#include <MitkExports.h>
#include <mitkCommon.h>
#include <itkRGBPixel.h>
#include <itkObject.h>
#include <itkVectorContainer.h>
#include <vtkSystemIncludes.h>
#include <string>
namespace mitk
{
/**
* Encapsulates 3D visualization properties which are forwarded to vtk for
* color mapping. This includes color, specular coefficient and power, opacity
* interpolation type (flat, gouraud, phong) and representation (points,
* wireframe or surface).
*
* @see vtkProperty
*/
class MITK_CORE_EXPORT Material : public itk::Object
{
public:
mitkClassMacro( Material, itk::Object );
typedef itk::RGBPixel<vtkFloatingPointType> Color;
enum InterpolationType
{
Flat, Gouraud, Phong
};
enum RepresentationType
{
Points, Wireframe, Surface
};
/**
* Constructor. Materials are set to the following default values:
* Color (0.5, 0.5, 0.5) color coefficient 1.0, specular color (1.0, 1.0, 1.0),
* specular coefficient 1.0, specular power 10, opacity 1.0, interpolation
* Gouraud, representation Surface.
* @param node optinally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
static Pointer New()
{
Pointer smartPtr = new Material( );
smartPtr->UnRegister();
return smartPtr;
}
/**
* Constructor. All values besides the given ones are set to defaults as
* described in the default constructor
* @param color the material color in RGB. Each RGB value should be in the
* range [0..1]
* @param opacity the opacity of the material. 0.0 means fully transparent
* and 1.0 means solid.
* @param node optinally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
static Pointer New( Color color, vtkFloatingPointType opacity = 1.0f)
{
Pointer smartPtr = new Material(color, opacity );
smartPtr->UnRegister();
return smartPtr;
}
/**
* Constructor. All values besides the given ones are set to defaults as
* described in the default constructor
* @param red the red component of the materials color (range [0..1])
* @param green the green component of the materials color (range [0..1])
* @param blue the blue component of the materials color (range [0..1])
* @param opacity the opacity of the material. 0.0 means fully transparent
* and 1.0 means solid.
* @param node optionally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
static Pointer New( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue, vtkFloatingPointType opacity = 1.0f)
{
Pointer smartPtr = new Material(red, green, blue, opacity );
smartPtr->UnRegister();
return smartPtr;
}
/**
* Constructor. All values besides the given ones are set to defaults as
* described in the default constructor
* @param red the red component of the materials color (range [0..1])
* @param green the green component of the materials color (range [0..1])
* @param blue the blue component of the materials color (range [0..1])
* @param colorCoefficient a scaling factor for the color coefficient which
* will be multiplied with each color component (range [0..1]).
* @param specularCoefficient controls in combination with the specular power
* how shiny the material will appear (range [0..1]).
* @param specularPower controls in combination with the specular coefficient
* how shiny the material will appear (range [0..inf]).
* @param opacity the opacity of the material. 0.0 means fully transparent
* and 1.0 means solid.
* @param node optionally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
static Pointer New( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue, vtkFloatingPointType colorCoefficient,
vtkFloatingPointType specularCoefficient, vtkFloatingPointType specularPower, vtkFloatingPointType opacity )
{
Pointer smartPtr = new Material(red, green, blue, colorCoefficient, specularCoefficient, specularPower, opacity );
smartPtr->UnRegister();
return smartPtr;
}
/**
* Constructor. All values besides the given ones are set to defaults as
* described in the default constructor
*
* @param color the material color in RGB. Each RGB value should be in the
* range [0..1]
* @param colorCoefficient a scaling factor for the color coefficient which
* will be multiplied with each color component (range [0..1]).
* @param specularCoefficient controls in combination with the specular power
* how shiny the material will appear (range [0..1]).
* @param specularPower controls in combination with the specular coefficient
* how shiny the material will appear (range [0..inf]).
* @param opacity the opacity of the material. 0.0 means fully transparent
* and 1.0 means solid.
* @param node optionally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
static Pointer New( Color color, vtkFloatingPointType colorCoefficient, vtkFloatingPointType specularCoefficient, vtkFloatingPointType specularPower, vtkFloatingPointType opacity )
{
Pointer smartPtr = new Material(color, colorCoefficient, specularCoefficient, specularPower, opacity );
smartPtr->UnRegister();
return smartPtr;
}
/**
* Copy constructor
*/
mitkNewMacro1Param(Material, const Material&);
/**
* Copy constructor, provided for convinience. The values are copied from property
* and afterwards the values provided for red green blue and opacity are written into the object.
*/
static Pointer New( const Material& property, vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue, vtkFloatingPointType opacity = 1.0, std::string name = "" )
{
Pointer smartPtr = new Material(property, red, green, blue, opacity, name );
smartPtr->UnRegister();
return smartPtr;
}
virtual bool Assignable(const Material& other) const;
virtual Material& operator=(const Material& other);
/* Sets the materials color in RGB space. The rgb components have to be
* in the range [0..1]
* @param color the new color of the material
*/
virtual void SetColor( Color color );
/**
* Sets the materials color in RGB space. The rgb components have to be
* in the range [0..1]
* @param red the red component of the materials color (range [0..1])
* @param green the green component of the materials color (range [0..1])
* @param blue the blue component of the materials color (range [0..1])
*/
virtual void SetColor( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue );
/**
* Sets a attenuation coefficient for the color. A value of 0 results in
* a black object. VAlid range is [0..1]
* @param coefficient the color attenuation coefficient
*/
virtual void SetColorCoefficient( vtkFloatingPointType coefficient );
/**
* Sets the specular color
* @param color the specular color in RGB. Each RGB value should be in the
* range [0..1]
*/
virtual void SetSpecularColor( Color color );
/**
* Sets the specular color
* @param red the red component of the specular color (range [0..1])
* @param green the green component of the specular color (range [0..1])
* @param blue the blue component of the specular color (range [0..1])
*/
virtual void SetSpecularColor( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue );
/**
* Sets the specular coefficient which controls the shininess of the object
* together with the specular power
* @param specularCoefficient the new specular coefficient. Valid range
* is [0..1]
*/
virtual void SetSpecularCoefficient( vtkFloatingPointType specularCoefficient );
/**
* Sets the specular power which controls the shininess of the object
* together with the specular coefficient
* @param specularCoefficient the new specular coefficient. Valid range
* is [0..inf]
*/
virtual void SetSpecularPower( vtkFloatingPointType specularPower );
/**
* Sets the opacity of the material, which controls how transparent the
* object appears. Valid range is [0..1], where 0 means fully transparent
* and 1 means a solid surface.
* @param opacity the new opacity of the material
*/
virtual void SetOpacity( vtkFloatingPointType opacity );
/**
* Sets the surface interpolation method of the object rendered using the
* given materials. Valid Interopation types are Flat, Gouraud and Phong.
* See any computer graphics book for their meaning
* @param interpolation the interpolation method used for rendering of
* surfaces.
*/
virtual void SetInterpolation( InterpolationType interpolation );
/**
* Sets the surface representation method of the object rendered using the
* given materials. Valid Interopation types are Points, Wireframe and
* Surface.
* @param representation the representation method used for rendering of
* surfaces.
*/
virtual void SetRepresentation( RepresentationType representation );
/**
* Set/Get the width of a Line. The width is expressed in screen units. The default is 1.0.
*/
virtual void SetLineWidth( float lineWidth );
/**
* @returns the color of the material
*/
virtual Color GetColor() const;
/**
* @returns the color coefficient of the material. Range is [0..1]
*/
virtual vtkFloatingPointType GetColorCoefficient() const;
/**
* @returns the specular color of the material in rgb values, which
* range from 0 .. 1
*/
virtual Color GetSpecularColor() const;
/**
* @returns the specular coefficient used for rendering. Range is [0..1]
*/
virtual vtkFloatingPointType GetSpecularCoefficient() const;
/**
* @returns the specular power. Ranges from 0 to infinity
*/
virtual vtkFloatingPointType GetSpecularPower() const;
/**
* @returns the opacity of the material. Ranges from 0 to 1
*/
virtual vtkFloatingPointType GetOpacity() const;
/**
* @returns the interpolation method used for rendering.
*/
virtual InterpolationType GetInterpolation() const;
/**
* @returns the representation type used for rendering.
*/
virtual RepresentationType GetRepresentation() const;
/**
* @returns the interpolation method used for rendering using the predefined
* vtk constants.
*/
virtual int GetVtkInterpolation() const;
/**
* @returns the representation type used for rendering using the predefined
* vtk constants.
*/
virtual int GetVtkRepresentation() const;
/**
* @returns the line width used for wireframe rendering as a fraction of screen units
*/
virtual float GetLineWidth() const;
/**
* Fills the current materials with the properties of the
* given material.
* @param property the materials which should be copied in the
* current materials
* @param copyDataNode If set to true, the data tree node and renderer
* associated with the material property are also copied. Otherwise
* these member variables will be left untouched
*/
virtual void Initialize( const Material& property );
/**
* comparison operator which uses the member variables for
* comparison
*/
virtual bool operator==( const Material& property ) const;
/**
* Dumps the properties to the out stream out
*/
void PrintSelf ( std::ostream &os, itk::Indent ) const;
/**
* Sets an optional name which may be associated with the material property
* Please note, that this name is NOT forwarded to the data tree node
* as the node name
*/
itkSetMacro( Name, std::string );
/**
* returns the name associated with the material property
*/
itkGetConstMacro( Name, std::string );
protected:
/**
* Constructor. Materials are set to the following default values:
* Color (0.5, 0.5, 0.5) color coefficient 1.0, specular color (1.0, 1.0, 1.0),
* specular coefficient 1.0, specular power 10, opacity 1.0, interpolation
* Gouraud, representation Surface.
* @param node optinally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
Material( );
/**
* Constructor. All values besides the given ones are set to defaults as
* described in the default constructor
* @param color the material color in RGB. Each RGB value should be in the
* range [0..1]
* @param opacity the opacity of the material. 0.0 means fully transparent
* and 1.0 means solid.
* @param node optinally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
Material( Color color, vtkFloatingPointType opacity = 1.0f );
/**
* Constructor. All values besides the given ones are set to defaults as
* described in the default constructor
* @param red the red component of the materials color (range [0..1])
* @param green the green component of the materials color (range [0..1])
* @param blue the blue component of the materials color (range [0..1])
* @param opacity the opacity of the material. 0.0 means fully transparent
* and 1.0 means solid.
* @param node optionally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
Material( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue, vtkFloatingPointType opacity = 1.0f );
/**
* Constructor. All values besides the given ones are set to defaults as
* described in the default constructor
* @param red the red component of the materials color (range [0..1])
* @param green the green component of the materials color (range [0..1])
* @param blue the blue component of the materials color (range [0..1])
* @param colorCoefficient a scaling factor for the color coefficient which
* will be multiplied with each color component (range [0..1]).
* @param specularCoefficient controls in combination with the specular power
* how shiny the material will appear (range [0..1]).
* @param specularPower controls in combination with the specular coefficient
* how shiny the material will appear (range [0..inf]).
* @param opacity the opacity of the material. 0.0 means fully transparent
* and 1.0 means solid.
* @param node optionally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
Material( vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue, vtkFloatingPointType colorCoefficient,
vtkFloatingPointType specularCoefficient, vtkFloatingPointType specularPower, vtkFloatingPointType opacity );
/**
* Constructor. All values besides the given ones are set to defaults as
* described in the default constructor
*
* @param color the material color in RGB. Each RGB value should be in the
* range [0..1]
* @param colorCoefficient a scaling factor for the color coefficient which
* will be multiplied with each color component (range [0..1]).
* @param specularCoefficient controls in combination with the specular power
* how shiny the material will appear (range [0..1]).
* @param specularPower controls in combination with the specular coefficient
* how shiny the material will appear (range [0..inf]).
* @param opacity the opacity of the material. 0.0 means fully transparent
* and 1.0 means solid.
* @param node optionally a data tree node may be defined to which the properties
* are forwarded. Please note, that if this node doesn't have the
* needed properties associated, they will be added.
*/
Material( Color color, vtkFloatingPointType colorCoefficient, vtkFloatingPointType specularCoefficient, vtkFloatingPointType specularPower, vtkFloatingPointType opacity );
/**
* Copy constructor
*/
Material( const Material& property );
/**
* Copy constructor, provided for convinience. The values are copied from property
* and afterwards the values provided for red green blue and opacity are written into the object.
*/
Material( const Material& property, vtkFloatingPointType red, vtkFloatingPointType green, vtkFloatingPointType blue, vtkFloatingPointType opacity = 1.0, std::string name = "");
virtual void InitializeStandardValues();
virtual void Update();
std::string m_Name;
Color m_Color;
Color m_SpecularColor;
vtkFloatingPointType m_ColorCoefficient;
vtkFloatingPointType m_SpecularCoefficient;
vtkFloatingPointType m_SpecularPower;
vtkFloatingPointType m_Opacity;
float m_LineWidth;
InterpolationType m_Interpolation;
RepresentationType m_Representation;
};
typedef itk::VectorContainer< unsigned int, Material::Pointer > MaterialVectorContainer;
}
#endif
diff --git a/Core/Code/DataManagement/mitkMatrixConvert.h b/Core/Code/DataManagement/mitkMatrixConvert.h
index 7123b09095..9b2c07d78e 100644
--- a/Core/Code/DataManagement/mitkMatrixConvert.h
+++ b/Core/Code/DataManagement/mitkMatrixConvert.h
@@ -1,150 +1,149 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKMATRIXCONVERT_H_HEADER_INCLUDED_C1EBD0AD
#define MITKMATRIXCONVERT_H_HEADER_INCLUDED_C1EBD0AD
#include "mitkGeometry3D.h"
#include "mitkItkMatrixHack.h"
#include <vtkMatrix4x4.h>
namespace mitk
{
template <class TTransformType>
void TransferVtkMatrixToItkTransform(const vtkMatrix4x4* vtkmatrix, TTransformType * itkTransform)
{
if(itkTransform==NULL)
return;
typename TTransformType::MatrixType::InternalMatrixType& vnlMatrix =
const_cast<typename TTransformType::MatrixType::InternalMatrixType&>(itkTransform->GetMatrix().GetVnlMatrix());
for ( int i=0; i < 3; ++i)
for( int j=0; j < 3; ++j )
vnlMatrix[i][j] = vtkmatrix->GetElement( i, j );
// *This* ensures m_MatrixMTime.Modified(), which is therewith not equal to
// m_InverseMatrixMTime, thus a new inverse will be calculated (when
// requested).
static_cast<mitk::ItkMatrixHack<TTransformType>*>(itkTransform)->MatrixChanged();
typename TTransformType::OffsetType offset;
offset[0] = vtkmatrix->GetElement( 0, 3 );
offset[1] = vtkmatrix->GetElement( 1, 3 );
offset[2] = vtkmatrix->GetElement( 2, 3 );
itkTransform->SetOffset( offset );
}
template <class TTransformType>
void TransferItkTransformToVtkMatrix(const TTransformType * itkTransform, vtkMatrix4x4* vtkmatrix)
{
int i,j;
for(i=0;i<3;++i)
for(j=0;j<3;++j)
vtkmatrix->SetElement(i, j, itkTransform->GetMatrix().GetVnlMatrix().get(i, j));
for(i=0;i<3;++i)
vtkmatrix->SetElement(i, 3, itkTransform->GetOffset()[i]);
vtkmatrix->Modified();
}
template <class TTransformType1, class TTransformType2>
void ConvertItkTransform(const TTransformType1* sourceTransform, TTransformType2* destTransform)
{
if((sourceTransform==NULL) || (destTransform==NULL))
return;
// transfer offset
const typename TTransformType1::OutputVectorType& sourceOffset =
sourceTransform->GetOffset();
typename TTransformType2::OutputVectorType offset;
offset[0] = sourceOffset[0]; offset[1] = sourceOffset[1]; offset[2] = sourceOffset[2];
destTransform->SetOffset( offset );
typename TTransformType1::MatrixType::InternalMatrixType& sourceVnlMatrix =
const_cast<typename TTransformType1::MatrixType::InternalMatrixType&>(sourceTransform->GetMatrix().GetVnlMatrix());
//transfer matrix
typename TTransformType2::MatrixType::InternalMatrixType& destVnlMatrix =
const_cast<typename TTransformType2::MatrixType::InternalMatrixType&>(destTransform->GetMatrix().GetVnlMatrix());
for ( int i=0; i < 3; ++i)
for( int j=0; j < 3; ++j )
destVnlMatrix[i][j] = sourceVnlMatrix[i][j];
// *This* ensures m_MatrixMTime.Modified(), which is therewith not equal to
// m_InverseMatrixMTime, thus a new inverse will be calculated (when
// requested).
static_cast<mitk::ItkMatrixHack<TTransformType2>*>(destTransform)->MatrixChanged();
}
template <class TMatrixType>
void GetRotation(const mitk::Geometry3D * geometry, TMatrixType& itkmatrix)
{
const mitk::Vector3D& spacing = geometry->GetSpacing();
typename mitk::Geometry3D::TransformType::MatrixType::InternalMatrixType& geometryVnlMatrix =
const_cast<typename mitk::Geometry3D::TransformType::MatrixType::InternalMatrixType&>(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix());
typename TMatrixType::InternalMatrixType& outputVnlMatrix =
const_cast<typename TMatrixType::InternalMatrixType&>(itkmatrix.GetVnlMatrix());
for ( int i=0; i < 3; ++i)
for( int j=0; j < 3; ++j )
outputVnlMatrix [i][j] = geometryVnlMatrix [i][j] / spacing[j];
}
template <class TTransformType>
void GetWorldToItkPhysicalTransform(const mitk::Geometry3D * geometry, TTransformType* itkTransform)
{
if(itkTransform==NULL)
return;
// get rotation matrix and offset from Geometry and transfer in TTransformType types
typename TTransformType::MatrixType rotationMatrix;
GetRotation(geometry, rotationMatrix);
const typename mitk::Geometry3D::TransformType::OffsetType& geometryOffset =
geometry->GetIndexToWorldTransform()->GetOffset();
vnl_vector<typename TTransformType::MatrixType::ValueType> vnlOffset(3);
vnlOffset[0] = geometryOffset[0]; vnlOffset[1] = geometryOffset[1]; vnlOffset[2] = geometryOffset[2];
// do calculations
typename TTransformType::MatrixType::InternalMatrixType inverseRotationVnlMatrix = rotationMatrix.GetTranspose();
vnlOffset -= inverseRotationVnlMatrix*vnlOffset;
typename TTransformType::OutputVectorType offset;//vnl_vector<TTransformType::MatrixType::ValueType> offset;
offset[0] = vnlOffset[0]; offset[1] = vnlOffset[1]; offset[2] = vnlOffset[2];
itkTransform->SetOffset( offset );
// copy in destination itkTransform
typename TTransformType::MatrixType::InternalMatrixType& destVnlMatrix =
const_cast<typename TTransformType::MatrixType::InternalMatrixType&>(itkTransform->GetMatrix().GetVnlMatrix());
for ( int i=0; i < 3; ++i)
for( int j=0; j < 3; ++j )
destVnlMatrix[i][j] = inverseRotationVnlMatrix[i][j];
// *This* ensures m_MatrixMTime.Modified(), which is therewith not equal to
// m_InverseMatrixMTime, thus a new inverse will be calculated (when
// requested).
static_cast<mitk::ItkMatrixHack<TTransformType>*>(itkTransform)->MatrixChanged();
}
}
#endif /* MITKMATRIXCONVERT_H_HEADER_INCLUDED_C1EBD0AD */
diff --git a/Core/Code/DataManagement/mitkMemoryUtilities.cpp b/Core/Code/DataManagement/mitkMemoryUtilities.cpp
index c07797d329..3e222a4194 100755
--- a/Core/Code/DataManagement/mitkMemoryUtilities.cpp
+++ b/Core/Code/DataManagement/mitkMemoryUtilities.cpp
@@ -1,120 +1,119 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkMemoryUtilities.h"
#include <stdio.h>
#if _MSC_VER || __MINGW32__
#include <windows.h>
#include <psapi.h>
#elif defined(__APPLE__)
#include <mach/task.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#else
#include <sys/sysinfo.h>
#include <unistd.h>
#endif
/**
* Returns the memory usage of the current process in bytes.
* On linux, this refers to the virtual memory allocated by
* the process (the VIRT column in top).
* On windows, this refery to the size in bytes of the working
* set pages (the "Speicherauslastung" column in the task manager).
*/
size_t mitk::MemoryUtilities::GetProcessMemoryUsage()
{
#if _MSC_VER || __MINGW32__
size_t size = 0;
DWORD pid = GetCurrentProcessId();
PROCESS_MEMORY_COUNTERS pmc;
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
if ( hProcess == NULL )
return 0;
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
size = pmc.WorkingSetSize;
}
CloseHandle( hProcess );
return size;
#elif defined(__APPLE__)
struct task_basic_info t_info;
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
task_info(current_task(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
size_t size = t_info.virtual_size;
return size;
#else
int size, res, shared, text, sharedLibs, stack, dirtyPages;
if ( ! ReadStatmFromProcFS( &size, &res, &shared, &text, &sharedLibs, &stack, &dirtyPages ) )
return (size_t) size * getpagesize();
else
return 0;
#endif
return 0;
}
/**
* Returns the total size of phyiscal memory in bytes
*/
size_t mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam()
{
#if _MSC_VER || __MINGW32__
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return (size_t) statex.ullTotalPhys;
#elif defined(__APPLE__)
kern_return_t kr;
host_basic_info_data_t hostinfo;
int count = HOST_BASIC_INFO_COUNT;
kr = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostinfo, (mach_msg_type_number_t*)&count);
if(kr == KERN_SUCCESS)
return (size_t)hostinfo.memory_size;
else
return 0;
#else
struct sysinfo info;
if ( ! sysinfo( &info ) )
return info.totalram * info.mem_unit;
else
return 0;
#endif
}
#ifndef _MSC_VER
#ifndef __APPLE__
int mitk::MemoryUtilities::ReadStatmFromProcFS( int* size, int* res, int* shared, int* text, int* sharedLibs, int* stack, int* dirtyPages )
{
int ret = 0;
FILE* f;
f = fopen( "/proc/self/statm", "r" );
if( f ) {
size_t ignored = fscanf( f, "%d %d %d %d %d %d %d", size, res, shared, text, sharedLibs, stack, dirtyPages );
++ignored;
fclose( f );
} else {
ret = -1;
}
return ret;
}
#endif
#endif
diff --git a/Core/Code/DataManagement/mitkMemoryUtilities.h b/Core/Code/DataManagement/mitkMemoryUtilities.h
index 081c478bee..10a654779f 100644
--- a/Core/Code/DataManagement/mitkMemoryUtilities.h
+++ b/Core/Code/DataManagement/mitkMemoryUtilities.h
@@ -1,99 +1,98 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 _MITK_MEMORY_UTILITIES_H_
#define _MITK_MEMORY_UTILITIES_H_
#include <itkMacro.h>
#include <itkExceptionObject.h>
#include <MitkExports.h>
namespace mitk
{
class MITK_CORE_EXPORT MemoryUtilities
{
public:
/**
* Returns the memory usage of the current process in bytes.
* On linux, this refers to the virtual memory allocated by
* the process (the VIRT column in top).
* On windows, this refery to the size in bytes of the working
* set pages (the "Speicherauslastung" column in the task manager).
*/
static size_t GetProcessMemoryUsage();
/**
* Returns the total size of phyiscal memory in bytes
*/
static size_t GetTotalSizeOfPhysicalRam();
/**
* Allocates an array of a given number of elements. Each element
* has a size of sizeof(ElementType). The function returns NULL, if the array
* could not be allocated.
* @param numberOfElements the number of elements of the array
* @param noThrow if set to false, an exception is thrown if memory allocation
* fails. If set to true, a itk::MemoryAllocationError is thrown
* @returns a pointer to the allocated array. If noThrow == true, NULL is returned
* if memory allocation failed.
*/
template <typename ElementType>
static ElementType* AllocateElements(size_t numberOfElements, bool noThrow = false )
{
// Encapsulate all image memory allocation here to throw an
// exception when memory allocation fails even when the compiler
// does not do this by default.
ElementType* data = NULL;
try
{
data = new ElementType[numberOfElements];
}
catch(...)
{
data = NULL;
}
if( ( data == NULL ) && ( noThrow == false ) )
{
throw itk::MemoryAllocationError(__FILE__, __LINE__, "Failed to allocate memory.", ITK_LOCATION);
}
return data;
}
/**
* Deletes an array of elements previously allocated by AllocateElements.
* @param elements the array to delete. Not that NULL is an accepted value.
*/
template <typename ElementType>
static void DeleteElements(ElementType* elements)
{
if ( elements != NULL )
{
delete[] elements;
}
}
protected:
#ifndef _MSC_VER
static int ReadStatmFromProcFS( int* size, int* res, int* shared, int* text, int* sharedLibs, int* stack, int* dirtyPages );
#endif
};
} //end of namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkModalityProperty.cpp b/Core/Code/DataManagement/mitkModalityProperty.cpp
index bdbae6bd48..26c91b7a06 100644
--- a/Core/Code/DataManagement/mitkModalityProperty.cpp
+++ b/Core/Code/DataManagement/mitkModalityProperty.cpp
@@ -1,71 +1,70 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-02-17 13:14:37 +0100 (Di, 17 Feb 2009) $
-Version: $Revision: 16318 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkModalityProperty.h"
mitk::ModalityProperty::ModalityProperty()
{
AddEnumerationTypes();
}
mitk::ModalityProperty::ModalityProperty( const IdType& value )
{
AddEnumerationTypes();
if ( IsValidEnumerationValue( value ) )
{
SetValue( value ) ;
}
else
{
SetValue( 0 );
}
}
mitk::ModalityProperty::ModalityProperty( const std::string& value )
{
AddEnumerationTypes();
if ( IsValidEnumerationValue( value ) )
{
SetValue( value );
}
else
{
SetValue( "undefined" );
}
}
mitk::ModalityProperty::~ModalityProperty()
{
}
void mitk::ModalityProperty::AddEnumerationTypes()
{
IdType newId = static_cast<IdType>(EnumerationProperty::Size());
AddEnum( "undefined", newId++ );
AddEnum( "CR", newId++ ); // computer radiography
AddEnum( "CT", newId++ ); // computed tomography
AddEnum( "MR", newId++ ); // magnetic resonance
AddEnum( "NM", newId++ ); // nuclear medicine
AddEnum( "US", newId++ ); // ultrasound
AddEnum( "Color Doppler", newId++ ); // ultrasound
AddEnum( "Power Doppler", newId++ ); // ultrasound
}
diff --git a/Core/Code/DataManagement/mitkModalityProperty.h b/Core/Code/DataManagement/mitkModalityProperty.h
index 2f6279939f..2140df279e 100644
--- a/Core/Code/DataManagement/mitkModalityProperty.h
+++ b/Core/Code/DataManagement/mitkModalityProperty.h
@@ -1,72 +1,71 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-15 10:46:54 +0200 (Fr, 15 Mai 2009) $
-Version: $Revision: 17272 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 mitkModalityProperty_h_Included
#define mitkModalityProperty_h_Included
#include <MitkExports.h>
#include "mitkEnumerationProperty.h"
#include <itkObjectFactory.h>
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
\brief Enumerates all known modalities
\ingroup DataManagement
*/
class MITK_CORE_EXPORT ModalityProperty : public EnumerationProperty
{
public:
mitkClassMacro(ModalityProperty, EnumerationProperty);
itkNewMacro(ModalityProperty);
mitkNewMacro1Param(ModalityProperty, const IdType&);
mitkNewMacro1Param(ModalityProperty, const std::string&);
using BaseProperty::operator=;
protected:
ModalityProperty();
ModalityProperty( const IdType& value );
ModalityProperty( const std::string& value );
virtual ~ModalityProperty();
virtual void AddEnumerationTypes();
private:
// purposely not implemented
ModalityProperty(const ModalityProperty&);
const ModalityProperty& operator=(const ModalityProperty&);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace
#endif
diff --git a/Core/Code/DataManagement/mitkModeOperation.cpp b/Core/Code/DataManagement/mitkModeOperation.cpp
index ddb212aa46..c7b084b547 100644
--- a/Core/Code/DataManagement/mitkModeOperation.cpp
+++ b/Core/Code/DataManagement/mitkModeOperation.cpp
@@ -1,34 +1,33 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkModeOperation.h"
#include <mitkOperation.h>
mitk::ModeOperation::ModeOperation(mitk::OperationType operationType, mitk::ModeOperation::ModeType mode)
: Operation(operationType), m_Mode(mode)
{
}
mitk::ModeOperation::~ModeOperation()
{
}
mitk::ModeOperation::ModeType mitk::ModeOperation::GetMode()
{
return m_Mode;
}
diff --git a/Core/Code/DataManagement/mitkModeOperation.h b/Core/Code/DataManagement/mitkModeOperation.h
index d869c53bd5..529e7f18b4 100644
--- a/Core/Code/DataManagement/mitkModeOperation.h
+++ b/Core/Code/DataManagement/mitkModeOperation.h
@@ -1,52 +1,51 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MODEOPERATION_H_HEADER_INCLUDED
#define MODEOPERATION_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkOperation.h"
#include <mitkInteractor.h>
namespace mitk {
// class Operation;
//##Documentation
//## @brief class that holds the information for a change of the modus of an interactor object
//##
//## @ingroup Undo
class MITK_CORE_EXPORT ModeOperation : public Operation
{
public:
typedef Interactor::ModeType ModeType;
mitkClassMacro(ModeOperation, Operation);
//##Documentation
//## Constructor
ModeOperation(OperationType operationType, ModeType mode);
virtual ~ModeOperation();
ModeType GetMode();
protected:
ModeType m_Mode;
};
}//namespace mitk
#endif /* MODEOPERATION_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkNodePredicateAnd.cpp b/Core/Code/DataManagement/mitkNodePredicateAnd.cpp
index b8ddbbe233..a1dbc81906 100644
--- a/Core/Code/DataManagement/mitkNodePredicateAnd.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateAnd.cpp
@@ -1,62 +1,61 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateAnd.h"
mitk::NodePredicateAnd::NodePredicateAnd()
: NodePredicateCompositeBase()
{
}
mitk::NodePredicateAnd::NodePredicateAnd(const NodePredicateBase* p1, const NodePredicateBase* p2)
: NodePredicateCompositeBase()
{
this->AddPredicate(p1);
this->AddPredicate(p2);
}
mitk::NodePredicateAnd::NodePredicateAnd(const NodePredicateBase* p1, const NodePredicateBase* p2, const NodePredicateBase* p3)
: NodePredicateCompositeBase()
{
this->AddPredicate(p1);
this->AddPredicate(p2);
this->AddPredicate(p3);
}
mitk::NodePredicateAnd::~NodePredicateAnd()
{
}
bool mitk::NodePredicateAnd::CheckNode(const mitk::DataNode* node) const
{
if (m_ChildPredicates.empty())
throw std::invalid_argument("NodePredicateAnd: no child predicates available");
if (node == NULL)
throw std::invalid_argument("NodePredicateAnd: invalid node");
// return the conjunction of the child predicate. If any predicate returns false, we return false too
for (ChildPredicates::const_iterator it = m_ChildPredicates.begin(); ( it != m_ChildPredicates.end() ); ++it)
if ((*it)->CheckNode(node) == false)
return false; // if one element of the conjunction is false, the whole conjunction gets false
return true; // none of the childs was false, so return true
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateAnd.h b/Core/Code/DataManagement/mitkNodePredicateAnd.h
index d6778b01e1..dc9eed9b14 100644
--- a/Core/Code/DataManagement/mitkNodePredicateAnd.h
+++ b/Core/Code/DataManagement/mitkNodePredicateAnd.h
@@ -1,68 +1,67 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATEAND_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEAND_H_HEADER_INCLUDED_
#include "mitkNodePredicateCompositeBase.h"
namespace mitk {
//##Documentation
//## @brief Composite predicate that forms a logical AND relation from its child predicates
//##
//##
//##
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateAnd : public NodePredicateCompositeBase
{
public:
mitkClassMacro(NodePredicateAnd, NodePredicateCompositeBase);
itkFactorylessNewMacro(NodePredicateAnd);
mitkNewMacro2Param(NodePredicateAnd, const NodePredicateBase*, const NodePredicateBase*);
mitkNewMacro3Param(NodePredicateAnd, const NodePredicateBase*, const NodePredicateBase*, const NodePredicateBase*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateAnd();
//##Documentation
//## @brief Checks, if the node fulfills all of the subpredicates conditions
virtual bool CheckNode(const DataNode* node) const;
protected:
//##Documentation
//## @brief Protected constructor, use static instantiation functions instead
NodePredicateAnd();
//##Documentation
//## @brief Convenience constructor that adds p1 and p2 to list of child predicates
//## Protected constructor, use static instantiation functions instead
NodePredicateAnd(const NodePredicateBase* p1, const NodePredicateBase* p2);
//##Documentation
//## @brief Convenience constructor that adds p1, p2 and p3 to list of child predicates
//## Protected constructor, use static instantiation functions instead
NodePredicateAnd(const NodePredicateBase* p1, const NodePredicateBase* p2, const NodePredicateBase* p3);
};
} // namespace mitk
#endif /* MITKNODEPREDICATEAND_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateBase.cpp b/Core/Code/DataManagement/mitkNodePredicateBase.cpp
index 57ba66db88..d4d5d8f490 100644
--- a/Core/Code/DataManagement/mitkNodePredicateBase.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateBase.cpp
@@ -1,23 +1,22 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateBase.h"
mitk::NodePredicateBase::~NodePredicateBase()
{
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateBase.h b/Core/Code/DataManagement/mitkNodePredicateBase.h
index 953fac6f9e..c7bebe270e 100644
--- a/Core/Code/DataManagement/mitkNodePredicateBase.h
+++ b/Core/Code/DataManagement/mitkNodePredicateBase.h
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATEBASE_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEBASE_H_HEADER_INCLUDED_
#include <MitkExports.h>
#include <mitkCommon.h>
#include "itkObject.h"
namespace mitk {
class DataNode;
//##Documentation
//## @brief Interface for evaluation conditions used in the DataStorage class GetSubset() method
//##
//## Classes that inherit this interface can be used as predicates in the GetSubset() method
//## of mitk::DataStorage. By combining different predicate objects, the user can form complex
//## queries like "give me all nodes that either contain a surface object or a binary segmentation
//## and that are tagged as Organtype == 'Liver'".
//## @warning NodePredicates are now derived from itk::Object and make thus use of the smart pointer concept.
//## As a result predicates should only store raw pointers because for one thing they are not owners
//## of these objects and should not keep them alive.
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateBase: public itk::Object
{
public:
mitkClassMacro(NodePredicateBase,itk::Object);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateBase();
//##Documentation
//## @brief This method will be used to evaluate the node. Has to be overwritten in subclasses
virtual bool CheckNode(const mitk::DataNode* node) const = 0;
};
} // namespace mitk
#endif /* MITKNODEPREDICATEBASE_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateCompositeBase.cpp b/Core/Code/DataManagement/mitkNodePredicateCompositeBase.cpp
index 81b3f098fb..5a84586bac 100644
--- a/Core/Code/DataManagement/mitkNodePredicateCompositeBase.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateCompositeBase.cpp
@@ -1,40 +1,39 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateCompositeBase.h"
// for std::find
#include <algorithm>
mitk::NodePredicateCompositeBase::~NodePredicateCompositeBase()
{
}
void mitk::NodePredicateCompositeBase::AddPredicate( const NodePredicateBase* p )
{
m_ChildPredicates.push_back(p);
}
void mitk::NodePredicateCompositeBase::RemovePredicate( const NodePredicateBase* p )
{
m_ChildPredicates.remove(p);
}
mitk::NodePredicateCompositeBase::ChildPredicates mitk::NodePredicateCompositeBase::GetPredicates() const
{
return m_ChildPredicates;
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateCompositeBase.h b/Core/Code/DataManagement/mitkNodePredicateCompositeBase.h
index 563b76b113..fd0ca5d919 100644
--- a/Core/Code/DataManagement/mitkNodePredicateCompositeBase.h
+++ b/Core/Code/DataManagement/mitkNodePredicateCompositeBase.h
@@ -1,66 +1,65 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATECOMPOSITEBASE_H_HEADER_INCLUDED_
#define MITKNODEPREDICATECOMPOSITEBASE_H_HEADER_INCLUDED_
#include "mitkNodePredicateBase.h"
#include <list>
namespace mitk {
//##Documentation
//## @brief Base class for all predicates that can have child predicates (e.g. AND/OR)
//##
//## This class provides methods to add and remove child predicates. It is used for
//## predicates that are compositions of other predicates like AND and OR.
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateCompositeBase : public NodePredicateBase
{
public:
mitkClassMacro(NodePredicateCompositeBase, NodePredicateBase);
typedef std::list<NodePredicateBase::ConstPointer> ChildPredicates;
//##Documentation
//## @brief Pure virtual (but implemented) Destructor makes NodePredicateCompositeBase an abstract class
virtual ~NodePredicateCompositeBase() = 0;
//##Documentation
//## @brief Adds a child predicate
virtual void AddPredicate(const NodePredicateBase* p);
//##Documentation
//## @brief Removes a child predicate
virtual void RemovePredicate(const NodePredicateBase* p);
//##Documentation
//## @brief Return all child predicates (immutable).
virtual ChildPredicates GetPredicates() const;
protected:
//##Documentation
//## @brief list of child predicates
ChildPredicates m_ChildPredicates;
};
} // namespace mitk
#endif /* MITKNODEPREDICATECOMPOSITEBASE_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateData.cpp b/Core/Code/DataManagement/mitkNodePredicateData.cpp
index 8041042091..30d3d1a414 100644
--- a/Core/Code/DataManagement/mitkNodePredicateData.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateData.cpp
@@ -1,41 +1,40 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateData.h"
#include "mitkDataNode.h"
mitk::NodePredicateData::NodePredicateData(mitk::BaseData* d)
: NodePredicateBase()
{
m_DataObject = d;
}
mitk::NodePredicateData::~NodePredicateData()
{
}
bool mitk::NodePredicateData::CheckNode(const mitk::DataNode* node) const
{
if (node == NULL)
throw std::invalid_argument("NodePredicateData: invalid node");
return (node->GetData() == m_DataObject);
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateData.h b/Core/Code/DataManagement/mitkNodePredicateData.h
index a7b647c808..48cf18d65f 100644
--- a/Core/Code/DataManagement/mitkNodePredicateData.h
+++ b/Core/Code/DataManagement/mitkNodePredicateData.h
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATEDATA_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEDATA_H_HEADER_INCLUDED_
#include "mitkNodePredicateBase.h"
namespace mitk {
class BaseData;
//##Documentation
//## @brief Predicate that evaluates if the given DataNodes data object pointer equals a given pointer
//##
//## NodePredicateData(NULL) returns true if a DataNode does not have a data object (e.g. ->GetData() returns NULL).
//## This could return an unexpected number of nodes (e.g. the root node of the tree)
//## @warning NodePredicateData holds a weak pointer to a BaseData! NodePredicateData p(mitk::BaseData::New()); will not work.
//## Intended use is: NodePredicateData p(myDataObject); result = myDataStorage->GetSubset(p); Then work with result, do not reuse p later.
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateData : public NodePredicateBase
{
public:
mitkClassMacro(NodePredicateData, NodePredicateBase);
mitkNewMacro1Param(NodePredicateData, mitk::BaseData*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateData();
//##Documentation
//## @brief Checks, if the nodes data object is of a specific data type
virtual bool CheckNode(const mitk::DataNode* node) const;
protected:
//##Documentation
//## @brief Protected constructor, use static instantiation functions instead
NodePredicateData(mitk::BaseData* d);
mitk::BaseData* m_DataObject;
};
} // namespace mitk
#endif /* MITKNODEPREDICATEDATA_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateDataType.cpp b/Core/Code/DataManagement/mitkNodePredicateDataType.cpp
index 8a143a019b..0e770091c0 100644
--- a/Core/Code/DataManagement/mitkNodePredicateDataType.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateDataType.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateDataType.h"
#include "mitkDataNode.h"
#include "mitkBaseData.h"
mitk::NodePredicateDataType::NodePredicateDataType(const char* datatype)
: NodePredicateBase()
{
if (datatype == NULL)
throw std::invalid_argument("NodePredicateDataType: invalid datatype");
m_ValidDataType = datatype;
}
mitk::NodePredicateDataType::~NodePredicateDataType()
{
}
bool mitk::NodePredicateDataType::CheckNode(const mitk::DataNode* node) const
{
if (node == NULL)
throw std::invalid_argument("NodePredicateDataType: invalid node");
mitk::BaseData* data = node->GetData();
if (data == NULL)
return false; // or should we check if m_ValidDataType == "NULL" so that nodes without data can be requested?
return ( m_ValidDataType.compare(data->GetNameOfClass()) == 0); // return true if data type matches
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateDataType.h b/Core/Code/DataManagement/mitkNodePredicateDataType.h
index 6b22aa6adb..4f25ab191e 100644
--- a/Core/Code/DataManagement/mitkNodePredicateDataType.h
+++ b/Core/Code/DataManagement/mitkNodePredicateDataType.h
@@ -1,93 +1,92 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATEDATATYPE_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEDATATYPE_H_HEADER_INCLUDED_
#include "mitkNodePredicateBase.h"
#include "mitkDataNode.h"
#include <string>
namespace mitk {
//##Documentation
//## @brief Predicate that evaluates if the given DataNodes data object is of a specific data type
//##
//## The data type must be specified in the constructor as a string. The string must equal the result
//## value of the requested data types GetNameOfClass() method.
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateDataType : public NodePredicateBase
{
public:
mitkClassMacro(NodePredicateDataType, NodePredicateBase);
mitkNewMacro1Param(NodePredicateDataType, const char*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateDataType();
//##Documentation
//## @brief Checks, if the nodes data object is of a specific data type
virtual bool CheckNode(const mitk::DataNode* node) const;
protected:
//##Documentation
//## @brief Protected constructor, use static instantiation functions instead
NodePredicateDataType(const char* datatype);
std::string m_ValidDataType;
};
/**
* \brief Tests for type compatibility (dynamic_cast).
*
* In contrast to NodePredicateDataType this class also accepts derived types.
* E.g. if you query for type BaseData, you will also get Image and Surface objects.
*
* The desired type is given as a template parameter, the constructor takes no other parameters.
*/
template <class T>
class TNodePredicateDataType : public NodePredicateBase
{
public:
mitkClassMacro(TNodePredicateDataType, NodePredicateBase);
itkFactorylessNewMacro(TNodePredicateDataType);
virtual ~TNodePredicateDataType()
{
}
//##Documentation
//## @brief Checks, if the nodes data object is of a specific data type (casts)
virtual bool CheckNode(const mitk::DataNode* node) const
{
return node && node->GetData() && dynamic_cast<T*>(node->GetData());
}
protected:
//##Documentation
//## @brief Protected constructor, use static instantiation functions instead
TNodePredicateDataType()
{
}
};
} // namespace mitk
#endif /* MITKNODEPREDICATEDATATYPE_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateDimension.cpp b/Core/Code/DataManagement/mitkNodePredicateDimension.cpp
index 3935dd536e..f2a6dda1ae 100644
--- a/Core/Code/DataManagement/mitkNodePredicateDimension.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateDimension.cpp
@@ -1,54 +1,53 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 11215 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateDimension.h"
#include "mitkDataNode.h"
mitk::NodePredicateDimension::NodePredicateDimension(unsigned int dimension, int pixelComponents)
: m_Dimension( dimension ),
m_PixelComponents( pixelComponents )
{
}
mitk::NodePredicateDimension::NodePredicateDimension( unsigned int dimension )
: m_Dimension( dimension ),
m_PixelComponents(1)
{
}
mitk::NodePredicateDimension::~NodePredicateDimension()
{
}
bool mitk::NodePredicateDimension::CheckNode(const mitk::DataNode* node) const
{
if (node == NULL)
throw std::invalid_argument("NodePredicateDimension: invalid node");
mitk::Image *image = dynamic_cast<mitk::Image *>( node->GetData() );
if (image != NULL)
{
return (image->GetDimension() == m_Dimension && image->GetPixelType().GetNumberOfComponents() == m_PixelComponents);
}
return false;
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateDimension.h b/Core/Code/DataManagement/mitkNodePredicateDimension.h
index 0be7f1406f..48dbe992ad 100644
--- a/Core/Code/DataManagement/mitkNodePredicateDimension.h
+++ b/Core/Code/DataManagement/mitkNodePredicateDimension.h
@@ -1,65 +1,64 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 11215 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATEDIMENSION_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEDIMENSION_H_HEADER_INCLUDED_
#include "mitkNodePredicateBase.h"
namespace mitk {
class BaseData;
//##Documentation
//## @brief Predicate that evaluates if the given DataNodes data object
//## has the specified dimension, for datasets where dimension is
//## applicable.
//##
//## Evaluates to "false" for unsupported datasets.
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateDimension : public NodePredicateBase
{
public:
mitkClassMacro(NodePredicateDimension, NodePredicateBase);
mitkNewMacro1Param(NodePredicateDimension, unsigned int);
mitkNewMacro2Param(NodePredicateDimension, unsigned int, int);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateDimension();
//##Documentation
//## @brief Checks if the nodes data object is of the specified dimension
virtual bool CheckNode(const mitk::DataNode* node) const;
protected:
//##Documentation
//## @brief Standard Constructor
NodePredicateDimension(unsigned int dimension);
//##Documentation
//## @brief Standard Constructor
NodePredicateDimension(unsigned int dimension, int pixelComponents);
unsigned int m_Dimension;
std::size_t m_PixelComponents;
};
} // namespace mitk
#endif /* MITKNodePredicateDimension_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateFirstLevel.cpp b/Core/Code/DataManagement/mitkNodePredicateFirstLevel.cpp
index e228751ad5..bef0340585 100644
--- a/Core/Code/DataManagement/mitkNodePredicateFirstLevel.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateFirstLevel.cpp
@@ -1,41 +1,40 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $
-Version: $Revision: 13129 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateFirstLevel.h"
mitk::NodePredicateFirstLevel::NodePredicateFirstLevel(mitk::DataStorage* ds)
: NodePredicateBase(), m_DataStorage(ds)
{
}
mitk::NodePredicateFirstLevel::~NodePredicateFirstLevel()
{
}
bool mitk::NodePredicateFirstLevel::CheckNode(const mitk::DataNode* node) const
{
if (node == NULL)
throw std::invalid_argument("NodePredicateFirstLevel: invalid node");
if(m_DataStorage.IsNull())
throw std::invalid_argument("NodePredicateFirstLevel: DataStorage is invalid");
mitk::DataStorage::SetOfObjects::ConstPointer list = m_DataStorage->GetSources(node, NULL, true);
return (list->Size() == 0);
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateFirstLevel.h b/Core/Code/DataManagement/mitkNodePredicateFirstLevel.h
index b281f9b207..bfde642deb 100644
--- a/Core/Code/DataManagement/mitkNodePredicateFirstLevel.h
+++ b/Core/Code/DataManagement/mitkNodePredicateFirstLevel.h
@@ -1,61 +1,60 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-08 13:23:19 +0100 (Fr, 08 Feb 2008) $
-Version: $Revision: 13561 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATEFIRSTLEVEL_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEFIRSTLEVEL_H_HEADER_INCLUDED_
#include "mitkNodePredicateBase.h"
#include "mitkDataStorage.h"
#include "mitkDataNode.h"
#include "mitkWeakPointer.h"
namespace mitk {
//##Documentation
//## @brief Predicate that evaluates if the given node is a direct or indirect source node of a specific node
//##
//## @warning This class seems to be obsolete since mitk::DataStorage::GetDerivations().
//## Since there is no real use case up until now, NodePredicateSource is NOT WORKING YET.
//## If you need it working, inform us.
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateFirstLevel : public NodePredicateBase
{
public:
mitkClassMacro(NodePredicateFirstLevel, NodePredicateBase);
mitkNewMacro1Param(NodePredicateFirstLevel, mitk::DataStorage*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateFirstLevel();
//##Documentation
//## @brief Checks, if the node is a source node of m_BaseNode (e.g. if m_BaseNode "was created from" node)
virtual bool CheckNode(const mitk::DataNode* node) const;
protected:
//##Documentation
//## @brief Constructor - This class can either search only for direct source objects or for all source objects
NodePredicateFirstLevel(mitk::DataStorage* ds);
mitk::WeakPointer<mitk::DataStorage> m_DataStorage;
};
} // namespace mitk
#endif /* MITKNODEPREDICATEFIRSTLEVEL_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateNot.cpp b/Core/Code/DataManagement/mitkNodePredicateNot.cpp
index 7aee3f47f8..64356b7a64 100644
--- a/Core/Code/DataManagement/mitkNodePredicateNot.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateNot.cpp
@@ -1,46 +1,45 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateNot.h"
mitk::NodePredicateNot::NodePredicateNot(const mitk::NodePredicateBase* p)
{
m_ChildPredicates.push_back(p);
}
mitk::NodePredicateNot::~NodePredicateNot()
{
}
bool mitk::NodePredicateNot::CheckNode(const mitk::DataNode* node) const
{
if (node == NULL)
throw std::invalid_argument("NodePredicateNot: invalid node");
// return the negation of the child predicate
return !m_ChildPredicates.front()->CheckNode(node);
}
void mitk::NodePredicateNot::AddPredicate( const mitk::NodePredicateBase* p )
{
if(!m_ChildPredicates.empty())
m_ChildPredicates.clear();
NodePredicateCompositeBase::AddPredicate(p);
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateNot.h b/Core/Code/DataManagement/mitkNodePredicateNot.h
index a451069e8b..23889cb293 100644
--- a/Core/Code/DataManagement/mitkNodePredicateNot.h
+++ b/Core/Code/DataManagement/mitkNodePredicateNot.h
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATENOT_H_HEADER_INCLUDED_
#define MITKNODEPREDICATENOT_H_HEADER_INCLUDED_
#include "mitkNodePredicateCompositeBase.h"
namespace mitk {
//##Documentation
//## @brief Composite predicate that negates its child predicate
//## Changed: NodePredicateNot now derives from NodePredicateCompositeBase though it really holds
//## only one subpredicate at any time. But logically any Predicate that has one or more subpredicate
//## is a CompositePredicate.
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateNot : public mitk::NodePredicateCompositeBase
{
public:
mitkClassMacro(NodePredicateNot, NodePredicateCompositeBase);
mitkNewMacro1Param(NodePredicateNot, const mitk::NodePredicateBase*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateNot();
//##Documentation
//## @brief Reimplemented, only one child predicate is allowed for the NOT predicate.
virtual void AddPredicate(const mitk::NodePredicateBase* p);
//##Documentation
//## @brief Checks, if the node does not fulfill the child predicate condition
virtual bool CheckNode(const mitk::DataNode* node) const;
protected:
//##Documentation
//## @brief Constructor
NodePredicateNot(const mitk::NodePredicateBase* p);
};
} // namespace mitk
#endif /* MITKNODEPREDICATENOT_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateOr.cpp b/Core/Code/DataManagement/mitkNodePredicateOr.cpp
index e9c53df438..ed07984b87 100644
--- a/Core/Code/DataManagement/mitkNodePredicateOr.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateOr.cpp
@@ -1,53 +1,52 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateOr.h"
mitk::NodePredicateOr::NodePredicateOr()
: NodePredicateCompositeBase()
{
}
mitk::NodePredicateOr::NodePredicateOr(const NodePredicateBase* p1, const NodePredicateBase* p2)
: NodePredicateCompositeBase()
{
this->AddPredicate(p1);
this->AddPredicate(p2);
}
mitk::NodePredicateOr::~NodePredicateOr()
{
}
bool mitk::NodePredicateOr::CheckNode(const DataNode* node) const
{
if (m_ChildPredicates.empty())
throw std::invalid_argument("NodePredicateOr: no child predicates available");
if (node == NULL)
throw std::invalid_argument("NodePredicateOr: invalid node");
/* return the disjunction of the child predicate. If any predicate returns true, we return true too. Return false only if all child predicates return false */
for (ChildPredicates::const_iterator it = m_ChildPredicates.begin(); it != m_ChildPredicates.end(); ++it)
if ((*it)->CheckNode(node) == true)
return true;
return false; // none of the childs was true, so return false
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateOr.h b/Core/Code/DataManagement/mitkNodePredicateOr.h
index 6944e265f0..c47c29f24e 100644
--- a/Core/Code/DataManagement/mitkNodePredicateOr.h
+++ b/Core/Code/DataManagement/mitkNodePredicateOr.h
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATEOR_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEOR_H_HEADER_INCLUDED_
#include "mitkNodePredicateCompositeBase.h"
namespace mitk {
//##Documentation
//## @brief Composite predicate that forms a logical OR relation from its child predicates
//##
//##
//##
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateOr : public NodePredicateCompositeBase
{
public:
mitkClassMacro(NodePredicateOr, NodePredicateCompositeBase);
itkFactorylessNewMacro(NodePredicateOr);
mitkNewMacro2Param(NodePredicateOr, const NodePredicateBase*, const NodePredicateBase*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateOr();
//##Documentation
//## @brief Checks, if the node fulfills any of the subpredicates conditions
virtual bool CheckNode(const DataNode* node) const;
protected:
//##Documentation
//## @brief Constructor
NodePredicateOr();
//##Documentation
//## @brief Convenience constructor that adds p1 and p2 to list of child predicates
NodePredicateOr(const NodePredicateBase* p1, const NodePredicateBase* p2);
};
} // namespace mitk
#endif /* MITKNODEPREDICATEOR_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateProperty.cpp b/Core/Code/DataManagement/mitkNodePredicateProperty.cpp
index b9c8371fda..8d8aed3182 100644
--- a/Core/Code/DataManagement/mitkNodePredicateProperty.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateProperty.cpp
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateProperty.h"
#include "mitkDataNode.h"
mitk::NodePredicateProperty::NodePredicateProperty(const char* propertyName, mitk::BaseProperty* p)
: NodePredicateBase(), m_ValidProperty(p), m_ValidPropertyName(propertyName)
{
}
mitk::NodePredicateProperty::NodePredicateProperty(const char* propertyName)
: NodePredicateBase(), m_ValidProperty(NULL), m_ValidPropertyName(propertyName)
{
}
mitk::NodePredicateProperty::~NodePredicateProperty()
{
}
bool mitk::NodePredicateProperty::CheckNode(const mitk::DataNode* node) const
{
if (node == NULL)
throw std::invalid_argument("NodePredicateProperty: invalid node");
if (m_ValidPropertyName.empty())
throw std::invalid_argument("NodePredicateProperty: invalid property name");
// check, if any of the properties of node are equal to m_ValidProperty.
if (m_ValidProperty.IsNull())
//if (m_ValidProperty==NULL)
{
return (node->GetPropertyList()->GetProperty(m_ValidPropertyName.c_str()) != NULL); // search only for name
}
else
{
mitk::BaseProperty::Pointer p = node->GetPropertyList()->GetProperty(m_ValidPropertyName.c_str());
if (p.IsNull())
return false;
return (*p == *m_ValidProperty); // search for name and property
}
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateProperty.h b/Core/Code/DataManagement/mitkNodePredicateProperty.h
index 6367f8ec99..3fa0170ee0 100644
--- a/Core/Code/DataManagement/mitkNodePredicateProperty.h
+++ b/Core/Code/DataManagement/mitkNodePredicateProperty.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATEPROPERTY_H_HEADER_INCLUDED_
#define MITKNODEPREDICATEPROPERTY_H_HEADER_INCLUDED_
#include "mitkNodePredicateBase.h"
#include "mitkBaseProperty.h"
#include "mitkWeakPointer.h"
namespace mitk {
//##Documentation
//## @brief Predicate that evaluates if the given DataNode has a specific property.
//## If the second parameter is NULL, it will only be checked whether there is a property with the specified name.
//##
//##
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateProperty : public NodePredicateBase
{
public:
mitkClassMacro(NodePredicateProperty, NodePredicateBase);
mitkNewMacro1Param(NodePredicateProperty, const char*);
mitkNewMacro2Param(NodePredicateProperty, const char*, mitk::BaseProperty*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateProperty();
//##Documentation
//## @brief Checks, if the nodes contains a property that is equal to m_ValidProperty
virtual bool CheckNode(const mitk::DataNode* node) const;
protected:
//##Documentation
//## @brief Constructor to check for a named property
NodePredicateProperty(const char* propertyName, mitk::BaseProperty* p);
//##Documentation
//## @brief Constructor to check for the existence of a property with a given name
NodePredicateProperty(const char* propertyName);
//mitk::WeakPointer<mitk::BaseProperty> m_ValidProperty;
mitk::BaseProperty::Pointer m_ValidProperty;
//mitk::BaseProperty* m_ValidProperty;
std::string m_ValidPropertyName;
};
} // namespace mitk
#endif /* MITKNODEPREDICATEPROPERTY_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkNodePredicateSource.cpp b/Core/Code/DataManagement/mitkNodePredicateSource.cpp
index 1edc08bf7d..abc2b19329 100644
--- a/Core/Code/DataManagement/mitkNodePredicateSource.cpp
+++ b/Core/Code/DataManagement/mitkNodePredicateSource.cpp
@@ -1,41 +1,40 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateSource.h"
mitk::NodePredicateSource::NodePredicateSource(mitk::DataNode* n, bool allsources, mitk::DataStorage* ds)
: NodePredicateBase(), m_BaseNode(n), m_SearchAllSources(allsources), m_DataStorage(ds)
{
}
mitk::NodePredicateSource::~NodePredicateSource()
{
}
bool mitk::NodePredicateSource::CheckNode(const mitk::DataNode* childNode) const
{
if(m_DataStorage && m_BaseNode)
{
const mitk::DataStorage::SetOfObjects::STLContainerType sources =
m_DataStorage->GetSources(childNode, 0, !m_SearchAllSources)->CastToSTLConstContainer();
return std::find(sources.begin(), sources.end(), m_BaseNode) != sources.end();
}
return false;
}
diff --git a/Core/Code/DataManagement/mitkNodePredicateSource.h b/Core/Code/DataManagement/mitkNodePredicateSource.h
index cf67402da3..83d6439b18 100644
--- a/Core/Code/DataManagement/mitkNodePredicateSource.h
+++ b/Core/Code/DataManagement/mitkNodePredicateSource.h
@@ -1,63 +1,62 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNODEPREDICATESOURCE_H_HEADER_INCLUDED_
#define MITKNODEPREDICATESOURCE_H_HEADER_INCLUDED_
#include "mitkNodePredicateBase.h"
#include "mitkDataStorage.h"
#include "mitkDataNode.h"
#include "mitkWeakPointer.h"
namespace mitk {
//##Documentation
//## @brief Predicate that evaluates if the given node is a direct or indirect source node of a specific node
//##
//## @warning Calling CheckNode() can be computationally quite expensive for a large DataStorage.
//## Alternatively mitk::StandaloneDataStorage::GetSources() can be used
//##
//## @ingroup DataStorage
class MITK_CORE_EXPORT NodePredicateSource : public NodePredicateBase
{
public:
mitkClassMacro(NodePredicateSource, NodePredicateBase);
mitkNewMacro3Param(NodePredicateSource, mitk::DataNode*, bool, mitk::DataStorage*);
//##Documentation
//## @brief Standard Destructor
virtual ~NodePredicateSource();
//##Documentation
//## @brief Checks, if m_BaseNode is a source node of childNode (e.g. if childNode "was created from" m_BaseNode)
virtual bool CheckNode(const mitk::DataNode* childNode) const;
protected:
//##Documentation
//## @brief Constructor - This class can either search only for direct source objects or for all source objects
NodePredicateSource(mitk::DataNode* n, bool allsources, mitk::DataStorage* ds);
mitk::WeakPointer<mitk::DataNode> m_BaseNode;
bool m_SearchAllSources;
mitk::WeakPointer<mitk::DataStorage> m_DataStorage;
};
} // namespace mitk
#endif /* MITKNODEPREDICATESOURCE_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkPlaneGeometry.cpp b/Core/Code/DataManagement/mitkPlaneGeometry.cpp
index 851fb449f9..8ae6971767 100644
--- a/Core/Code/DataManagement/mitkPlaneGeometry.cpp
+++ b/Core/Code/DataManagement/mitkPlaneGeometry.cpp
@@ -1,778 +1,777 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPlaneGeometry.h"
#include "mitkPlaneOperation.h"
#include "mitkInteractionConst.h"
#include "mitkLine.h"
#include <vtkTransform.h>
#include <vnl/vnl_cross.h>
namespace mitk
{
mitk::PlaneGeometry::PlaneGeometry()
{
Initialize();
}
mitk::PlaneGeometry::~PlaneGeometry()
{
}
void
PlaneGeometry::Initialize()
{
Superclass::Initialize();
}
void
PlaneGeometry::EnsurePerpendicularNormal(mitk::AffineTransform3D *transform)
{
//ensure row(2) of transform to be perpendicular to plane, keep length.
VnlVector normal = vnl_cross_3d(
transform->GetMatrix().GetVnlMatrix().get_column(0),
transform->GetMatrix().GetVnlMatrix().get_column(1) );
normal.normalize();
ScalarType len = transform->GetMatrix()
.GetVnlMatrix().get_column(2).two_norm();
if (len==0) len = 1;
normal*=len;
Matrix3D matrix = transform->GetMatrix();
matrix.GetVnlMatrix().set_column(2, normal);
transform->SetMatrix(matrix);
}
void
PlaneGeometry::SetIndexToWorldTransform(mitk::AffineTransform3D *transform)
{
EnsurePerpendicularNormal(transform);
Superclass::SetIndexToWorldTransform(transform);
}
void
PlaneGeometry::SetBounds(const BoundingBox::BoundsArrayType &bounds)
{
//currently the unit rectangle must be starting at the origin [0,0]
assert(bounds[0]==0);
assert(bounds[2]==0);
//the unit rectangle must be two-dimensional
assert(bounds[1]>0);
assert(bounds[3]>0);
Superclass::SetBounds(bounds);
}
void
PlaneGeometry::IndexToWorld( const Point2D &pt_units, Point2D &pt_mm ) const
{
pt_mm[0]=m_ScaleFactorMMPerUnitX*pt_units[0];
pt_mm[1]=m_ScaleFactorMMPerUnitY*pt_units[1];
}
void PlaneGeometry::WorldToIndex( const Point2D &pt_mm, Point2D &pt_units ) const
{
pt_units[0]=pt_mm[0]*(1.0/m_ScaleFactorMMPerUnitX);
pt_units[1]=pt_mm[1]*(1.0/m_ScaleFactorMMPerUnitY);
}
void PlaneGeometry::IndexToWorld( const Point2D & /*atPt2d_units*/,
const Vector2D &vec_units, Vector2D &vec_mm) const
{
MITK_WARN<<"Warning! Call of the deprecated function PlaneGeometry::IndexToWorld(point, vec, vec). Use PlaneGeometry::IndexToWorld(vec, vec) instead!";
this->IndexToWorld(vec_units, vec_mm);
}
void PlaneGeometry::IndexToWorld(const Vector2D &vec_units, Vector2D &vec_mm) const
{
vec_mm[0] = m_ScaleFactorMMPerUnitX * vec_units[0];
vec_mm[1] = m_ScaleFactorMMPerUnitY * vec_units[1];
}
void
PlaneGeometry::WorldToIndex( const Point2D & /*atPt2d_mm*/,
const Vector2D &vec_mm, Vector2D &vec_units) const
{
MITK_WARN<<"Warning! Call of the deprecated function PlaneGeometry::WorldToIndex(point, vec, vec). Use PlaneGeometry::WorldToIndex(vec, vec) instead!";
this->WorldToIndex(vec_mm, vec_units);
}
void
PlaneGeometry::WorldToIndex( const Vector2D &vec_mm, Vector2D &vec_units) const
{
vec_units[0] = vec_mm[0] * ( 1.0 / m_ScaleFactorMMPerUnitX );
vec_units[1] = vec_mm[1] * ( 1.0 / m_ScaleFactorMMPerUnitY );
}
void
PlaneGeometry::InitializeStandardPlane( mitk::ScalarType width,
ScalarType height, const Vector3D & spacing,
PlaneGeometry::PlaneOrientation planeorientation,
ScalarType zPosition, bool frontside, bool rotated )
{
AffineTransform3D::Pointer transform;
transform = AffineTransform3D::New();
AffineTransform3D::MatrixType matrix;
AffineTransform3D::MatrixType::InternalMatrixType &vnlmatrix =
matrix.GetVnlMatrix();
vnlmatrix.set_identity();
vnlmatrix(0,0) = spacing[0];
vnlmatrix(1,1) = spacing[1];
vnlmatrix(2,2) = spacing[2];
transform->SetIdentity();
transform->SetMatrix(matrix);
InitializeStandardPlane(width, height, transform.GetPointer(),
planeorientation, zPosition, frontside, rotated);
}
void
PlaneGeometry::InitializeStandardPlane( mitk::ScalarType width,
ScalarType height, const AffineTransform3D* transform,
PlaneGeometry::PlaneOrientation planeorientation, ScalarType zPosition,
bool frontside, bool rotated )
{
Superclass::Initialize();
//construct standard view
Point3D origin;
VnlVector rightDV(3), bottomDV(3);
origin.Fill(0);
int normalDirection;
switch(planeorientation)
{
case Transversal:
if(frontside)
{
if(rotated==false)
{
FillVector3D(origin, 0, 0, zPosition);
FillVector3D(rightDV, 1, 0, 0);
FillVector3D(bottomDV, 0, 1, 0);
}
else
{
FillVector3D(origin, width, height, zPosition);
FillVector3D(rightDV, -1, 0, 0);
FillVector3D(bottomDV, 0, -1, 0);
}
}
else
{
if(rotated==false)
{
FillVector3D(origin, width, 0, zPosition);
FillVector3D(rightDV, -1, 0, 0);
FillVector3D(bottomDV, 0, 1, 0);
}
else
{
FillVector3D(origin, 0, height, zPosition);
FillVector3D(rightDV, 1, 0, 0);
FillVector3D(bottomDV, 0, -1, 0);
}
}
normalDirection = 2;
break;
case Frontal:
if(frontside)
{
if(rotated==false)
{
FillVector3D(origin, 0, zPosition, 0);
FillVector3D(rightDV, 1, 0, 0);
FillVector3D(bottomDV, 0, 0, 1);
}
else
{
FillVector3D(origin, width, zPosition, height);
FillVector3D(rightDV, -1, 0, 0);
FillVector3D(bottomDV, 0, 0, -1);
}
}
else
{
if(rotated==false)
{
FillVector3D(origin, width, zPosition, 0);
FillVector3D(rightDV, -1, 0, 0);
FillVector3D(bottomDV, 0, 0, 1);
}
else
{
FillVector3D(origin, 0, zPosition, height);
FillVector3D(rightDV, 1, 0, 0);
FillVector3D(bottomDV, 0, 0, -1);
}
}
normalDirection = 1;
break;
case Sagittal:
if(frontside)
{
if(rotated==false)
{
FillVector3D(origin, zPosition, 0, 0);
FillVector3D(rightDV, 0, 1, 0);
FillVector3D(bottomDV, 0, 0, 1);
}
else
{
FillVector3D(origin, zPosition, width, height);
FillVector3D(rightDV, 0, -1, 0);
FillVector3D(bottomDV, 0, 0, -1);
}
}
else
{
if(rotated==false)
{
FillVector3D(origin, zPosition, width, 0);
FillVector3D(rightDV, 0, -1, 0);
FillVector3D(bottomDV, 0, 0, 1);
}
else
{
FillVector3D(origin, zPosition, 0, height);
FillVector3D(rightDV, 0, 1, 0);
FillVector3D(bottomDV, 0, 0, -1);
}
}
normalDirection = 0;
break;
default:
itkExceptionMacro("unknown PlaneOrientation");
}
if ( transform != NULL )
{
origin = transform->TransformPoint( origin );
rightDV = transform->TransformVector( rightDV );
bottomDV = transform->TransformVector( bottomDV );
}
ScalarType bounds[6]= { 0, width, 0, height, 0, 1 };
this->SetBounds( bounds );
if ( transform == NULL )
{
this->SetMatrixByVectors( rightDV, bottomDV );
}
else
{
this->SetMatrixByVectors(
rightDV, bottomDV,
transform->GetMatrix().GetVnlMatrix()
.get_column(normalDirection).magnitude()
);
}
this->SetOrigin(origin);
}
void
PlaneGeometry::InitializeStandardPlane( const Geometry3D *geometry3D,
PlaneOrientation planeorientation, ScalarType zPosition,
bool frontside, bool rotated )
{
this->SetReferenceGeometry( const_cast< Geometry3D * >( geometry3D ) );
ScalarType width, height;
const BoundingBox::BoundsArrayType& boundsarray =
geometry3D->GetBoundingBox()->GetBounds();
Vector3D originVector;
FillVector3D(originVector, boundsarray[0], boundsarray[2], boundsarray[4]);
if(geometry3D->GetImageGeometry())
{
FillVector3D( originVector,
originVector[0] - 0.5,
originVector[1] - 0.5,
originVector[2] - 0.5 );
}
switch(planeorientation)
{
case Transversal:
width = geometry3D->GetExtent(0);
height = geometry3D->GetExtent(1);
break;
case Frontal:
width = geometry3D->GetExtent(0);
height = geometry3D->GetExtent(2);
break;
case Sagittal:
width = geometry3D->GetExtent(1);
height = geometry3D->GetExtent(2);
break;
default:
itkExceptionMacro("unknown PlaneOrientation");
}
InitializeStandardPlane( width, height,
geometry3D->GetIndexToWorldTransform(),
planeorientation, zPosition, frontside, rotated );
ScalarType bounds[6]= { 0, width, 0, height, 0, 1 };
this->SetBounds( bounds );
Point3D origin;
originVector = geometry3D->GetIndexToWorldTransform()
->TransformVector( originVector );
origin = GetOrigin() + originVector;
SetOrigin(origin);
}
void
PlaneGeometry::InitializeStandardPlane( const Geometry3D *geometry3D,
bool top, PlaneOrientation planeorientation, bool frontside, bool rotated )
{
ScalarType zPosition;
switch(planeorientation)
{
case Transversal:
zPosition = (top ? 0.5 : geometry3D->GetExtent(2)-1+0.5);
break;
case Frontal:
zPosition = (top ? 0.5 : geometry3D->GetExtent(1)-1+0.5);
break;
case Sagittal:
zPosition = (top ? 0.5 : geometry3D->GetExtent(0)-1+0.5);
break;
default:
itkExceptionMacro("unknown PlaneOrientation");
}
InitializeStandardPlane( geometry3D, planeorientation,
zPosition, frontside, rotated );
}
void
PlaneGeometry::InitializeStandardPlane( const Vector3D &rightVector,
const Vector3D &downVector, const Vector3D *spacing )
{
InitializeStandardPlane( rightVector.Get_vnl_vector(),
downVector.Get_vnl_vector(), spacing );
}
void
PlaneGeometry::InitializeStandardPlane( const VnlVector& rightVector,
const VnlVector &downVector, const Vector3D *spacing )
{
ScalarType width = rightVector.magnitude();
ScalarType height = downVector.magnitude();
InitializeStandardPlane( width, height, rightVector, downVector, spacing );
}
void
PlaneGeometry::InitializeStandardPlane( mitk::ScalarType width,
ScalarType height, const Vector3D &rightVector, const Vector3D &downVector,
const Vector3D *spacing )
{
InitializeStandardPlane(
width, height,
rightVector.Get_vnl_vector(), downVector.Get_vnl_vector(),
spacing );
}
void
PlaneGeometry::InitializeStandardPlane(
mitk::ScalarType width, ScalarType height,
const VnlVector &rightVector, const VnlVector &downVector,
const Vector3D *spacing )
{
assert(width > 0);
assert(height > 0);
VnlVector rightDV = rightVector; rightDV.normalize();
VnlVector downDV = downVector; downDV.normalize();
VnlVector normal = vnl_cross_3d(rightVector, downVector);
normal.normalize();
if(spacing!=NULL)
{
rightDV *= (*spacing)[0];
downDV *= (*spacing)[1];
normal *= (*spacing)[2];
}
AffineTransform3D::Pointer transform = AffineTransform3D::New();
Matrix3D matrix;
matrix.GetVnlMatrix().set_column(0, rightDV);
matrix.GetVnlMatrix().set_column(1, downDV);
matrix.GetVnlMatrix().set_column(2, normal);
transform->SetMatrix(matrix);
transform->SetOffset(m_IndexToWorldTransform->GetOffset());
ScalarType bounds[6] = { 0, width, 0, height, 0, 1 };
this->SetBounds( bounds );
this->SetIndexToWorldTransform( transform );
}
void
PlaneGeometry::InitializePlane( const Point3D &origin,
const Vector3D &normal )
{
VnlVector rightVectorVnl(3), downVectorVnl;
if( Equal( normal[1], 0.0f ) == false )
{
FillVector3D( rightVectorVnl, 1.0f, -normal[0]/normal[1], 0.0f );
rightVectorVnl.normalize();
}
else
{
FillVector3D( rightVectorVnl, 0.0f, 1.0f, 0.0f );
}
downVectorVnl = vnl_cross_3d( normal.Get_vnl_vector(), rightVectorVnl );
downVectorVnl.normalize();
InitializeStandardPlane( rightVectorVnl, downVectorVnl );
SetOrigin(origin);
}
void
PlaneGeometry::SetMatrixByVectors( const VnlVector &rightVector,
const VnlVector &downVector, ScalarType thickness )
{
VnlVector normal = vnl_cross_3d(rightVector, downVector);
normal.normalize();
normal *= thickness;
AffineTransform3D::Pointer transform = AffineTransform3D::New();
Matrix3D matrix;
matrix.GetVnlMatrix().set_column(0, rightVector);
matrix.GetVnlMatrix().set_column(1, downVector);
matrix.GetVnlMatrix().set_column(2, normal);
transform->SetMatrix(matrix);
transform->SetOffset(m_IndexToWorldTransform->GetOffset());
SetIndexToWorldTransform(transform);
}
Vector3D
PlaneGeometry::GetNormal() const
{
Vector3D frontToBack;
frontToBack.Set_vnl_vector( m_IndexToWorldTransform
->GetMatrix().GetVnlMatrix().get_column(2) );
return frontToBack;
}
VnlVector
PlaneGeometry::GetNormalVnl() const
{
return m_IndexToWorldTransform
->GetMatrix().GetVnlMatrix().get_column(2);
}
ScalarType
PlaneGeometry::DistanceFromPlane( const Point3D &pt3d_mm ) const
{
return fabs(SignedDistance( pt3d_mm ));
}
ScalarType
PlaneGeometry::SignedDistance( const Point3D &pt3d_mm ) const
{
return SignedDistanceFromPlane(pt3d_mm);
}
bool
PlaneGeometry::IsAbove( const Point3D &pt3d_mm ) const
{
return SignedDistanceFromPlane(pt3d_mm) > 0;
}
bool
PlaneGeometry::IntersectionLine(
const PlaneGeometry* plane, Line3D& crossline ) const
{
Vector3D normal = this->GetNormal();
normal.Normalize();
Vector3D planeNormal = plane->GetNormal();
planeNormal.Normalize();
Vector3D direction = itk::CrossProduct( normal, planeNormal );
if ( direction.GetSquaredNorm() < eps )
return false;
crossline.SetDirection( direction );
double N1dN2 = normal * planeNormal;
double determinant = 1.0 - N1dN2 * N1dN2;
Vector3D origin = this->GetOrigin().GetVectorFromOrigin();
Vector3D planeOrigin = plane->GetOrigin().GetVectorFromOrigin();
double d1 = normal * origin;
double d2 = planeNormal * planeOrigin;
double c1 = ( d1 - d2 * N1dN2 ) / determinant;
double c2 = ( d2 - d1 * N1dN2 ) / determinant;
Vector3D p = normal * c1 + planeNormal * c2;
crossline.GetPoint().Get_vnl_vector() = p.Get_vnl_vector();
return true;
}
unsigned int
PlaneGeometry::IntersectWithPlane2D(
const PlaneGeometry* plane, Point2D& lineFrom, Point2D &lineTo ) const
{
Line3D crossline;
if ( this->IntersectionLine( plane, crossline ) == false )
return 0;
Point2D point2;
Vector2D direction2;
this->Map( crossline.GetPoint(), point2 );
this->Map( crossline.GetPoint(), crossline.GetDirection(), direction2 );
return
Line3D::RectangleLineIntersection(
0, 0, GetExtentInMM(0), GetExtentInMM(1),
point2, direction2, lineFrom, lineTo );
}
double PlaneGeometry::Angle( const PlaneGeometry *plane ) const
{
return angle(plane->GetMatrixColumn(2), GetMatrixColumn(2));
}
double PlaneGeometry::Angle( const Line3D &line ) const
{
return vnl_math::pi_over_2
- angle( line.GetDirection().Get_vnl_vector(), GetMatrixColumn(2) );
}
bool PlaneGeometry::IntersectionPoint(
const Line3D &line, Point3D &intersectionPoint ) const
{
Vector3D planeNormal = this->GetNormal();
planeNormal.Normalize();
Vector3D lineDirection = line.GetDirection();
lineDirection.Normalize();
double t = planeNormal * lineDirection;
if ( fabs( t ) < eps )
{
return false;
}
Vector3D diff;
diff = this->GetOrigin() - line.GetPoint();
t = ( planeNormal * diff ) / t;
intersectionPoint = line.GetPoint() + lineDirection * t;
return true;
}
bool
PlaneGeometry::IntersectionPointParam( const Line3D &line, double &t ) const
{
Vector3D planeNormal = this->GetNormal();
Vector3D lineDirection = line.GetDirection();
t = planeNormal * lineDirection;
if ( fabs( t ) < eps )
{
return false;
}
Vector3D diff;
diff = this->GetOrigin() - line.GetPoint();
t = ( planeNormal * diff ) / t;
return true;
}
bool
PlaneGeometry::IsParallel( const PlaneGeometry *plane ) const
{
return ( (Angle(plane) < 10.0 * mitk::sqrteps ) || ( Angle(plane) > ( vnl_math::pi - 10.0 * sqrteps ) ) ) ;
}
bool
PlaneGeometry::IsOnPlane( const Point3D &point ) const
{
return Distance(point) < eps;
}
bool
PlaneGeometry::IsOnPlane( const Line3D &line ) const
{
return ( (Distance( line.GetPoint() ) < eps)
&& (Distance( line.GetPoint2() ) < eps) );
}
bool
PlaneGeometry::IsOnPlane( const PlaneGeometry *plane ) const
{
return ( IsParallel( plane ) && (Distance( plane->GetOrigin() ) < eps) );
}
Point3D
PlaneGeometry::ProjectPointOntoPlane( const Point3D& pt ) const
{
ScalarType len = this->GetNormalVnl().two_norm();
return pt - this->GetNormal() * this->SignedDistanceFromPlane( pt ) / len;
}
AffineGeometryFrame3D::Pointer
PlaneGeometry::Clone() const
{
Self::Pointer newGeometry = new PlaneGeometry(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
void
PlaneGeometry::ExecuteOperation( Operation *operation )
{
vtkTransform *transform = vtkTransform::New();
transform->SetMatrix( m_VtkMatrix );
switch ( operation->GetOperationType() )
{
case OpORIENT:
{
mitk::PlaneOperation *planeOp = dynamic_cast< mitk::PlaneOperation * >( operation );
if ( planeOp == NULL )
{
return;
}
Point3D center = planeOp->GetPoint();
Vector3D orientationVector = planeOp->GetNormal();
Vector3D defaultVector;
FillVector3D( defaultVector, 0.0, 0.0, 1.0 );
Vector3D rotationAxis = itk::CrossProduct( orientationVector, defaultVector );
//vtkFloatingPointType rotationAngle = acos( orientationVector[2] / orientationVector.GetNorm() );
vtkFloatingPointType rotationAngle = atan2( (double) rotationAxis.GetNorm(), (double) (orientationVector * defaultVector) );
rotationAngle *= 180.0 / vnl_math::pi;
transform->PostMultiply();
transform->Identity();
transform->Translate( center[0], center[1], center[2] );
transform->RotateWXYZ( rotationAngle, rotationAxis[0], rotationAxis[1], rotationAxis[2] );
transform->Translate( -center[0], -center[1], -center[2] );
break;
}
case OpRESTOREPLANEPOSITION:
{
RestorePlanePositionOperation *op = dynamic_cast< mitk::RestorePlanePositionOperation* >(operation);
if(op == NULL)
{
return;
}
AffineTransform3D::Pointer transform2 = AffineTransform3D::New();
Matrix3D matrix;
matrix.GetVnlMatrix().set_column(0, op->GetTransform()->GetMatrix().GetVnlMatrix().get_column(0));
matrix.GetVnlMatrix().set_column(1, op->GetTransform()->GetMatrix().GetVnlMatrix().get_column(1));
matrix.GetVnlMatrix().set_column(2, op->GetTransform()->GetMatrix().GetVnlMatrix().get_column(2));
transform2->SetMatrix(matrix);
Vector3D offset = op->GetTransform()->GetOffset();
transform2->SetOffset(offset);
this->SetIndexToWorldTransform(transform2);
ScalarType bounds[6] = {0, op->GetWidth(), 0, op->GetHeight(), 0 ,1 };
this->SetBounds(bounds);
TransferItkToVtkTransform();
this->Modified();
transform->Delete();
return;
}
default:
Superclass::ExecuteOperation( operation );
transform->Delete();
return;
}
m_VtkMatrix->DeepCopy(transform->GetMatrix());
this->TransferVtkToItkTransform();
this->Modified();
transform->Delete();
}
void PlaneGeometry::PrintSelf( std::ostream& os, itk::Indent indent ) const
{
Superclass::PrintSelf(os,indent);
os << indent << " Normal: " << GetNormal() << std::endl;
}
} // namespace
diff --git a/Core/Code/DataManagement/mitkPlaneGeometry.h b/Core/Code/DataManagement/mitkPlaneGeometry.h
index a36b1b1119..70625eb5fc 100644
--- a/Core/Code/DataManagement/mitkPlaneGeometry.h
+++ b/Core/Code/DataManagement/mitkPlaneGeometry.h
@@ -1,423 +1,422 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 PLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#define PLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#include <MitkExports.h>
#include "mitkGeometry2D.h"
#include "mitkRestorePlanePositionOperation.h"
#include <vnl/vnl_cross.h>
namespace mitk {
template < class TCoordRep, unsigned int NPointDimension > class Line;
typedef Line<ScalarType, 3> Line3D;
/**
* \brief Describes a two-dimensional, rectangular plane
*
* \ingroup Geometry
*/
class MITK_CORE_EXPORT PlaneGeometry : public Geometry2D
{
public:
mitkClassMacro(PlaneGeometry,Geometry2D);
/** Method for creation through the object factory. */
itkNewMacro(Self);
enum PlaneOrientation { Transversal, Sagittal, Frontal };
virtual void IndexToWorld(const Point2D &pt_units, Point2D &pt_mm) const;
virtual void WorldToIndex(const Point2D &pt_mm, Point2D &pt_units) const;
//##Documentation
//## @brief Convert (continuous or discrete) index coordinates of a \em vector
//## \a vec_units to world coordinates (in mm)
//## @deprecated First parameter (Point2D) is not used. If possible, please use void IndexToWorld(const mitk::Vector2D& vec_units, mitk::Vector2D& vec_mm) const.
//## For further information about coordinates types, please see the Geometry documentation
virtual void IndexToWorld(const mitk::Point2D &atPt2d_untis, const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const;
//##Documentation
//## @brief Convert (continuous or discrete) index coordinates of a \em vector
//## \a vec_units to world coordinates (in mm)
//## For further information about coordinates types, please see the Geometry documentation
virtual void IndexToWorld(const mitk::Vector2D &vec_units, mitk::Vector2D &vec_mm) const;
//##Documentation
//## @brief Convert world coordinates (in mm) of a \em vector
//## \a vec_mm to (continuous!) index coordinates.
//## @deprecated First parameter (Point2D) is not used. If possible, please use void WorldToIndex(const mitk::Vector2D& vec_mm, mitk::Vector2D& vec_units) const.
//## For further information about coordinates types, please see the Geometry documentation
virtual void WorldToIndex(const mitk::Point2D &atPt2d_mm, const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const;
//##Documentation
//## @brief Convert world coordinates (in mm) of a \em vector
//## \a vec_mm to (continuous!) index coordinates.
//## For further information about coordinates types, please see the Geometry documentation
virtual void WorldToIndex(const mitk::Vector2D &vec_mm, mitk::Vector2D &vec_units) const;
virtual void Initialize();
/**
* \brief Initialize a plane with orientation \a planeorientation
* (default: transversal) with respect to \a geometry3D (default: identity).
* Spacing also taken from \a geometry3D.
*
* \warning A former version of this method created a geometry with unit
* spacing. For unit spacing use
*
* \code
* // for in-plane unit spacing:
* thisgeometry->SetSizeInUnits(thisgeometry->GetExtentInMM(0),
* thisgeometry->GetExtentInMM(1));
* // additionally, for unit spacing in normal direction (former version
* // did not do this):
* thisgeometry->SetExtentInMM(2, 1.0);
* \endcode
*/
virtual void InitializeStandardPlane( const Geometry3D* geometry3D,
PlaneOrientation planeorientation = Transversal, ScalarType zPosition = 0,
bool frontside=true, bool rotated=false );
/**
* \brief Initialize a plane with orientation \a planeorientation
* (default: transversal) with respect to \a geometry3D (default: identity).
* Spacing also taken from \a geometry3D.
*
* \param top if \a true, create plane at top, otherwise at bottom
* (for PlaneOrientation Transversal, for other plane locations respectively)
*/
virtual void InitializeStandardPlane( const Geometry3D* geometry3D, bool top,
PlaneOrientation planeorientation = Transversal,
bool frontside=true, bool rotated=false );
/**
* \brief Initialize a plane with orientation \a planeorientation
* (default: transversal) with respect to \a transform (default: identity)
* given width and height in units.
*
*/
virtual void InitializeStandardPlane( ScalarType width, ScalarType height,
const AffineTransform3D* transform = NULL,
PlaneOrientation planeorientation = Transversal,
ScalarType zPosition = 0, bool frontside=true, bool rotated=false );
/**
* \brief Initialize plane with orientation \a planeorientation
* (default: transversal) given width, height and spacing.
*
*/
virtual void InitializeStandardPlane( ScalarType width, ScalarType height,
const Vector3D & spacing, PlaneOrientation planeorientation = Transversal,
ScalarType zPosition = 0, bool frontside = true, bool rotated = false );
/**
* \brief Initialize plane by width and height in pixels, right-/down-vector
* (itk) to describe orientation in world-space (vectors will be normalized)
* and spacing (default: 1.0 mm in all directions).
*
* The vectors are normalized and multiplied by the respective spacing before
* they are set in the matrix.
*/
virtual void InitializeStandardPlane( ScalarType width, ScalarType height,
const Vector3D& rightVector, const Vector3D& downVector,
const Vector3D *spacing = NULL );
/**
* \brief Initialize plane by width and height in pixels,
* right-/down-vector (vnl) to describe orientation in world-space (vectors
* will be normalized) and spacing (default: 1.0 mm in all directions).
*
* The vectors are normalized and multiplied by the respective spacing
* before they are set in the matrix.
*/
virtual void InitializeStandardPlane( ScalarType width, ScalarType height,
const VnlVector& rightVector, const VnlVector& downVector,
const Vector3D * spacing = NULL );
/**
* \brief Initialize plane by right-/down-vector (itk) and spacing
* (default: 1.0 mm in all directions).
*
* The length of the right-/-down-vector is used as width/height in units,
* respectively. Then, the vectors are normalized and multiplied by the
* respective spacing before they are set in the matrix.
*/
virtual void InitializeStandardPlane( const Vector3D& rightVector,
const Vector3D& downVector, const Vector3D * spacing = NULL );
/**
* \brief Initialize plane by right-/down-vector (vnl) and spacing
* (default: 1.0 mm in all directions).
*
* The length of the right-/-down-vector is used as width/height in units,
* respectively. Then, the vectors are normalized and multiplied by the
* respective spacing before they are set in the matrix.
*/
virtual void InitializeStandardPlane( const VnlVector& rightVector,
const VnlVector& downVector, const Vector3D * spacing = NULL );
/**
* \brief Initialize plane by origin and normal (size is 1.0 mm in
* all directions, direction of right-/down-vector valid but
* undefined).
*
*/
virtual void InitializePlane( const Point3D& origin, const Vector3D& normal);
/**
* \brief Initialize plane by right-/down-vector.
*
* \warning The vectors are set into the matrix as they are,
* \em without normalization!
*/
void SetMatrixByVectors( const VnlVector& rightVector,
const VnlVector& downVector, ScalarType thickness=1.0 );
/**
* \brief Change \a transform so that the third column of the
* transform-martix is perpendicular to the first two columns
*
*/
static void EnsurePerpendicularNormal( AffineTransform3D* transform );
/**
* \brief Normal of the plane
*
*/
Vector3D GetNormal() const;
/**
* \brief Normal of the plane as VnlVector
*
*/
VnlVector GetNormalVnl() const;
virtual ScalarType SignedDistance( const Point3D& pt3d_mm ) const;
virtual bool IsAbove( const Point3D& pt3d_mm ) const;
/**
* \brief Distance of the point from the plane
* (bounding-box \em not considered)
*
*/
ScalarType DistanceFromPlane( const Point3D& pt3d_mm ) const ;
/**
* \brief Signed distance of the point from the plane
* (bounding-box \em not considered)
*
* > 0 : point is in the direction of the direction vector.
*/
inline ScalarType SignedDistanceFromPlane( const Point3D& pt3d_mm ) const
{
ScalarType len = GetNormalVnl().two_norm();
if( len == 0 )
return 0;
return (pt3d_mm-GetOrigin())*GetNormal() / len;
}
/**
* \brief Distance of the plane from another plane
* (bounding-box \em not considered)
*
* Result is 0 if planes are not parallel.
*/
ScalarType DistanceFromPlane(const PlaneGeometry* plane) const
{
return fabs(SignedDistanceFromPlane(plane));
}
/**
* \brief Signed distance of the plane from another plane
* (bounding-box \em not considered)
*
* Result is 0 if planes are not parallel.
*/
inline ScalarType SignedDistanceFromPlane( const PlaneGeometry *plane ) const
{
if(IsParallel(plane))
{
return SignedDistance(plane->GetOrigin());
}
return 0;
}
/**
* \brief Calculate the intersecting line of two planes
*
* \return \a true planes are intersecting
* \return \a false planes do not intersect
*/
bool IntersectionLine( const PlaneGeometry *plane, Line3D &crossline ) const;
/**
* \brief Calculate two points where another plane intersects the border of this plane
*
* \return number of intersection points (0..2). First interection point (if existing)
* is returned in \a lineFrom, second in \a lineTo.
*/
unsigned int IntersectWithPlane2D(const PlaneGeometry *plane,
Point2D &lineFrom, Point2D &lineTo ) const ;
/**
* \brief Calculate the angle between two planes
*
* \return angle in radiants
*/
double Angle( const PlaneGeometry *plane ) const;
/**
* \brief Calculate the angle between the plane and a line
*
* \return angle in radiants
*/
double Angle( const Line3D &line ) const;
/**
* \brief Calculate intersection point between the plane and a line
*
* \param intersectionPoint intersection point
* \return \a true if \em unique intersection exists, i.e., if line
* is \em not on or parallel to the plane
*/
bool IntersectionPoint( const Line3D &line,
Point3D &intersectionPoint ) const;
/**
* \brief Calculate line parameter of intersection point between the
* plane and a line
*
* \param t parameter of line: intersection point is
* line.GetPoint()+t*line.GetDirection()
* \return \a true if \em unique intersection exists, i.e., if line
* is \em not on or parallel to the plane
*/
bool IntersectionPointParam( const Line3D &line, double &t ) const;
/**
* \brief Returns whether the plane is parallel to another plane
*
* @return true iff the normal vectors both point to the same or exactly oposit direction
*/
bool IsParallel( const PlaneGeometry *plane ) const;
/**
* \brief Returns whether the point is on the plane
* (bounding-box \em not considered)
*/
bool IsOnPlane( const Point3D &point ) const;
/**
* \brief Returns whether the line is on the plane
* (bounding-box \em not considered)
*/
bool IsOnPlane( const Line3D &line ) const;
/**
* \brief Returns whether the plane is on the plane
* (bounding-box \em not considered)
*
* @return true iff the normal vector of the planes point to the same or the exactly oposit direction and
* the distance of the planes is < eps
*
*/
bool IsOnPlane( const PlaneGeometry *plane ) const;
/**
* \brief Returns the lot from the point to the plane
*/
Point3D ProjectPointOntoPlane( const Point3D &pt ) const;
virtual void SetIndexToWorldTransform( AffineTransform3D *transform);
virtual void SetBounds( const BoundingBox::BoundsArrayType &bounds );
AffineGeometryFrame3D::Pointer Clone() const;
/** Implements operation to re-orient the plane */
virtual void ExecuteOperation( Operation *operation );
protected:
PlaneGeometry();
virtual ~PlaneGeometry();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
private:
/**
* \brief Compares plane with another plane: \a true if IsOnPlane
* (bounding-box \em not considered)
*/
virtual bool operator==( const PlaneGeometry * ) const { return false; };
/**
* \brief Compares plane with another plane: \a false if IsOnPlane
* (bounding-box \em not considered)
*/
virtual bool operator!=( const PlaneGeometry * ) const { return false; };
};
} // namespace mitk
#endif /* PLANEGEOMETRY_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Core/Code/DataManagement/mitkPlaneOperation.cpp b/Core/Code/DataManagement/mitkPlaneOperation.cpp
index 7750e44915..6b8d6f02d0 100644
--- a/Core/Code/DataManagement/mitkPlaneOperation.cpp
+++ b/Core/Code/DataManagement/mitkPlaneOperation.cpp
@@ -1,41 +1,40 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPlaneOperation.h"
namespace mitk
{
PlaneOperation
::PlaneOperation( OperationType operationType, Point3D point, Vector3D normal )
: PointOperation( operationType, point ), m_Normal( normal )
{
}
PlaneOperation
::~PlaneOperation()
{
}
Vector3D mitk::PlaneOperation::GetNormal()
{
return m_Normal;
}
} // namespace mitk
diff --git a/Core/Code/DataManagement/mitkPlaneOperation.h b/Core/Code/DataManagement/mitkPlaneOperation.h
index 1ceff99b27..6d18e162f1 100644
--- a/Core/Code/DataManagement/mitkPlaneOperation.h
+++ b/Core/Code/DataManagement/mitkPlaneOperation.h
@@ -1,54 +1,53 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPlaneOperation_H
#define MITKPlaneOperation_H
#include <MitkExports.h>
#include "mitkPointOperation.h"
#include "mitkVector.h"
namespace mitk {
/**
* @brief Operation for setting a plane (defined by its origin and normal)
*
* @ingroup Undo
*/
class MITK_CORE_EXPORT PlaneOperation : public PointOperation
{
public:
PlaneOperation( OperationType operationType, Point3D point, Vector3D normal );
virtual ~PlaneOperation();
Vector3D GetNormal();
private:
Vector3D m_Normal;
};
} //namespace mitk
#endif /* MITKPlaneOperation_H */
diff --git a/Core/Code/DataManagement/mitkPlaneOrientationProperty.cpp b/Core/Code/DataManagement/mitkPlaneOrientationProperty.cpp
index cba9d49d17..ce12797d34 100644
--- a/Core/Code/DataManagement/mitkPlaneOrientationProperty.cpp
+++ b/Core/Code/DataManagement/mitkPlaneOrientationProperty.cpp
@@ -1,97 +1,96 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $
-Version: $Revision: 13129 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkPlaneOrientationProperty.h"
namespace mitk
{
PlaneOrientationProperty::PlaneOrientationProperty( )
{
this->AddDecorationTypes();
this->SetValue( static_cast<IdType>( PLANE_DECORATION_NONE ) );
}
PlaneOrientationProperty::PlaneOrientationProperty( const IdType& value )
{
this->AddDecorationTypes();
if ( this->IsValidEnumerationValue( value ) )
{
this->SetValue( value ) ;
}
else
{
this->SetValue( static_cast<IdType>( PLANE_DECORATION_NONE ) );
}
}
PlaneOrientationProperty::PlaneOrientationProperty( const std::string& value )
{
this->AddDecorationTypes();
if ( this->IsValidEnumerationValue( value ) )
{
this->SetValue( value );
}
else
{
this->SetValue( static_cast<IdType>( PLANE_DECORATION_NONE ) );
}
}
int PlaneOrientationProperty::GetPlaneDecoration()
{
return static_cast<int>( this->GetValueAsId() );
}
void PlaneOrientationProperty::SetPlaneDecorationToNone()
{
this->SetValue( static_cast<IdType>( PLANE_DECORATION_NONE ) );
}
void PlaneOrientationProperty::SetPlaneDecorationToPositiveOrientation()
{
this->SetValue( static_cast<IdType>( PLANE_DECORATION_POSITIVE_ORIENTATION ) );
}
void PlaneOrientationProperty::SetPlaneDecorationToNegativeOrientation()
{
this->SetValue( static_cast<IdType>( PLANE_DECORATION_NEGATIVE_ORIENTATION ) );
}
void PlaneOrientationProperty::AddDecorationTypes()
{
this->AddEnum( "No plane decoration", static_cast<IdType>( PLANE_DECORATION_NONE ) );
this->AddEnum( "Arrows in positive direction", static_cast<IdType>( PLANE_DECORATION_POSITIVE_ORIENTATION ) );
this->AddEnum( "Arrows in negative direction", static_cast<IdType>( PLANE_DECORATION_NEGATIVE_ORIENTATION ) );
}
bool PlaneOrientationProperty::AddEnum( const std::string& name, const IdType& id )
{
return Superclass::AddEnum( name, id );
}
} // namespace
diff --git a/Core/Code/DataManagement/mitkPlaneOrientationProperty.h b/Core/Code/DataManagement/mitkPlaneOrientationProperty.h
index 0f2db713df..cff03d00e6 100644
--- a/Core/Code/DataManagement/mitkPlaneOrientationProperty.h
+++ b/Core/Code/DataManagement/mitkPlaneOrientationProperty.h
@@ -1,130 +1,129 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $
-Version: $Revision: 14081 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 MITK_PLANE_DECORATION_PROPERTY__H
#define MITK_PLANE_DECORATION_PROPERTY__H
#include "mitkEnumerationProperty.h"
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* Property which controls whether 2D line representation of a PlaneGeometry
* should have small arrows at both ends to indicate the orientation of
* the plane, and whether the arrows should be oriented in the direction of
* the plane's normal or against it.
*
* Valid values of the enumeration property are
* - PLANE_DECORATION_NONE (no arrows)
* - PLANE_DECORATION_POSITIVE_ORIENTATION (arrows pointing upwards)
* - PLANE_DECORATION_NEGATIVE_ORIENTATION (arrows pointing downwards)
*
* See also mitk::Geometry2DDataMapper2D::DrawOrientationArrow()
*/
class MITK_CORE_EXPORT PlaneOrientationProperty : public EnumerationProperty
{
public:
mitkClassMacro( PlaneOrientationProperty, EnumerationProperty );
itkNewMacro(PlaneOrientationProperty);
mitkNewMacro1Param(PlaneOrientationProperty, const IdType&);
mitkNewMacro1Param(PlaneOrientationProperty, const std::string&);
enum
{
PLANE_DECORATION_NONE,
PLANE_DECORATION_POSITIVE_ORIENTATION,
PLANE_DECORATION_NEGATIVE_ORIENTATION
};
/**
* Returns the state of plane decoration.
*/
virtual int GetPlaneDecoration();
/**
* Sets the decoration type to no decoration.
*/
virtual void SetPlaneDecorationToNone();
/**
* Sets the decoration type to arrows in positive plane direction.
*/
virtual void SetPlaneDecorationToPositiveOrientation();
/**
* Sets the decoration type to arrows in negative plane direction.
*/
virtual void SetPlaneDecorationToNegativeOrientation();
using BaseProperty::operator=;
protected:
/**
* Constructor. Sets the decoration type to none.
*/
PlaneOrientationProperty( );
/**
* Constructor. Sets the decoration type to the given value. If it is not
* valid, the interpolation is set to none
*/
PlaneOrientationProperty( const IdType &value );
/**
* Constructor. Sets the decoration type to the given value. If it is not
* valid, the representation is set to none
*/
PlaneOrientationProperty( const std::string &value );
/**
* this function is overridden as protected, so that the user may not add
* additional invalid types.
*/
virtual bool AddEnum( const std::string &name, const IdType &id );
/**
* Adds the standard enumeration types with corresponding strings.
*/
virtual void AddDecorationTypes();
private:
// purposely not implemented
PlaneOrientationProperty(const PlaneOrientationProperty&);
PlaneOrientationProperty& operator=(const PlaneOrientationProperty&);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // end of namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkPointOperation.cpp b/Core/Code/DataManagement/mitkPointOperation.cpp
index d52a692367..8c413f89d0 100755
--- a/Core/Code/DataManagement/mitkPointOperation.cpp
+++ b/Core/Code/DataManagement/mitkPointOperation.cpp
@@ -1,56 +1,55 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointOperation.h"
mitk::PointOperation::PointOperation(OperationType operationType, Point3D point, int index, bool selected, PointSpecificationType type)
: mitk::Operation(operationType), m_Point(point), m_Index(index), m_Selected(selected), m_Type(type), m_TimeInMS(0)
{}
mitk::PointOperation::PointOperation(OperationType operationType, ScalarType timeInMS, Point3D point, int index, bool selected, PointSpecificationType type)
: mitk::Operation(operationType), m_Point(point), m_Index(index), m_Selected(selected), m_Type(type), m_TimeInMS(timeInMS)
{}
mitk::PointOperation::~PointOperation()
{
}
mitk::Point3D mitk::PointOperation::GetPoint()
{
return m_Point;
}
int mitk::PointOperation::GetIndex()
{
return m_Index;
}
bool mitk::PointOperation::GetSelected()
{
return m_Selected;
}
mitk::PointSpecificationType mitk::PointOperation::GetPointType()
{
return m_Type;
}
mitk::ScalarType mitk::PointOperation::GetTimeInMS() const
{
return m_TimeInMS;
}
diff --git a/Core/Code/DataManagement/mitkPointOperation.h b/Core/Code/DataManagement/mitkPointOperation.h
index fabb5fe608..4ee6b49d65 100755
--- a/Core/Code/DataManagement/mitkPointOperation.h
+++ b/Core/Code/DataManagement/mitkPointOperation.h
@@ -1,85 +1,84 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPOINTOPERATION_H
#define MITKPOINTOPERATION_H
#include <MitkExports.h>
#include "mitkOperation.h"
#include "mitkVector.h"
namespace mitk {
//##Documentation
//## @brief Operation that handles all actions on one Point.
//##
//## Stores everything for Adding, Moving and Deleting a Point.
//## @ingroup Undo
class MITK_CORE_EXPORT PointOperation : public Operation
{
public:
//##Documentation
//##@brief Operation that handles all actions on one Point.
//##
//## @param operationType is the type of the operation (see mitkOperation.h; e.g. move or add; Information for StateMachine::ExecuteOperation());
//## @param point is the information of the point to add or is the information to change a point into
//## @param index is e.g. the position in a list which describes the element to change
PointOperation(OperationType operationType, Point3D point, int index = -1, bool selected = true, PointSpecificationType type = PTUNDEFINED);
//##Documentation
//##@brief Operation that handles all actions on one Point.
//##
//## @param operationType is the type of the operation (see mitkOperation.h; e.g. move or add; Information for StateMachine::ExecuteOperation());
//## @param point is the information of the point to add or is the information to change a point into
//## @param index is e.g. the position in a list which describes the element to change
PointOperation(OperationType operationType, ScalarType timeInMS, Point3D point, int index = -1, bool selected = true, PointSpecificationType type = PTUNDEFINED);
virtual ~PointOperation();
Point3D GetPoint();
int GetIndex();
bool GetSelected();
PointSpecificationType GetPointType();
ScalarType GetTimeInMS() const;
private:
Point3D m_Point;
//##Documentation
//##@brief to declare an index where to store the point in data
int m_Index;
//to declare weather the point is selected or deselected
bool m_Selected;
//##Documentation
//##@brief to describe the type of the point. See enum PointSpecification for different types
PointSpecificationType m_Type;
ScalarType m_TimeInMS;
};
}//namespace mitk
#endif /* MITKPOINTOPERATION_H*/
diff --git a/Core/Code/DataManagement/mitkPointSet.cpp b/Core/Code/DataManagement/mitkPointSet.cpp
index b49a91d3e4..b98affc4c8 100755
--- a/Core/Code/DataManagement/mitkPointSet.cpp
+++ b/Core/Code/DataManagement/mitkPointSet.cpp
@@ -1,787 +1,786 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSet.h"
#include "mitkPointOperation.h"
#include "mitkInteractionConst.h"
mitk::PointSet::PointSet()
{
this->InitializeEmpty();
}
mitk::PointSet::PointSet(const PointSet &other): BaseData(other)
{
this->Expand(other.GetTimeSteps());
for (unsigned int t=0; t < other.GetTimeSteps(); t++)
{
for (int i=0; i< other.GetSize(t); i++)
{
this->InsertPoint(i, other.GetPoint(i,t), t);
}
}
this->SetGeometry(other.GetGeometry());
}
mitk::PointSet::~PointSet()
{
this->ClearData();
}
void mitk::PointSet::ClearData()
{
m_PointSetSeries.clear();
Superclass::ClearData();
}
void mitk::PointSet::InitializeEmpty()
{
m_PointSetSeries.resize( 1 );
m_PointSetSeries[0] = DataType::New();
PointDataContainer::Pointer pointData = PointDataContainer::New();
m_PointSetSeries[0]->SetPointData( pointData );
m_CalculateBoundingBox = false;
Superclass::InitializeTimeSlicedGeometry(1);
m_Initialized = true;
}
bool mitk::PointSet::IsEmptyTimeStep(unsigned int t) const
{
return IsInitialized() && (GetSize(t) == 0);
}
void mitk::PointSet::Expand( unsigned int timeSteps )
{
// Check if the vector is long enough to contain the new element
// at the given position. If not, expand it with sufficient pre-initialized
// elements.
//
// NOTE: This method will never REDUCE the vector size; it should only
// be used to make sure that the vector has enough elements to include the
// specified time step.
unsigned int oldSize = m_PointSetSeries.size();
if ( timeSteps > oldSize )
{
Superclass::Expand( timeSteps );
m_PointSetSeries.resize( timeSteps );
for ( unsigned int i = oldSize; i < timeSteps; ++i )
{
m_PointSetSeries[i] = DataType::New();
PointDataContainer::Pointer pointData = PointDataContainer::New();
m_PointSetSeries[i]->SetPointData( pointData );
}
//if the size changes, then compute the bounding box
m_CalculateBoundingBox = true;
this->InvokeEvent( PointSetExtendTimeRangeEvent() );
}
}
unsigned int mitk::PointSet::GetPointSetSeriesSize() const
{
return m_PointSetSeries.size();
}
int mitk::PointSet::GetSize( unsigned int t ) const
{
if ( t < m_PointSetSeries.size() )
{
return m_PointSetSeries[t]->GetNumberOfPoints();
}
else
{
return 0;
}
}
mitk::PointSet::DataType::Pointer mitk::PointSet::GetPointSet( int t ) const
{
if ( t < (int)m_PointSetSeries.size() )
{
return m_PointSetSeries[t];
}
else
{
return NULL;
}
}
int mitk::PointSet::SearchPoint( Point3D point, float distance, int t ) const
{
if ( t >= (int)m_PointSetSeries.size() )
{
return -1;
}
// Out is the point which is checked to be the searched point
PointType out;
out.Fill( 0 );
PointType indexPoint;
this->GetGeometry( t )->WorldToIndex(point, indexPoint);
// Searching the first point in the Set, that is +- distance far away fro
// the given point
unsigned int i;
PointsContainer::Iterator it, end;
end = m_PointSetSeries[t]->GetPoints()->End();
int bestIndex = -1;
distance = distance * distance;
// To correct errors from converting index to world and world to index
if (distance == 0.0)
{
distance = 0.000001;
}
ScalarType bestDist = distance;
ScalarType dist, tmp;
for ( it = m_PointSetSeries[t]->GetPoints()->Begin(), i = 0;
it != end;
++it, ++i )
{
bool ok = m_PointSetSeries[t]->GetPoints()
->GetElementIfIndexExists( it->Index(), &out );
if ( !ok )
{
return -1;
}
else if ( indexPoint == out ) //if totally equal
{
return it->Index();
}
//distance calculation
tmp = out[0] - indexPoint[0]; dist = tmp * tmp;
tmp = out[1] - indexPoint[1]; dist += tmp * tmp;
tmp = out[2] - indexPoint[2]; dist += tmp * tmp;
if ( dist < bestDist )
{
bestIndex = it->Index();
bestDist = dist;
}
}
return bestIndex;
}
mitk::PointSet::PointType
mitk::PointSet::GetPoint( PointIdentifier id, int t ) const
{
PointType out;
out.Fill(0);
if ( (unsigned int) t >= m_PointSetSeries.size() )
{
return out;
}
if ( m_PointSetSeries[t]->GetPoints()->IndexExists(id) )
{
m_PointSetSeries[t]->GetPoint( id, &out );
this->GetGeometry(t)->IndexToWorld( out, out );
return out;
}
else
{
return out;
}
}
bool
mitk::PointSet
::GetPointIfExists( PointIdentifier id, PointType* point, int t ) const
{
if ( (unsigned int) t >= m_PointSetSeries.size() )
{
return false;
}
if ( m_PointSetSeries[t]->GetPoints()->GetElementIfIndexExists(id, point) )
{
this->GetGeometry( t )->IndexToWorld( *point, *point );
return true;
}
else
{
return false;
}
}
void mitk::PointSet::SetPoint( PointIdentifier id, PointType point, int t )
{
// Adapt the size of the data vector if necessary
this->Expand( t+1 );
mitk::Point3D indexPoint;
this->GetGeometry( t )->WorldToIndex( point, indexPoint );
m_PointSetSeries[t]->SetPoint( id, indexPoint );
PointDataType defaultPointData;
defaultPointData.id = id;
defaultPointData.selected = false;
defaultPointData.pointSpec = mitk::PTUNDEFINED;
m_PointSetSeries[t]->SetPointData( id, defaultPointData );
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->Modified();
}
void mitk::PointSet::SetPoint( PointIdentifier id, PointType point, PointSpecificationType spec, int t )
{
// Adapt the size of the data vector if necessary
this->Expand( t+1 );
mitk::Point3D indexPoint;
this->GetGeometry( t )->WorldToIndex( point, indexPoint );
m_PointSetSeries[t]->SetPoint( id, indexPoint );
PointDataType defaultPointData;
defaultPointData.id = id;
defaultPointData.selected = false;
defaultPointData.pointSpec = spec;
m_PointSetSeries[t]->SetPointData( id, defaultPointData );
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->Modified();
}
void mitk::PointSet::InsertPoint( PointIdentifier id, PointType point, int t )
{
if ( (unsigned int) t < m_PointSetSeries.size() )
{
mitk::Point3D indexPoint;
mitk::Geometry3D* tempGeometry = this->GetGeometry( t );
if (tempGeometry == NULL)
{
MITK_INFO<< __FILE__ << ", l." << __LINE__ << ": GetGeometry of "<< t <<" returned NULL!" << std::endl;
return;
}
tempGeometry->WorldToIndex( point, indexPoint );
m_PointSetSeries[t]->GetPoints()->InsertElement( id, indexPoint );
PointDataType defaultPointData;
defaultPointData.id = id;
defaultPointData.selected = false;
defaultPointData.pointSpec = mitk::PTUNDEFINED;
m_PointSetSeries[t]->GetPointData()->InsertElement(id, defaultPointData);
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->Modified();
}
}
void mitk::PointSet::InsertPoint( PointIdentifier id, PointType point, PointSpecificationType spec, int t )
{
if ( (unsigned int) t < m_PointSetSeries.size() )
{
mitk::Point3D indexPoint;
mitk::Geometry3D* tempGeometry = this->GetGeometry( t );
if (tempGeometry == NULL)
{
MITK_INFO<< __FILE__ << ", l." << __LINE__ << ": GetGeometry of "<< t <<" returned NULL!" << std::endl;
return;
}
tempGeometry->WorldToIndex( point, indexPoint );
m_PointSetSeries[t]->GetPoints()->InsertElement( id, indexPoint );
PointDataType defaultPointData;
defaultPointData.id = id;
defaultPointData.selected = false;
defaultPointData.pointSpec = spec;
m_PointSetSeries[t]->GetPointData()->InsertElement(id, defaultPointData);
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->Modified();
}
}
bool mitk::PointSet::SwapPointPosition( PointIdentifier id, bool moveUpwards, int t )
{
if(IndexExists(id, t) )
{
PointType point = GetPoint(id,t);
if(moveUpwards)
{//up
if(IndexExists(id-1,t))
{
InsertPoint(id, GetPoint(id - 1, t), t);
InsertPoint(id-1,point,t);
this->Modified();
return true;
}
}
else
{//down
if(IndexExists(id+1,t))
{
InsertPoint(id, GetPoint(id + 1, t), t);
InsertPoint(id+1,point,t);
this->Modified();
return true;
}
}
}
return false;
}
bool mitk::PointSet::IndexExists( int position, int t ) const
{
if ( (unsigned int) t < m_PointSetSeries.size() )
{
return m_PointSetSeries[t]->GetPoints()->IndexExists( position );
}
else
{
return false;
}
}
bool mitk::PointSet::GetSelectInfo( int position, int t ) const
{
if ( this->IndexExists( position, t ) )
{
PointDataType pointData = { 0, false, PTUNDEFINED };
m_PointSetSeries[t]->GetPointData( position, &pointData );
return pointData.selected;
}
else
{
return false;
}
}
void mitk::PointSet::SetSelectInfo( int position, bool selected, int t )
{
if ( this->IndexExists( position, t ) )
{
// timeStep to ms
ScalarType timeInMS = this->GetTimeSlicedGeometry()->TimeStepToMS( t );
// point
Point3D point = this->GetPoint( position, t );
PointOperation* op;
if (selected)
{
op = new mitk::PointOperation(OpSELECTPOINT, timeInMS, point, position );
}
else
{
op = new mitk::PointOperation(OpDESELECTPOINT, timeInMS, point, position );
}
this->ExecuteOperation( op );
}
}
mitk::PointSpecificationType mitk::PointSet::GetSpecificationTypeInfo( int position, int t ) const
{
if ( this->IndexExists( position, t ) )
{
PointDataType pointData = { 0, false, PTUNDEFINED };
m_PointSetSeries[t]->GetPointData( position, &pointData );
return pointData.pointSpec;
}
else
{
return PTUNDEFINED;
}
}
int mitk::PointSet::GetNumberOfSelected( int t ) const
{
if ( (unsigned int) t >= m_PointSetSeries.size() )
{
return 0;
}
int numberOfSelected = 0;
PointDataIterator it;
for ( it = m_PointSetSeries[t]->GetPointData()->Begin();
it != m_PointSetSeries[t]->GetPointData()->End();
it++ )
{
if (it->Value().selected == true)
{
++numberOfSelected;
}
}
return numberOfSelected;
}
int mitk::PointSet::SearchSelectedPoint( int t ) const
{
if ( (unsigned int) t >= m_PointSetSeries.size() )
{
return -1;
}
PointDataIterator it;
for ( it = m_PointSetSeries[t]->GetPointData()->Begin();
it != m_PointSetSeries[t]->GetPointData()->End();
it++ )
{
if ( it->Value().selected == true )
{
return it->Index();
}
}
return -1;
}
void mitk::PointSet::ExecuteOperation( Operation* operation )
{
int timeStep = -1;
mitkCheckOperationTypeMacro(PointOperation, operation, pointOp);
if ( pointOp )
{
timeStep = this->GetTimeSlicedGeometry()
->MSToTimeStep( pointOp->GetTimeInMS() );
}
if ( timeStep < 0 )
{
MITK_ERROR << "Time step (" << timeStep << ") outside of PointSet time bounds" << std::endl;
return;
}
switch (operation->GetOperationType())
{
case OpNOTHING:
break;
case OpINSERT://inserts the point at the given position and selects it.
{
int position = pointOp->GetIndex();
PointType pt;
pt.CastFrom(pointOp->GetPoint());
//transfer from world to index coordinates
mitk::Geometry3D* geometry = this->GetGeometry( timeStep );
if (geometry == NULL)
{
MITK_INFO<<"GetGeometry returned NULL!\n";
return;
}
geometry->WorldToIndex(pt, pt);
m_PointSetSeries[timeStep]->GetPoints()->InsertElement(position, pt);
PointDataType pointData =
{
pointOp->GetIndex(),
pointOp->GetSelected(),
pointOp->GetPointType()
};
m_PointSetSeries[timeStep]->GetPointData()
->InsertElement(position, pointData);
this->Modified();
//boundingbox has to be computed
m_CalculateBoundingBox = true;
this->InvokeEvent( PointSetAddEvent() );
this->OnPointSetChange();
}
break;
case OpMOVE://moves the point given by index
{
PointType pt;
pt.CastFrom(pointOp->GetPoint());
//transfer from world to index coordinates
this->GetGeometry( timeStep )->WorldToIndex(pt, pt);
// Copy new point into container
m_PointSetSeries[timeStep]->SetPoint(pointOp->GetIndex(), pt);
// Insert a default point data object to keep the containers in sync
// (if no point data object exists yet)
PointDataType pointData;
if ( !m_PointSetSeries[timeStep]->GetPointData( pointOp->GetIndex(), &pointData ) )
{
m_PointSetSeries[timeStep]->SetPointData( pointOp->GetIndex(), pointData );
}
this->OnPointSetChange();
this->Modified();
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->InvokeEvent( PointSetMoveEvent() );
}
break;
case OpREMOVE://removes the point at given by position
{
m_PointSetSeries[timeStep]->GetPoints()->DeleteIndex((unsigned)pointOp->GetIndex());
m_PointSetSeries[timeStep]->GetPointData()->DeleteIndex((unsigned)pointOp->GetIndex());
this->OnPointSetChange();
this->Modified();
//boundingbox has to be computed anyway
m_CalculateBoundingBox = true;
this->InvokeEvent( PointSetRemoveEvent() );
}
break;
case OpSELECTPOINT://select the given point
{
PointDataType pointData = {0, false, PTUNDEFINED};
m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
pointData.selected = true;
m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
this->Modified();
}
break;
case OpDESELECTPOINT://unselect the given point
{
PointDataType pointData = {0, false, PTUNDEFINED};
m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
pointData.selected = false;
m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
this->Modified();
}
break;
case OpSETPOINTTYPE:
{
PointDataType pointData = {0, false, PTUNDEFINED};
m_PointSetSeries[timeStep]->GetPointData(pointOp->GetIndex(), &pointData);
pointData.pointSpec = pointOp->GetPointType();
m_PointSetSeries[timeStep]->SetPointData(pointOp->GetIndex(), pointData);
this->Modified();
}
break;
case OpMOVEPOINTUP: // swap content of point with ID pointOp->GetIndex() with the point preceding it in the container // move point position within the pointset
{
PointIdentifier currentID = pointOp->GetIndex();
/* search for point with this id and point that precedes this one in the data container */
PointsContainer::STLContainerType points = m_PointSetSeries[timeStep]->GetPoints()->CastToSTLContainer();
PointsContainer::STLContainerType::iterator it = points.find(currentID);
if (it == points.end()) // ID not found
break;
if (it == points.begin()) // we are at the first element, there is no previous element
break;
/* get and cache current point & pointdata and previous point & pointdata */
--it;
PointIdentifier prevID = it->first;
if (this->SwapPointContents(prevID, currentID, timeStep) == true)
this->Modified();
}
break;
case OpMOVEPOINTDOWN: // move point position within the pointset
{
PointIdentifier currentID = pointOp->GetIndex();
/* search for point with this id and point that succeeds this one in the data container */
PointsContainer::STLContainerType points = m_PointSetSeries[timeStep]->GetPoints()->CastToSTLContainer();
PointsContainer::STLContainerType::iterator it = points.find(currentID);
if (it == points.end()) // ID not found
break;
++it;
if (it == points.end()) // ID is already the last element, there is no succeeding element
break;
/* get and cache current point & pointdata and previous point & pointdata */
PointIdentifier nextID = it->first;
if (this->SwapPointContents(nextID, currentID, timeStep) == true)
this->Modified();
}
break;
default:
itkWarningMacro("mitkPointSet could not understrand the operation. Please check!");
break;
}
//to tell the mappers, that the data is modified and has to be updated
//only call modified if anything is done, so call in cases
//this->Modified();
mitk::OperationEndEvent endevent(operation);
((const itk::Object*)this)->InvokeEvent(endevent);
//*todo has to be done here, cause of update-pipeline not working yet
// As discussed lately, don't mess with the rendering from inside data structures
//mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void mitk::PointSet::UpdateOutputInformation()
{
if ( this->GetSource( ) )
{
this->GetSource( )->UpdateOutputInformation( );
}
//
// first make sure, that the associated time sliced geometry has
// the same number of geometry 3d's as PointSets are present
//
mitk::TimeSlicedGeometry* timeGeometry = GetTimeSlicedGeometry();
if ( timeGeometry->GetTimeSteps() != m_PointSetSeries.size() )
{
itkExceptionMacro(<<"timeGeometry->GetTimeSteps() != m_PointSetSeries.size() -- use Initialize(timeSteps) with correct number of timeSteps!");
}
// This is needed to detect zero objects
mitk::ScalarType nullpoint[]={0,0,0,0,0,0};
BoundingBox::BoundsArrayType itkBoundsNull(nullpoint);
//
// Iterate over the PointSets and update the Geometry
// information of each of the items.
//
if (m_CalculateBoundingBox)
{
for ( unsigned int i = 0 ; i < m_PointSetSeries.size() ; ++i )
{
const DataType::BoundingBoxType *bb = m_PointSetSeries[i]->GetBoundingBox();
BoundingBox::BoundsArrayType itkBounds = bb->GetBounds();
if ( m_PointSetSeries[i].IsNull() || (m_PointSetSeries[i]->GetNumberOfPoints() == 0)
|| (itkBounds == itkBoundsNull) )
{
itkBounds = itkBoundsNull;
continue;
}
// Ensure minimal bounds of 1.0 in each dimension
for ( unsigned int j = 0; j < 3; ++j )
{
if ( itkBounds[j*2+1] - itkBounds[j*2] < 1.0 )
{
BoundingBox::CoordRepType center =
(itkBounds[j*2] + itkBounds[j*2+1]) / 2.0;
itkBounds[j*2] = center - 0.5;
itkBounds[j*2+1] = center + 0.5;
}
}
this->GetGeometry(i)->SetBounds(itkBounds);
}
m_CalculateBoundingBox = false;
}
this->GetTimeSlicedGeometry()->UpdateInformation();
}
void mitk::PointSet::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::PointSet::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::PointSet::VerifyRequestedRegion()
{
return true;
}
void mitk::PointSet::SetRequestedRegion( itk::DataObject * )
{
}
void mitk::PointSet::PrintSelf( std::ostream& os, itk::Indent indent ) const
{
Superclass::PrintSelf(os, indent);
os << indent << "Number timesteps: " << m_PointSetSeries.size() << "\n";
unsigned int i = 0;
for (PointSetSeries::const_iterator it = m_PointSetSeries.begin(); it != m_PointSetSeries.end(); ++it)
{
os << indent << "Timestep " << i++ << ": \n";
MeshType::Pointer ps = *it;
itk::Indent nextIndent = indent.GetNextIndent();
ps->Print(os, nextIndent);
MeshType::PointsContainer* points = ps->GetPoints();
MeshType::PointDataContainer* datas = ps->GetPointData();
MeshType::PointDataContainer::Iterator dataIterator = datas->Begin();
for (MeshType::PointsContainer::Iterator pointIterator = points->Begin();
pointIterator != points->End();
++pointIterator, ++dataIterator)
{
os << nextIndent << "Point " << pointIterator->Index() << ": [";
os << pointIterator->Value().GetElement(0);
for (unsigned int i = 1; i < PointType::GetPointDimension(); ++i)
{
os << ", " << pointIterator->Value().GetElement(i);
}
os << "]";
os << ", selected: " << dataIterator->Value().selected << ", point spec: " << dataIterator->Value().pointSpec << "\n";
}
}
}
bool mitk::PointSet::SwapPointContents(PointIdentifier id1, PointIdentifier id2, int timeStep)
{
/* search and cache contents */
PointType p1;
if (m_PointSetSeries[timeStep]->GetPoint(id1, &p1) == false)
return false;
PointDataType data1;
if (m_PointSetSeries[timeStep]->GetPointData(id1, &data1) == false)
return false;
PointType p2;
if (m_PointSetSeries[timeStep]->GetPoint(id2, &p2) == false)
return false;
PointDataType data2;
if (m_PointSetSeries[timeStep]->GetPointData(id2, &data2) == false)
return false;
/* now swap contents */
m_PointSetSeries[timeStep]->SetPoint(id1, p2);
m_PointSetSeries[timeStep]->SetPointData(id1, data2);
m_PointSetSeries[timeStep]->SetPoint(id2, p1);
m_PointSetSeries[timeStep]->SetPointData(id2, data1);
return true;
}
diff --git a/Core/Code/DataManagement/mitkPointSet.h b/Core/Code/DataManagement/mitkPointSet.h
index e0f03d657d..5500901c7d 100755
--- a/Core/Code/DataManagement/mitkPointSet.h
+++ b/Core/Code/DataManagement/mitkPointSet.h
@@ -1,275 +1,274 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPointSet_H_HEADER_INCLUDED
#define MITKPointSet_H_HEADER_INCLUDED
#include "mitkBaseData.h"
#include <itkMesh.h>
#include <itkDefaultDynamicMeshTraits.h>
namespace mitk {
/**
* \brief Data structure which stores a set of points. Superclass of
* mitk::Mesh.
*
* 3D points are grouped within a point set; for time resolved usage, one point
* set is created and maintained per time step. A point entry consists of the
* point coordinates and point data.
*
* The point data includes a point ID (unique identifier to address this point
* within the point set), the selection state of the point and the type of
* the point.
*
* For further information about different point types see
* mitk::PointSpecificationType in mitkVector.h.
*
* Inserting a point is accompanied by an event, containing an index. The new
* point is inserted into the list at the specified position. At the same time
* an internal ID is generated and stored for the point. Points at specific time
* steps are accessed by specifying the time step number (which defaults to 0).
*
* The points of itk::PointSet stores the points in a pointContainer
* (MapContainer). The points are best accessed by using a ConstIterator (as
* defined in MapContainer); avoid access via index.
*
* The class internally uses an itk::Mesh for each time step, because
* mitk::Mesh is derived from mitk::PointSet and needs the itk::Mesh structure
* which is also derived from itk::PointSet. Thus several typedefs which seem
* to be in wrong place, are declared here (for example SelectedLinesType).
*
* \section mitkPointSetDisplayOptions
*
* The default mappers for this data structure are mitk::PointSetGLMapper2D and
* mitk::PointSetVtkMapper3D. See these classes for display options which can
* can be set via properties.
*
* \section Events
*
* PointSet issues the following events, for which observers can register
* (the below events are grouped into a class hierarchy as indicated by
* identation level; e.g. PointSetSizeChangeEvent comprises PointSetAddEvent
* and PointSetRemoveEvent):
*
* <tt>
* PointSetEvent <i>subsumes all PointSet events</i>
* PointSetMoveEvent <i>issued when a point of the PointSet is moved</i>
* PointSetSizeChangeEvent <i>subsumes add and remove events</i>
* PointSetAddEvent <i>issued when a point is added to the PointSet</i>
* PointSetRemoveEvent <i>issued when a point is removed from the PointSet</i>
* </tt>
* \ingroup PSIO
* \ingroup Data
*/
class MITK_CORE_EXPORT PointSet : public BaseData
{
public:
mitkClassMacro(PointSet, BaseData);
itkNewMacro(Self);
mitkCloneMacro(PointSet);
typedef mitk::ScalarType CoordinateType;
typedef mitk::ScalarType InterpolationWeightType;
static const unsigned int PointDimension = 3;
static const unsigned int MaxTopologicalDimension = 3;
/**
* \brief struct for data of a point
*/
struct PointDataType
{
unsigned int id; //to give the point a special ID
bool selected; //information about if the point is selected
mitk::PointSpecificationType pointSpec; //specifies the type of the point
};
/**
* \brief cellDataType, that stores all indexes of the lines, that are
* selected e.g.: points A,B and C.Between A and B there is a line with
* index 0. If vector of cellData contains 1 and 2, then the lines between
* B and C and C and A is selected.
*/
typedef std::vector<unsigned int> SelectedLinesType;
typedef SelectedLinesType::iterator SelectedLinesIter;
struct CellDataType
{
//used to set the whole cell on selected
bool selected;
//indexes of selected lines. 0 is between pointId 0 and 1
SelectedLinesType selectedLines;
//is the polygon already finished and closed
bool closed;
};
typedef itk::DefaultDynamicMeshTraits<
PointDataType, PointDimension, MaxTopologicalDimension,
CoordinateType, InterpolationWeightType, CellDataType > MeshTraits;
typedef itk::Mesh<PointDataType, PointDimension, MeshTraits> MeshType;
typedef MeshType DataType;
typedef DataType::PointType PointType;
typedef DataType::PointIdentifier PointIdentifier;
typedef DataType::PointsContainer PointsContainer;
typedef DataType::PointsContainerIterator PointsIterator;
typedef DataType::PointsContainer::ConstIterator PointsConstIterator;
typedef DataType::PointDataContainer PointDataContainer;
typedef DataType::PointDataContainerIterator PointDataIterator;
virtual void Expand( unsigned int timeSteps );
/** \brief executes the given Operation */
virtual void ExecuteOperation(Operation* operation);
/** \brief returns the current size of the point-list */
virtual int GetSize( unsigned int t = 0 ) const;
virtual unsigned int GetPointSetSeriesSize() const;
/** \brief returns the pointset */
virtual DataType::Pointer GetPointSet( int t = 0 ) const;
/**
* \brief Get the point with ID id in world coordinates
*
* check if the ID exists. If it doesn't exist, then return 0,0,0
*/
PointType GetPoint( PointIdentifier id, int t = 0 ) const;
/**
* \brief Get the point with ID id in world coordinates
*
* If a point exists for the ID id, the point is returned in the parameter point
* and the method returns true. If the ID does not exist, the method returns false
*/
bool GetPointIfExists( PointIdentifier id, PointType* point, int t = 0 ) const;
/**
* \brief Set the given point in world coordinate system into the itkPointSet.
*/
void SetPoint( PointIdentifier id, PointType point, int t = 0 );
/**
* \brief Set the given point in world coordinate system with the given PointSpecificationType
*/
void SetPoint( PointIdentifier id, PointType point, PointSpecificationType spec, int t = 0 );
/**
* \brief Set the given point in world coordinate system into the itkPointSet.
*/
void InsertPoint( PointIdentifier id, PointType point, int t = 0 );
/**
* \brief Set the given point in world coordinate system with given PointSpecificationType
*/
void InsertPoint( PointIdentifier id, PointType point, PointSpecificationType spec, int t );
/**
* \brief Swap a point at the given position (id) with the upper point (moveUpwards=true) or with the lower point (moveUpwards=false).
* If upper or lower index does not exist false is returned, if swap was successful true.
*/
bool SwapPointPosition( PointIdentifier id, bool moveUpwards, int t = 0 );
/**
* \brief searches a selected point and returns the id of that point.
* If no point is found, then -1 is returned
*/
virtual int SearchSelectedPoint( int t = 0 ) const;
/** \brief returns true if a point exists at this position */
virtual bool IndexExists( int position, int t = 0 ) const;
/** \brief to get the state selected/unselected of the point on the
* position
*/
virtual bool GetSelectInfo( int position, int t = 0 ) const;
virtual void SetSelectInfo( int position, bool selected, int t = 0 );
/** \brief to get the type of the point at the position and the moment */
virtual PointSpecificationType GetSpecificationTypeInfo( int position, int t ) const;
/** \brief returns the number of selected points */
virtual int GetNumberOfSelected( int t = 0 ) const;
/**
* \brief searches a point in the list == point +/- distance
*
* \param point is in world coordinates.
* \param distance is in mm.
* returns -1 if no point is found
* or the position in the list of the first match
*/
int SearchPoint( Point3D point, float distance, int t = 0 ) const;
virtual bool IsEmptyTimeStep(unsigned int t) const;
//virtual methods, that need to be implemented
virtual void UpdateOutputInformation();
virtual void SetRequestedRegionToLargestPossibleRegion();
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
virtual bool VerifyRequestedRegion();
virtual void SetRequestedRegion(itk::DataObject *data);
//Method for subclasses
virtual void OnPointSetChange(){};
protected:
PointSet();
PointSet(const PointSet &other);
virtual ~PointSet();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; ///< print content of the object to os
virtual void ClearData();
virtual void InitializeEmpty();
/** \brief swaps point coordinates and point data of the points with identifiers id1 and id2 */
bool SwapPointContents(PointIdentifier id1, PointIdentifier id2, int t = 0 );
typedef std::vector< DataType::Pointer > PointSetSeries;
PointSetSeries m_PointSetSeries;
/**
* @brief flag to indicate the right time to call SetBounds
**/
bool m_CalculateBoundingBox;
};
#pragma GCC visibility push(default)
itkEventMacro( PointSetEvent, itk::AnyEvent );
itkEventMacro( PointSetMoveEvent, PointSetEvent );
itkEventMacro( PointSetSizeChangeEvent, PointSetEvent );
itkEventMacro( PointSetAddEvent, PointSetSizeChangeEvent );
itkEventMacro( PointSetRemoveEvent, PointSetSizeChangeEvent );
itkEventMacro( PointSetExtendTimeRangeEvent, PointSetEvent );
#pragma GCC visibility pop
} // namespace mitk
#endif /* MITKPointSet_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkProperties.cpp b/Core/Code/DataManagement/mitkProperties.cpp
index 11577cb3a3..c5e0d697f1 100644
--- a/Core/Code/DataManagement/mitkProperties.cpp
+++ b/Core/Code/DataManagement/mitkProperties.cpp
@@ -1,40 +1,39 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkProperties.h"
mitkDefineGenericProperty(BoolProperty,bool,false);
mitkDefineGenericProperty(IntProperty,int,0);
mitkDefineGenericProperty(FloatProperty,float,0.0f);
mitkDefineGenericProperty(DoubleProperty,double,0.0);
mitkDefineGenericProperty(Vector3DProperty,Vector3D,Vector3D(0.0f));
mitkDefineGenericProperty(Point3dProperty,Point3D,Point3D::BaseArray::Filled(0.0f).GetDataPointer() );
mitkDefineGenericProperty(Point4dProperty,Point4D,Point4D::BaseArray::Filled(0.0f).GetDataPointer() );
mitkDefineGenericProperty(Point3iProperty,Point3I,Point3I::BaseArray::Filled(0).GetDataPointer() );
mitkDefineGenericProperty(FloatLookupTableProperty, FloatLookupTable, FloatLookupTable());
mitkDefineGenericProperty(BoolLookupTableProperty, BoolLookupTable, BoolLookupTable());
mitkDefineGenericProperty(IntLookupTableProperty, IntLookupTable, IntLookupTable());
mitkDefineGenericProperty(StringLookupTableProperty, StringLookupTable, StringLookupTable());
diff --git a/Core/Code/DataManagement/mitkProperties.h b/Core/Code/DataManagement/mitkProperties.h
index 2c66d595f8..efa3b645de 100644
--- a/Core/Code/DataManagement/mitkProperties.h
+++ b/Core/Code/DataManagement/mitkProperties.h
@@ -1,53 +1,52 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPROPERTIES_H_HEADER_INCLUDED
#define MITKPROPERTIES_H_HEADER_INCLUDED
#include "mitkGenericProperty.h"
#include "mitkVector.h"
#include "mitkLookupTables.h"
namespace mitk {
mitkDeclareGenericProperty(BoolProperty,bool,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(IntProperty,int,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(FloatProperty,float,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(DoubleProperty,double,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(Vector3DProperty,Vector3D,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(Point3dProperty,Point3D,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(Point4dProperty,Point4D,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(Point3iProperty,Point3I,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(FloatLookupTableProperty, FloatLookupTable,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(BoolLookupTableProperty, BoolLookupTable,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(IntLookupTableProperty, IntLookupTable,MITK_CORE_EXPORT);
mitkDeclareGenericProperty(StringLookupTableProperty, StringLookupTable,MITK_CORE_EXPORT);
/**
* \warning If you add more specialization of GenericProperty, you must also add these to the
* templated GetPropertyValue() method in mitkPropertyList.cpp!
*/
} // namespace mitk
#endif /* MITKPROPERTIES_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkPropertyList.cpp b/Core/Code/DataManagement/mitkPropertyList.cpp
index 5ccbcb0e5b..9f917165dc 100644
--- a/Core/Code/DataManagement/mitkPropertyList.cpp
+++ b/Core/Code/DataManagement/mitkPropertyList.cpp
@@ -1,281 +1,280 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPropertyList.h"
#include "mitkProperties.h"
#include "mitkStringProperty.h"
#include "mitkVector.h"
mitk::BaseProperty* mitk::PropertyList::GetProperty(const std::string& propertyKey) const
{
PropertyMap::const_iterator it;
it=m_Properties.find( propertyKey );
if(it!=m_Properties.end())
return it->second;
else
return NULL;
}
void mitk::PropertyList::SetProperty(const std::string& propertyKey, BaseProperty* property)
{
if (!property) return;
//make sure that BaseProperty*, which may have just been created and never been
//assigned to a SmartPointer, is registered/unregistered properly. If we do not
//do that, it will a) not deleted in case it is identical to the old one or
//b) possibly deleted when temporarily added to a smartpointer somewhere below.
BaseProperty::Pointer tmpSmartPointerToProperty = property;
PropertyMap::iterator it( m_Properties.find( propertyKey ) );
// Is a property with key @a propertyKey contained in the list?
if( it != m_Properties.end() )
{
// yes
//is the property contained in the list identical to the new one?
if( it->second->operator==(*property) )
{
// yes? do nothing and return.
return;
}
if (it->second->AssignProperty(*property))
{
// The assignment was successfull
this->Modified();
}
else
{
MITK_ERROR << "In " __FILE__ ", l." << __LINE__
<< ": Trying to set existing property " << it->first << " of type " << it->second->GetNameOfClass()
<< " to a property with different type " << property->GetNameOfClass() << "."
<< " Use ReplaceProperty() instead."
<< std::endl;
}
return;
}
//no? add it.
PropertyMapElementType newProp;
newProp.first = propertyKey;
newProp.second = property;
m_Properties.insert ( newProp );
this->Modified();
}
void mitk::PropertyList::ReplaceProperty(const std::string& propertyKey, BaseProperty* property)
{
if (!property) return;
PropertyMap::iterator it( m_Properties.find( propertyKey ) );
// Is a property with key @a propertyKey contained in the list?
if( it != m_Properties.end() )
{
it->second=NULL;
m_Properties.erase(it);
}
//no? add/replace it.
PropertyMapElementType newProp;
newProp.first = propertyKey;
newProp.second = property;
m_Properties.insert ( newProp );
Modified();
}
mitk::PropertyList::PropertyList()
{
}
mitk::PropertyList::~PropertyList()
{
Clear();
}
/**
* Consider the list as changed when any of the properties has changed recently.
*/
unsigned long mitk::PropertyList::GetMTime() const
{
for ( PropertyMap::const_iterator it = m_Properties.begin() ;
it != m_Properties.end();
++it )
{
if( it->second.IsNull() )
{
itkWarningMacro(<< "Property '" << it->first <<"' contains nothing (NULL).");
continue;
}
if( Superclass::GetMTime() < it->second->GetMTime() )
{
Modified();
break;
}
}
return Superclass::GetMTime();
}
bool mitk::PropertyList::DeleteProperty(const std::string& propertyKey)
{
PropertyMap::iterator it;
it=m_Properties.find( propertyKey );
if(it!=m_Properties.end())
{
it->second=NULL;
m_Properties.erase(it);
Modified();
return true;
}
return false;
}
mitk::PropertyList::Pointer mitk::PropertyList::Clone()
{
mitk::PropertyList::Pointer newPropertyList = PropertyList::New();
// copy the map
newPropertyList->m_Properties = m_Properties;
return newPropertyList.GetPointer();
}
void mitk::PropertyList::Clear()
{
PropertyMap::iterator it = m_Properties.begin(), end = m_Properties.end();
while(it!=end)
{
it->second = NULL;
++it;
}
m_Properties.clear();
}
void mitk::PropertyList::ConcatenatePropertyList(PropertyList *pList, bool replace)
{
if (pList)
{
const PropertyMap* propertyMap = pList->GetMap();
for ( PropertyMap::const_iterator iter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here
iter != propertyMap->end();
++iter )
{
const std::string key = iter->first;
BaseProperty* value = iter->second;
if (replace)
{
ReplaceProperty( key.c_str(), value );
}
else
{
SetProperty( key.c_str(), value );
}
}
}
}
bool mitk::PropertyList::GetBoolProperty(const char* propertyKey, bool& boolValue) const
{
BoolProperty *gp = dynamic_cast<BoolProperty*>( GetProperty(propertyKey) );
if ( gp != NULL )
{
boolValue = gp->GetValue();
return true;
}
return false;
// Templated Method does not work on Macs
//return GetPropertyValue<bool>(propertyKey, boolValue);
}
bool mitk::PropertyList::GetIntProperty(const char* propertyKey, int &intValue) const
{
IntProperty *gp = dynamic_cast<IntProperty*>( GetProperty(propertyKey) );
if ( gp != NULL )
{
intValue = gp->GetValue();
return true;
}
return false;
// Templated Method does not work on Macs
//return GetPropertyValue<int>(propertyKey, intValue);
}
bool mitk::PropertyList::GetFloatProperty(const char* propertyKey, float &floatValue) const
{
FloatProperty *gp = dynamic_cast<FloatProperty*>( GetProperty(propertyKey) );
if ( gp != NULL )
{
floatValue = gp->GetValue();
return true;
}
return false;
// Templated Method does not work on Macs
//return GetPropertyValue<float>(propertyKey, floatValue);
}
bool mitk::PropertyList::GetStringProperty(const char* propertyKey, std::string& stringValue) const
{
StringProperty* sp= dynamic_cast<StringProperty*>(GetProperty(propertyKey));
if ( sp != NULL )
{
stringValue = sp->GetValue();
return true;
}
return false;
}
void mitk::PropertyList::SetIntProperty(const char* propertyKey, int intValue)
{
SetProperty(propertyKey, mitk::IntProperty::New(intValue));
}
void mitk::PropertyList::SetBoolProperty( const char* propertyKey, bool boolValue)
{
SetProperty(propertyKey, mitk::BoolProperty::New(boolValue));
}
void mitk::PropertyList::SetFloatProperty( const char* propertyKey, float floatValue)
{
SetProperty(propertyKey, mitk::FloatProperty::New(floatValue));
}
void mitk::PropertyList::SetStringProperty( const char* propertyKey, const char* stringValue)
{
SetProperty(propertyKey, mitk::StringProperty::New(stringValue));
}
diff --git a/Core/Code/DataManagement/mitkPropertyList.h b/Core/Code/DataManagement/mitkPropertyList.h
index 714907ae8b..4042adf9eb 100644
--- a/Core/Code/DataManagement/mitkPropertyList.h
+++ b/Core/Code/DataManagement/mitkPropertyList.h
@@ -1,208 +1,207 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D
#define PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D
#include <MitkExports.h>
#include "mitkBaseProperty.h"
#include "mitkGenericProperty.h"
#include "mitkUIDGenerator.h"
#include <itkObjectFactory.h>
#include <string>
#include <map>
namespace mitk {
class XMLWriter;
/**
* @brief Key-value list holding instances of BaseProperty
*
* This list is meant to hold an arbitrary list of "properties",
* which should describe the object associated with this list.
*
* Usually you will use PropertyList as part of a DataNode
* object - in this context the properties describe the data object
* held by the DataNode (e.g. whether the object is rendered at
* all, which color is used for rendering, what name should be
* displayed for the object, etc.)
*
* The values in the list are not fixed, you may introduce any kind
* of property that seems useful - all you have to do is inherit
* from BaseProperty.
*
* The list is organized as a key-value pairs, i.e.
*
* \li "name" : pointer to a StringProperty
* \li "visible" : pointer to a BoolProperty
* \li "color" : pointer to a ColorProperty
* \li "volume" : pointer to a FloatProperty
*
* Please see the documentation of SetProperty and ReplaceProperty for two
* quite different semantics. Normally SetProperty is what you want - this
* method will try to change the value of an existing property and will
* not allow you to replace e.g. a ColorProperty with an IntProperty.
*
* @ingroup DataManagement
*/
class MITK_CORE_EXPORT PropertyList : public itk::Object
{
public:
mitkClassMacro(PropertyList, itk::Object);
/**
* Method for creation through the object factory.
*/
itkNewMacro(Self);
/**
* Map structure to hold the properties: the map key is a string,
* the value consists of the actual property object (BaseProperty).
*/
typedef std::map< std::string, BaseProperty::Pointer> PropertyMap;
typedef std::pair< std::string, BaseProperty::Pointer> PropertyMapElementType;
/**
* @brief Get a property by its name.
*/
mitk::BaseProperty* GetProperty(const std::string& propertyKey) const;
/**
* @brief Set a property in the list/map by value.
*
* The actual OBJECT holding the value of the property is not replaced, but its value
* is modified to match that of @a property. To really replace the object holding the
* property - which would make sense if you want to change the type (bool, string) of the property
* - call ReplaceProperty.
*/
void SetProperty(const std::string& propertyKey, BaseProperty* property);
/**
* @brief Set a property object in the list/map by reference.
*
* The actual OBJECT holding the value of the property is replaced by this function.
* This is useful if you want to change the type of the property, like from BoolProperty to StringProperty.
* Another use is to share one and the same property object among several ProperyList/DataNode objects, which
* makes them appear synchronized.
*/
void ReplaceProperty(const std::string& propertyKey, BaseProperty* property);
/**
* @brief Set a property object in the list/map by reference.
*/
void ConcatenatePropertyList(PropertyList *pList, bool replace = false);
//##Documentation
//## @brief Convenience access method for GenericProperty<T> properties
//## (T being the type of the second parameter)
//## @return @a true property was found
template <typename T>
bool GetPropertyValue(const char* propertyKey, T & value) const
{
GenericProperty<T>* gp= dynamic_cast<GenericProperty<T>*>(GetProperty(propertyKey));
if ( gp != NULL )
{
value = gp->GetValue();
return true;
}
return false;
}
/**
* @brief Convenience method to access the value of a BoolProperty
*/
bool GetBoolProperty(const char* propertyKey, bool& boolValue) const;
/**
* @brief Convenience method to set the value of a BoolProperty
*/
void SetBoolProperty( const char* propertyKey, bool boolValue);
/**
* @brief Convenience method to access the value of an IntProperty
*/
bool GetIntProperty(const char* propertyKey, int &intValue) const;
/**
* @brief Convenience method to set the value of an IntProperty
*/
void SetIntProperty(const char* propertyKey, int intValue);
/**
* @brief Convenience method to access the value of a FloatProperty
*/
bool GetFloatProperty(const char* propertyKey, float &floatValue) const;
/**
* @brief Convenience method to set the value of a FloatProperty
*/
void SetFloatProperty( const char* propertyKey, float floatValue);
/**
* @brief Convenience method to access the value of a StringProperty
*/
bool GetStringProperty(const char* propertyKey, std::string& stringValue) const;
/**
* @brief Convenience method to set the value of a StringProperty
*/
void SetStringProperty( const char* propertyKey, const char* stringValue);
/**
* @brief Get the timestamp of the last change of the map or the last change of one of
* the properties store in the list (whichever is later).
*/
virtual unsigned long GetMTime() const;
/**
* @brief Remove a property from the list/map.
*/
bool DeleteProperty(const std::string& propertyKey);
const PropertyMap* GetMap() const { return &m_Properties; }
bool IsEmpty() const { return m_Properties.empty(); }
virtual Pointer Clone();
virtual void Clear();
protected:
PropertyList();
virtual ~PropertyList();
/**
* @brief Map of properties.
*/
PropertyMap m_Properties;
};
} // namespace mitk
#endif /* PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D */
diff --git a/Core/Code/DataManagement/mitkResliceMethodProperty.cpp b/Core/Code/DataManagement/mitkResliceMethodProperty.cpp
index 240697980b..cdb2c52395 100644
--- a/Core/Code/DataManagement/mitkResliceMethodProperty.cpp
+++ b/Core/Code/DataManagement/mitkResliceMethodProperty.cpp
@@ -1,47 +1,46 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $
-Version: $Revision: 13129 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkResliceMethodProperty.h"
mitk::ResliceMethodProperty::ResliceMethodProperty( )
{
AddThickSlicesTypes();
SetValue( (IdType)0 );
}
mitk::ResliceMethodProperty::ResliceMethodProperty( const IdType& value )
{
AddThickSlicesTypes();
if ( IsValidEnumerationValue( value ) )
SetValue( value );
}
mitk::ResliceMethodProperty::ResliceMethodProperty( const std::string& value )
{
AddThickSlicesTypes();
if ( IsValidEnumerationValue( value ) )
SetValue( value );
}
void mitk::ResliceMethodProperty::AddThickSlicesTypes()
{
AddEnum( "disabled", (IdType) 0 );
AddEnum( "mip", (IdType) 1 );
AddEnum( "sum", (IdType) 2 );
AddEnum( "weighted", (IdType) 3 );
}
diff --git a/Core/Code/DataManagement/mitkResliceMethodProperty.h b/Core/Code/DataManagement/mitkResliceMethodProperty.h
index e54428135e..38ae3151b0 100644
--- a/Core/Code/DataManagement/mitkResliceMethodProperty.h
+++ b/Core/Code/DataManagement/mitkResliceMethodProperty.h
@@ -1,68 +1,67 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $
-Version: $Revision: 14081 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 __MITKRESLICEMETHODENUMPROPERTY_H
#define __MITKRESLICEMETHODENUMPROPERTY_H
#include "mitkEnumerationProperty.h"
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* Encapsulates the thick slices method enumeration
*/
class MITK_CORE_EXPORT ResliceMethodProperty : public EnumerationProperty
{
public:
mitkClassMacro( ResliceMethodProperty, EnumerationProperty );
itkNewMacro(ResliceMethodProperty);
mitkNewMacro1Param(ResliceMethodProperty, const IdType&);
mitkNewMacro1Param(ResliceMethodProperty, const std::string&);
using BaseProperty::operator=;
protected:
ResliceMethodProperty( );
ResliceMethodProperty( const IdType& value );
ResliceMethodProperty( const std::string& value );
void AddThickSlicesTypes();
private:
// purposely not implemented
ResliceMethodProperty(const ResliceMethodProperty&);
ResliceMethodProperty& operator=(const ResliceMethodProperty&);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // end of namespace mitk
#endif //_MITK_VTK_SCALARMODE_PROPERTY__H_
diff --git a/Core/Code/DataManagement/mitkRestorePlanePositionOperation.cpp b/Core/Code/DataManagement/mitkRestorePlanePositionOperation.cpp
index b5937b3862..2f56a15f06 100644
--- a/Core/Code/DataManagement/mitkRestorePlanePositionOperation.cpp
+++ b/Core/Code/DataManagement/mitkRestorePlanePositionOperation.cpp
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRestorePlanePositionOperation.h"
namespace mitk
{
RestorePlanePositionOperation
::RestorePlanePositionOperation( OperationType operationType, float width, float height, Vector3D spacing , unsigned int pos, Vector3D direction, AffineTransform3D::Pointer transform/*, PlaneOrientation orientation*/)
: Operation(operationType), m_Spacing( spacing ), m_DirectionVector(direction), m_Width( width ), m_Height( height ), m_Pos(pos), m_Transform(transform)/*, m_Orientation(orientation)*/
{
//MITK_INFO<<"Width: "<<width<<"height: "<<height<<"spacing: "<<spacing<<"direction: "<<direction<<"transform: "<<transform;
}
RestorePlanePositionOperation
::~RestorePlanePositionOperation()
{
}
Vector3D RestorePlanePositionOperation::GetSpacing()
{
return m_Spacing;
}
Vector3D RestorePlanePositionOperation::GetDirectionVector()
{
return m_DirectionVector;
}
float RestorePlanePositionOperation::GetWidth()
{
return m_Width;
}
float RestorePlanePositionOperation::GetHeight()
{
return m_Height;
}
unsigned int RestorePlanePositionOperation::GetPos()
{
return m_Pos;
}
AffineTransform3D::Pointer RestorePlanePositionOperation::GetTransform()
{
return m_Transform;
}
} // namespace mitk
diff --git a/Core/Code/DataManagement/mitkRestorePlanePositionOperation.h b/Core/Code/DataManagement/mitkRestorePlanePositionOperation.h
index 844e713c3d..c2966f74e9 100644
--- a/Core/Code/DataManagement/mitkRestorePlanePositionOperation.h
+++ b/Core/Code/DataManagement/mitkRestorePlanePositionOperation.h
@@ -1,77 +1,76 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 mitkRestorePlanePositionOperation_h_Included
#define mitkRestorePlanePositionOperation_h_Included
#include "mitkCommon.h"
#include "mitkPointOperation.h"
#include "mitkVector.h"
namespace mitk {
//##Documentation
//## TODO
class MITK_CORE_EXPORT RestorePlanePositionOperation : public Operation
{
public:
//##Documentation
//##@brief Operation that handles all actions on one Point.
//##
//## @param operationType is the type of the operation (see mitkOperation.h; e.g. move or add; Information for StateMachine::ExecuteOperation());
//## @param point is the information of the point to add or is the information to change a point into
//## @param index is e.g. the position in a list which describes the element to change
//PointOperation(OperationType operationType, Point3D point, int index = -1, bool selected = true, PointSpecificationType type = PTUNDEFINED);
RestorePlanePositionOperation(OperationType operationType, float width, float height, Vector3D spacing, unsigned int pos, Vector3D direction, AffineTransform3D::Pointer transform);
virtual ~RestorePlanePositionOperation();
Vector3D GetDirectionVector();
float GetWidth();
float GetHeight();
Vector3D GetSpacing();
unsigned int GetPos();
AffineTransform3D::Pointer GetTransform();
private:
Vector3D m_Spacing;
Vector3D m_DirectionVector;
float m_Width;
float m_Height;
unsigned int m_Pos;
AffineTransform3D::Pointer m_Transform;
};
}//namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkRotationOperation.cpp b/Core/Code/DataManagement/mitkRotationOperation.cpp
index 4faa9b8e92..fe057dcf55 100644
--- a/Core/Code/DataManagement/mitkRotationOperation.cpp
+++ b/Core/Code/DataManagement/mitkRotationOperation.cpp
@@ -1,43 +1,42 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRotationOperation.h"
mitk::RotationOperation::RotationOperation(OperationType operationType, Point3D pointOfRotation, Vector3D vectorOfRotation, ScalarType angleOfRotation)
: mitk::Operation(operationType)
, m_AngleOfRotation(angleOfRotation), m_PointOfRotation(pointOfRotation), m_VectorOfRotation(vectorOfRotation)
{
}
mitk::RotationOperation::~RotationOperation(void)
{
}
mitk::ScalarType mitk::RotationOperation::GetAngleOfRotation()
{
return this->m_AngleOfRotation;
}
const mitk::Point3D mitk::RotationOperation::GetCenterOfRotation()
{
return this->m_PointOfRotation;
}
const mitk::Vector3D mitk::RotationOperation::GetVectorOfRotation()
{
return this->m_VectorOfRotation;
}
diff --git a/Core/Code/DataManagement/mitkRotationOperation.h b/Core/Code/DataManagement/mitkRotationOperation.h
index 37b262636d..2db1094b9b 100644
--- a/Core/Code/DataManagement/mitkRotationOperation.h
+++ b/Core/Code/DataManagement/mitkRotationOperation.h
@@ -1,48 +1,47 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKROTATIONOPERATION_H_HEADER_INCLUDED
#define MITKROTATIONOPERATION_H_HEADER_INCLUDED
#include "mitkOperation.h"
#include "mitkVector.h"
namespace mitk {
//##Documentation
//## @brief Operation, that holds everything necessary for an rotation operation
//##
//## @ingroup Undo
class MITK_CORE_EXPORT RotationOperation : public Operation
{
public:
RotationOperation(OperationType operationType, Point3D pointOfRotation, Vector3D vectorOfRotation, ScalarType angleOfRotation);
virtual ~RotationOperation(void);
virtual ScalarType GetAngleOfRotation();
virtual const Point3D GetCenterOfRotation();
virtual const Vector3D GetVectorOfRotation();
protected:
ScalarType m_AngleOfRotation;
Point3D m_PointOfRotation;
Vector3D m_VectorOfRotation;
};
} // namespace mitk
#endif /* MITKROTATIONOPERATION_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkShaderProperty.cpp b/Core/Code/DataManagement/mitkShaderProperty.cpp
index 45585c30af..19b62813bc 100644
--- a/Core/Code/DataManagement/mitkShaderProperty.cpp
+++ b/Core/Code/DataManagement/mitkShaderProperty.cpp
@@ -1,107 +1,106 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $
-Version: $Revision: 13129 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <vtkAbstractMapper.h>
#include "mitkShaderProperty.h"
#include "mitkShaderRepository.h"
#include <itkDirectory.h>
#include <itksys/SystemTools.hxx>
mitk::ShaderProperty::ShaderProperty( )
{
AddShaderTypes();
SetShader( (IdType)0 );
}
mitk::ShaderProperty::ShaderProperty( const IdType& value )
{
AddShaderTypes();
SetShader(value);
}
mitk::ShaderProperty::ShaderProperty( const std::string& value )
{
AddShaderTypes();
SetShader(value);
}
void mitk::ShaderProperty::SetShader( const IdType& value )
{
if ( IsValidEnumerationValue( value ) )
SetValue( value );
else
SetValue( (IdType)0 );
}
void mitk::ShaderProperty::SetShader( const std::string& value )
{
if ( IsValidEnumerationValue( value ) )
SetValue( value );
else
SetValue( (IdType)0 );
}
mitk::EnumerationProperty::IdType mitk::ShaderProperty::GetShaderId()
{
return GetValueAsId();
}
std::string mitk::ShaderProperty::GetShaderName()
{
return GetValueAsString();
}
void mitk::ShaderProperty::AddShaderTypes()
{
AddEnum( "fixed" );
std::list<mitk::ShaderRepository::Shader::Pointer> *l
= mitk::ShaderRepository::GetGlobalShaderRepository()->GetShaders();
std::list<mitk::ShaderRepository::Shader::Pointer>::const_iterator i = l->begin();
while( i != l->end() )
{
AddEnum( (*i)->name );
i++;
}
}
bool mitk::ShaderProperty::AddEnum( const std::string& name ,const IdType& /*id*/)
{
Element e;
e.name=name;
bool success=Superclass::AddEnum( e.name, (IdType)shaderList.size() );
shaderList.push_back(e);
return success;
}
bool mitk::ShaderProperty::Assign(const BaseProperty &property)
{
Superclass::Assign(property);
this->shaderList = static_cast<const Self&>(property).shaderList;
return true;
}
diff --git a/Core/Code/DataManagement/mitkShaderProperty.h b/Core/Code/DataManagement/mitkShaderProperty.h
index 72f456c0a0..e8618c6ab9 100644
--- a/Core/Code/DataManagement/mitkShaderProperty.h
+++ b/Core/Code/DataManagement/mitkShaderProperty.h
@@ -1,116 +1,115 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $
-Version: $Revision: 14081 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 __MITKSHADERENUMPROPERTY_H
#define __MITKSHADERENUMPROPERTY_H
#include "mitkEnumerationProperty.h"
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* Encapsulates the shader enumeration
*/
class MITK_CORE_EXPORT ShaderProperty : public EnumerationProperty
{
public:
class Element {
public:
std::string name;
};
mitkClassMacro( ShaderProperty, EnumerationProperty );
itkNewMacro(ShaderProperty);
mitkNewMacro1Param(ShaderProperty, const IdType&);
mitkNewMacro1Param(ShaderProperty, const std::string&);
/**
* Returns the current scalar mode value as defined by VTK constants.
* @returns the current scalar mode as VTK constant.
*/
IdType GetShaderId();
std::string GetShaderName();
void SetShader(const IdType& i);
void SetShader(const std::string& i);
using BaseProperty::operator=;
protected:
std::list<Element> shaderList;
/**
* Constructor. Sets the representation to a default value of surface(2)
*/
ShaderProperty( );
/**
* \brief Sets the scalar mode to the given value. If it is not
* valid, the scalar mode is set to default (0).
* @param value the integer representation of the scalar mode
*/
ShaderProperty( const IdType& value );
/**
* \brief Sets the scalar mode to the given value. If it is not
* valid, the representation is set to default (0).
* @param value the string representation of the scalar mode
*/
ShaderProperty( const std::string& value );
/**
* this function is overridden as protected, so that the user may not add
* additional invalid scalar mode types.
*/
bool AddEnum( const std::string& name, const IdType& id = 0);
/**
* Adds the enumeration types as defined by vtk to the list of known
* enumeration values.
*/
void AddShaderTypes();
private:
// purposely not implemented
ShaderProperty(const ShaderProperty&);
ShaderProperty& operator=(const ShaderProperty&);
virtual bool Assign(const BaseProperty &property);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // end of namespace mitk
#endif //_MITK_VTK_SCALARMODE_PROPERTY__H_
diff --git a/Core/Code/DataManagement/mitkSlicedData.cpp b/Core/Code/DataManagement/mitkSlicedData.cpp
index ff65f22f15..d51e3f0dfe 100644
--- a/Core/Code/DataManagement/mitkSlicedData.cpp
+++ b/Core/Code/DataManagement/mitkSlicedData.cpp
@@ -1,353 +1,352 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSlicedData.h"
#include "mitkBaseProcess.h"
mitk::SlicedData::SlicedData() : m_UseLargestPossibleRegion(false)
{
unsigned int i;
for(i=0;i<4;++i)
{
m_LargestPossibleRegion.SetIndex(i, 0);
m_LargestPossibleRegion.SetSize (i, 1);
}
}
mitk::SlicedData::SlicedData( const SlicedData &other ): BaseData(other),
m_LargestPossibleRegion(other.m_LargestPossibleRegion),
m_RequestedRegion(other.m_RequestedRegion),
m_BufferedRegion(other.m_BufferedRegion),
m_UseLargestPossibleRegion(other.m_UseLargestPossibleRegion)
{
}
mitk::SlicedData::~SlicedData()
{
}
void mitk::SlicedData::UpdateOutputInformation()
{
Superclass::UpdateOutputInformation();
if (this->GetSource().IsNull())
// If we don't have a source, then let's make our Image
// span our buffer
{
m_UseLargestPossibleRegion = true;
}
// Now we should know what our largest possible region is. If our
// requested region was not set yet, (or has been set to something
// invalid - with no data in it ) then set it to the largest possible
// region.
if ( ! m_RequestedRegionInitialized)
{
this->SetRequestedRegionToLargestPossibleRegion();
m_RequestedRegionInitialized = true;
}
m_LastRequestedRegionWasOutsideOfTheBufferedRegion = 0;
}
void mitk::SlicedData::PrepareForNewData()
{
if ( GetUpdateMTime() < GetPipelineMTime() || GetDataReleased() )
{
ReleaseData();
}
}
void mitk::SlicedData::SetRequestedRegionToLargestPossibleRegion()
{
m_UseLargestPossibleRegion = true;
if(GetGeometry()==NULL)
return;
unsigned int i;
const RegionType::IndexType & index = GetLargestPossibleRegion().GetIndex();
const RegionType::SizeType & size = GetLargestPossibleRegion().GetSize();
for(i=0;i<RegionDimension;++i)
{
m_RequestedRegion.SetIndex(i, index[i]);
m_RequestedRegion.SetSize(i, size[i]);
}
}
bool mitk::SlicedData::RequestedRegionIsOutsideOfTheBufferedRegion()
{
// Is the requested region within the currently buffered data?
// SlicedData and subclasses store entire volumes or slices. The
// methods IsVolumeSet() and IsSliceSet are provided to check,
// a volume or slice, respectively, is available. Thus, these
// methods used here.
const IndexType &requestedRegionIndex = m_RequestedRegion.GetIndex();
const SizeType& requestedRegionSize = m_RequestedRegion.GetSize();
const SizeType& largestPossibleRegionSize
= GetLargestPossibleRegion().GetSize();
// are whole channels requested?
int c, cEnd;
c=requestedRegionIndex[4];
cEnd=c+static_cast<long>(requestedRegionSize[4]);
if(requestedRegionSize[3] == largestPossibleRegionSize[3])
{
for (; c< cEnd; ++c)
if(IsChannelSet(c)==false) return true;
return false;
}
// are whole volumes requested?
int t, tEnd;
t=requestedRegionIndex[3];
tEnd=t+static_cast<long>(requestedRegionSize[3]);
if(requestedRegionSize[2] == largestPossibleRegionSize[2])
{
for (; c< cEnd; ++c)
for (; t< tEnd; ++t)
if(IsVolumeSet(t, c)==false) return true;
return false;
}
// ok, only slices are requested. Check if they are available.
int s, sEnd;
s=requestedRegionIndex[2];
sEnd=s+static_cast<long>(requestedRegionSize[2]);
for (; c< cEnd; ++c)
for (; t< tEnd; ++t)
for (; s< sEnd; ++s)
if(IsSliceSet(s, t, c)==false) return true;
return false;
}
bool mitk::SlicedData::VerifyRequestedRegion()
{
if(GetTimeSlicedGeometry() == NULL) return false;
unsigned int i;
// Is the requested region within the LargestPossibleRegion?
// Note that the test is indeed against the largest possible region
// rather than the buffered region; see DataObject::VerifyRequestedRegion.
const IndexType &requestedRegionIndex = m_RequestedRegion.GetIndex();
const IndexType &largestPossibleRegionIndex
= GetLargestPossibleRegion().GetIndex();
const SizeType& requestedRegionSize = m_RequestedRegion.GetSize();
const SizeType& largestPossibleRegionSize
= GetLargestPossibleRegion().GetSize();
for (i=0; i< RegionDimension; ++i)
{
if ( (requestedRegionIndex[i] < largestPossibleRegionIndex[i]) ||
((requestedRegionIndex[i] + static_cast<long>(requestedRegionSize[i]))
> (largestPossibleRegionIndex[i]+static_cast<long>(largestPossibleRegionSize[i]))))
{
return false;
}
}
return true;
}
void mitk::SlicedData::SetRequestedRegion(itk::DataObject *data)
{
m_UseLargestPossibleRegion=false;
mitk::SlicedData *slicedData;
slicedData = dynamic_cast<mitk::SlicedData*>(data);
if (slicedData)
{
m_RequestedRegion = slicedData->GetRequestedRegion();
m_RequestedRegionInitialized = true;
}
else
{
// pointer could not be cast back down
itkExceptionMacro( << "mitk::SlicedData::SetRequestedRegion(DataObject*) cannot cast " << typeid(data).name() << " to " << typeid(SlicedData*).name() );
}
}
void mitk::SlicedData::SetRequestedRegion(SlicedData::RegionType *region)
{
m_UseLargestPossibleRegion=false;
if(region!=NULL)
{
m_RequestedRegion = *region;
m_RequestedRegionInitialized = true;
}
else
{
// pointer could not be cast back down
itkExceptionMacro( << "mitk::SlicedData::SetRequestedRegion(SlicedData::RegionType*) cannot cast " << typeid(region).name() << " to " << typeid(SlicedData*).name() );
}
}
void mitk::SlicedData::CopyInformation(const itk::DataObject *data)
{
// Standard call to the superclass' method
Superclass::CopyInformation(data);
const mitk::SlicedData *slicedData;
slicedData = dynamic_cast<const mitk::SlicedData*>(data);
if (slicedData)
{
m_LargestPossibleRegion = slicedData->GetLargestPossibleRegion();
}
else
{
// pointer could not be cast back down
itkExceptionMacro( << "mitk::SlicedData::CopyInformation(const DataObject *data) cannot cast " << typeid(data).name() << " to " << typeid(SlicedData*).name() );
}
}
//const mitk::Geometry2D* mitk::SlicedData::GetGeometry2D(int s, int t) const
//{
// const_cast<SlicedData*>(this)->SetRequestedRegionToLargestPossibleRegion();
//
// const_cast<SlicedData*>(this)->UpdateOutputInformation();
//
// return GetSlicedGeometry(t)->GetGeometry2D(s);
//}
//
mitk::SlicedGeometry3D* mitk::SlicedData::GetSlicedGeometry(unsigned int t) const
{
if(GetTimeSlicedGeometry() == NULL)
return NULL;
return dynamic_cast<SlicedGeometry3D*>(GetTimeSlicedGeometry()->GetGeometry3D(t));
}
const mitk::SlicedGeometry3D* mitk::SlicedData::GetUpdatedSlicedGeometry(unsigned int t)
{
SetRequestedRegionToLargestPossibleRegion();
UpdateOutputInformation();
return GetSlicedGeometry(t);
}
void mitk::SlicedData::SetGeometry(Geometry3D* aGeometry3D)
{
if(aGeometry3D!=NULL)
{
TimeSlicedGeometry::Pointer timeSlicedGeometry = dynamic_cast<TimeSlicedGeometry*>(aGeometry3D);
if(timeSlicedGeometry.IsNull())
{
SlicedGeometry3D::Pointer slicedGeometry = dynamic_cast<SlicedGeometry3D*>(aGeometry3D);
if(slicedGeometry.IsNull())
{
Geometry2D* geometry2d = dynamic_cast<Geometry2D*>(aGeometry3D);
if(geometry2d!=NULL)
{
if((GetSlicedGeometry()->GetGeometry2D(0)==geometry2d) && (GetSlicedGeometry()->GetSlices()==1))
return;
slicedGeometry = SlicedGeometry3D::New();
slicedGeometry->InitializeEvenlySpaced(geometry2d, 1);
}
else
{
slicedGeometry = SlicedGeometry3D::New();
PlaneGeometry::Pointer planeGeometry = PlaneGeometry::New();
planeGeometry->InitializeStandardPlane(aGeometry3D);
slicedGeometry->InitializeEvenlySpaced(planeGeometry, (unsigned int)(aGeometry3D->GetExtent(2)));
}
}
assert(slicedGeometry.IsNotNull());
timeSlicedGeometry = TimeSlicedGeometry::New();
timeSlicedGeometry->InitializeEvenlyTimed(slicedGeometry, 1);
}
Superclass::SetGeometry(timeSlicedGeometry);
}
else
{
if(GetGeometry()==NULL)
return;
Superclass::SetGeometry(NULL);
}
}
void mitk::SlicedData::SetSpacing(const float aSpacing[3])
{
this->SetSpacing((mitk::Vector3D)aSpacing);
}
void mitk::SlicedData::SetOrigin(const mitk::Point3D& origin)
{
mitk::TimeSlicedGeometry* timeSlicedGeometry = GetTimeSlicedGeometry();
assert(timeSlicedGeometry!=NULL);
mitk::SlicedGeometry3D* slicedGeometry;
unsigned int steps = timeSlicedGeometry->GetTimeSteps();
for(unsigned int timestep = 0; timestep < steps; ++timestep)
{
slicedGeometry = GetSlicedGeometry(timestep);
if(slicedGeometry != NULL)
{
slicedGeometry->SetOrigin(origin);
if(slicedGeometry->GetEvenlySpaced())
{
mitk::Geometry2D* geometry2D = slicedGeometry->GetGeometry2D(0);
geometry2D->SetOrigin(origin);
slicedGeometry->InitializeEvenlySpaced(geometry2D, slicedGeometry->GetSlices());
}
}
if(GetTimeSlicedGeometry()->GetEvenlyTimed())
{
GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, steps);
break;
}
}
}
void mitk::SlicedData::SetSpacing(mitk::Vector3D aSpacing)
{
mitk::TimeSlicedGeometry* timeSlicedGeometry = GetTimeSlicedGeometry();
assert(timeSlicedGeometry!=NULL);
mitk::SlicedGeometry3D* slicedGeometry;
unsigned int steps = timeSlicedGeometry->GetTimeSteps();
for(unsigned int timestep = 0; timestep < steps; ++timestep)
{
slicedGeometry = GetSlicedGeometry(timestep);
if(slicedGeometry != NULL)
{
slicedGeometry->SetSpacing(aSpacing);
}
if(GetTimeSlicedGeometry()->GetEvenlyTimed())
{
GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, steps);
break;
}
}
}
diff --git a/Core/Code/DataManagement/mitkSlicedData.h b/Core/Code/DataManagement/mitkSlicedData.h
index b237897c71..1ee731174c 100644
--- a/Core/Code/DataManagement/mitkSlicedData.h
+++ b/Core/Code/DataManagement/mitkSlicedData.h
@@ -1,223 +1,222 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 SLICEDDATA_H_HEADER_INCLUDED
#define SLICEDDATA_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkBaseData.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include "itkIndex.h"
#include "itkOffset.h"
#include "itkSize.h"
#include "itkImageRegion.h"
namespace mitk {
class SlicedGeometry3D;
//##Documentation
//## @brief Super class of data objects consisting of slices
//##
//## Super class of data objects consisting of slices, e.g., images or a stack
//## of contours. (GetGeometry will return a Geometry3D containing Geometry2D
//## objects).
//##
//## SlicedData-objects have geometries of type SlicedGeometry3D or sub-classes.
//## @ingroup Data
class MITK_CORE_EXPORT SlicedData : public BaseData
{
public:
mitkClassMacro(SlicedData, BaseData);
itkStaticConstMacro(RegionDimension, unsigned int, 5);
/** Region typedef support. A region is used to specify a subset of a @a SlicedData. */
typedef itk::ImageRegion<RegionDimension> RegionType;
/** Index typedef support. An index is used to access pixel values. */
typedef itk::Index<RegionDimension> IndexType;
typedef IndexType::IndexValueType IndexValueType;
/** Offset typedef support. An offset represent relative position
* between indices. */
typedef itk::Offset<RegionDimension> OffsetType;
typedef OffsetType::OffsetValueType OffsetValueType;
/** Size typedef support. A size is used to define region bounds. */
typedef itk::Size<RegionDimension> SizeType;
typedef SizeType::SizeValueType SizeValueType;
//##Documentation
//## Update the information for this DataObject so that it can be used as
//## an output of a ProcessObject. This method is used in the pipeline
//## mechanism to propagate information and initialize the meta data
//## associated with a itk::DataObject. Any implementation of this method
//## in a derived class of itk::DataObject is assumed to call its source's
//## ProcessObject::UpdateOutputInformation() which determines modified
//## times, LargestPossibleRegions, and any extra meta data like spacing,
//## origin, etc.
virtual void UpdateOutputInformation();
virtual void PrepareForNewData();
//##Documentation
//## Set the RequestedRegion to the LargestPossibleRegion. This forces a
//## filter to produce all of the output in one execution (i.e. not
//## streaming) on the next call to Update().
virtual void SetRequestedRegionToLargestPossibleRegion();
//##Documentation
//## Determine whether the RequestedRegion is outside of the
//## BufferedRegion. This method returns true if the RequestedRegion is
//## outside the BufferedRegion (true if at least one pixel is outside).
//## This is used by the pipeline mechanism to determine whether a filter
//## needs to re-execute in order to satisfy the current request. If the
//## current RequestedRegion is already inside the BufferedRegion from the
//## previous execution (and the current filter is up to date), then a
//## given filter does not need to re-execute
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
//##Documentation
//## @brief Verify that the RequestedRegion is within the
//## LargestPossibleRegion.
//##
//## Verify that the RequestedRegion is within the LargestPossibleRegion.
//## If the RequestedRegion is not within the LargestPossibleRegion,
//## then the filter cannot possibly satisfy the request. This method
//## returns true if the request can be satisfied (even if it will be
//## necessary to process the entire LargestPossibleRegion) and
//## returns false otherwise. This method is used by
//## PropagateRequestedRegion(). PropagateRequestedRegion() throws a
//## InvalidRequestedRegionError exception if the requested region is
//## not within the LargestPossibleRegion.
virtual bool VerifyRequestedRegion();
//##Documentation
//## Set the requested region from this data object to match the requested
//## region of the data object passed in as a parameter. This method is
//## implemented in the concrete subclasses of DataObject.
virtual void SetRequestedRegion(itk::DataObject *data);
//##Documentation
//## Set the requested region from this data object to match the requested
//## region of the data object passed in as a parameter. This method is
//## implemented in the concrete subclasses of DataObject.
virtual void SetRequestedRegion(SlicedData::RegionType *region);
const RegionType& GetLargestPossibleRegion() const
{
return m_LargestPossibleRegion;
}
//##Documentation
//## Get the region object that defines the size and starting index
//## for the region of the image requested (i.e., the region of the
//## image to be operated on by a filter).
virtual const RegionType& GetRequestedRegion() const
{
return m_RequestedRegion;
}
virtual bool IsSliceSet(int s = 0, int t = 0, int n = 0) const = 0;
virtual bool IsVolumeSet(int t = 0, int n = 0) const = 0;
virtual bool IsChannelSet(int n = 0) const = 0;
virtual void CopyInformation(const itk::DataObject *data);
//##Documentation
//## @brief Get the number of channels
unsigned int GetNumberOfChannels() const
{
return m_LargestPossibleRegion.GetSize(4);
}
////##Documentation
////## @brief Return the Geometry2D of the slice (@a s, @a t).
////##
////## The method does not simply call GetGeometry()->GetGeometry2D(). Before doing this, it
////## makes sure that the Geometry2D is up-to-date before returning it (by
////## setting the update extent appropriately and calling
////## UpdateOutputInformation).
////##
////## @warning GetGeometry2D not yet completely implemented.
////## @todo Appropriate setting of the update extent is missing.
//virtual const mitk::Geometry2D* GetGeometry2D(int s, int t=0) const;
//##Documentation
//## @brief Convenience access method for the geometry, which is of type SlicedGeometry3D (or a sub-class of it).
//##
//## @em No update will be called. Normally used in GenerateOutputInformation of
//## subclasses of BaseProcess.
SlicedGeometry3D* GetSlicedGeometry(unsigned int t=0) const;
//##Documentation
//## @brief Convenience access method for the geometry, which is of type SlicedGeometry3D (or a sub-class of it).
//##
//## The method does not simply return the value of the m_Geometry3D member.
//## Before doing this, it makes sure that the Geometry3D is up-to-date before
//## returning it (by setting the update extent appropriately and calling
//## UpdateOutputInformation).
//##
//## @warning GetGeometry not yet completely implemented.
//## @todo Appropriate setting of the update extent is missing.
const SlicedGeometry3D* GetUpdatedSlicedGeometry(unsigned int t=0);
//##Documentation
//## @brief Set the Geometry3D of the data, which will be referenced (not copied!). It
//## has to be a sub-class of SlicedGeometry3D.
//##
//## @warning This method will normally be called internally by the sub-class of SlicedData
//## during initialization.
virtual void SetGeometry(Geometry3D* aGeometry3D);
//##Documentation
//## @brief Convenience method for setting the origin of
//## the SlicedGeometry3D instances of all time steps
//##
//## In case the SlicedGeometry3D is evenly spaced,
//## the origin of the first slice is set to \a origin.
//## \sa mitk::BaseData::SetOrigin
virtual void SetOrigin(const Point3D& origin);
//##Documentation
//## @brief Convenience method for setting the spacing of
//## the SlicedGeometry3D instances of all time steps
virtual void SetSpacing(const float aSpacing[3]);
//##Documentation
//## @brief Convenience method for setting the spacing of
//## the SlicedGeometry3D instances of all time steps
virtual void SetSpacing(mitk::Vector3D aSpacing);
protected:
SlicedData();
SlicedData(const SlicedData &other);
virtual ~SlicedData();
RegionType m_LargestPossibleRegion;
RegionType m_RequestedRegion;
RegionType m_BufferedRegion;
bool m_UseLargestPossibleRegion;
};
} // namespace mitk
#endif /* SLICEDDATA_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkSlicedGeometry3D.cpp b/Core/Code/DataManagement/mitkSlicedGeometry3D.cpp
index cfa611d015..46691e0fcf 100644
--- a/Core/Code/DataManagement/mitkSlicedGeometry3D.cpp
+++ b/Core/Code/DataManagement/mitkSlicedGeometry3D.cpp
@@ -1,934 +1,933 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSlicedGeometry3D.h"
#include "mitkPlaneGeometry.h"
#include "mitkRotationOperation.h"
#include "mitkPlaneOperation.h"
#include "mitkRestorePlanePositionOperation.h"
#include "mitkInteractionConst.h"
#include "mitkSliceNavigationController.h"
mitk::SlicedGeometry3D::SlicedGeometry3D()
: m_EvenlySpaced( true ),
m_Slices( 0 ),
m_ReferenceGeometry( NULL ),
m_SliceNavigationController( NULL )
{
m_DirectionVector.Fill(0);
this->InitializeSlicedGeometry( m_Slices );
}
mitk::SlicedGeometry3D::SlicedGeometry3D(const SlicedGeometry3D& other)
: Superclass(other),
m_EvenlySpaced( other.m_EvenlySpaced ),
m_Slices( other.m_Slices ),
m_ReferenceGeometry( other.m_ReferenceGeometry ),
m_SliceNavigationController( other.m_SliceNavigationController )
{
m_DirectionVector.Fill(0);
SetSpacing( other.GetSpacing() );
SetDirectionVector( other.GetDirectionVector() );
if ( m_EvenlySpaced )
{
AffineGeometryFrame3D::Pointer geometry = other.m_Geometry2Ds[0]->Clone();
Geometry2D* geometry2D = dynamic_cast<Geometry2D*>(geometry.GetPointer());
assert(geometry2D!=NULL);
SetGeometry2D(geometry2D, 0);
}
else
{
unsigned int s;
for ( s = 0; s < other.m_Slices; ++s )
{
if ( other.m_Geometry2Ds[s].IsNull() )
{
assert(other.m_EvenlySpaced);
m_Geometry2Ds[s] = NULL;
}
else
{
AffineGeometryFrame3D::Pointer geometry = other.m_Geometry2Ds[s]->Clone();
Geometry2D* geometry2D = dynamic_cast<Geometry2D*>(geometry.GetPointer());
assert(geometry2D!=NULL);
SetGeometry2D(geometry2D, s);
}
}
}
}
mitk::SlicedGeometry3D::~SlicedGeometry3D()
{
}
mitk::Geometry2D *
mitk::SlicedGeometry3D::GetGeometry2D( int s ) const
{
mitk::Geometry2D::Pointer geometry2D = NULL;
if ( this->IsValidSlice(s) )
{
geometry2D = m_Geometry2Ds[s];
// If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored
// for the requested slice, and (c) the first slice (s=0)
// is a PlaneGeometry instance, then we calculate the geometry of the
// requested as the plane of the first slice shifted by m_Spacing[2]*s
// in the direction of m_DirectionVector.
if ( (m_EvenlySpaced) && (geometry2D.IsNull()) )
{
PlaneGeometry *firstSlice = dynamic_cast< PlaneGeometry * > (
m_Geometry2Ds[0].GetPointer() );
if ( firstSlice != NULL )
{
if ( (m_DirectionVector[0] == 0.0)
&& (m_DirectionVector[1] == 0.0)
&& (m_DirectionVector[2] == 0.0) )
{
m_DirectionVector = firstSlice->GetNormal();
m_DirectionVector.Normalize();
}
Vector3D direction;
direction = m_DirectionVector * m_Spacing[2];
mitk::PlaneGeometry::Pointer requestedslice;
requestedslice = static_cast< mitk::PlaneGeometry * >(
firstSlice->Clone().GetPointer() );
requestedslice->SetOrigin(
requestedslice->GetOrigin() + direction * s );
geometry2D = requestedslice;
m_Geometry2Ds[s] = geometry2D;
}
}
return geometry2D;
}
else
{
return NULL;
}
}
const mitk::BoundingBox *
mitk::SlicedGeometry3D::GetBoundingBox() const
{
assert(m_BoundingBox.IsNotNull());
return m_BoundingBox.GetPointer();
}
bool
mitk::SlicedGeometry3D::SetGeometry2D( mitk::Geometry2D *geometry2D, int s )
{
if ( this->IsValidSlice(s) )
{
m_Geometry2Ds[s] = geometry2D;
m_Geometry2Ds[s]->SetReferenceGeometry( m_ReferenceGeometry );
return true;
}
return false;
}
void
mitk::SlicedGeometry3D::InitializeSlicedGeometry( unsigned int slices )
{
Superclass::Initialize();
m_Slices = slices;
Geometry2D::Pointer gnull = NULL;
m_Geometry2Ds.assign( m_Slices, gnull );
Vector3D spacing;
spacing.Fill( 1.0 );
this->SetSpacing( spacing );
m_DirectionVector.Fill( 0 );
}
void
mitk::SlicedGeometry3D::InitializeEvenlySpaced(
mitk::Geometry2D* geometry2D, unsigned int slices, bool flipped )
{
assert( geometry2D != NULL );
this->InitializeEvenlySpaced(
geometry2D, geometry2D->GetExtentInMM(2)/geometry2D->GetExtent(2),
slices, flipped );
}
void
mitk::SlicedGeometry3D::InitializeEvenlySpaced(
mitk::Geometry2D* geometry2D, mitk::ScalarType zSpacing,
unsigned int slices, bool flipped )
{
assert( geometry2D != NULL );
assert( geometry2D->GetExtent(0) > 0 );
assert( geometry2D->GetExtent(1) > 0 );
geometry2D->Register();
Superclass::Initialize();
m_Slices = slices;
BoundingBox::BoundsArrayType bounds = geometry2D->GetBounds();
bounds[4] = 0;
bounds[5] = slices;
// clear and reserve
Geometry2D::Pointer gnull = NULL;
m_Geometry2Ds.assign( m_Slices, gnull );
Vector3D directionVector = geometry2D->GetAxisVector(2);
directionVector.Normalize();
directionVector *= zSpacing;
if ( flipped == false )
{
// Normally we should use the following four lines to create a copy of
// the transform contrained in geometry2D, because it may not be changed
// by us. But we know that SetSpacing creates a new transform without
// changing the old (coming from geometry2D), so we can use the fifth
// line instead. We check this at (**).
//
// AffineTransform3D::Pointer transform = AffineTransform3D::New();
// transform->SetMatrix(geometry2D->GetIndexToWorldTransform()->GetMatrix());
// transform->SetOffset(geometry2D->GetIndexToWorldTransform()->GetOffset());
// SetIndexToWorldTransform(transform);
m_IndexToWorldTransform = const_cast< AffineTransform3D * >(
geometry2D->GetIndexToWorldTransform() );
}
else
{
directionVector *= -1.0;
m_IndexToWorldTransform = AffineTransform3D::New();
m_IndexToWorldTransform->SetMatrix(
geometry2D->GetIndexToWorldTransform()->GetMatrix() );
AffineTransform3D::OutputVectorType scaleVector;
FillVector3D(scaleVector, 1.0, 1.0, -1.0);
m_IndexToWorldTransform->Scale(scaleVector, true);
m_IndexToWorldTransform->SetOffset(
geometry2D->GetIndexToWorldTransform()->GetOffset() );
}
mitk::Vector3D spacing;
FillVector3D( spacing,
geometry2D->GetExtentInMM(0) / bounds[1],
geometry2D->GetExtentInMM(1) / bounds[3],
zSpacing );
// Ensure that spacing differs from m_Spacing to make SetSpacing change the
// matrix.
m_Spacing[2] = zSpacing - 1;
this->SetDirectionVector( directionVector );
this->SetBounds( bounds );
this->SetGeometry2D( geometry2D, 0 );
this->SetSpacing( spacing );
this->SetEvenlySpaced();
this->SetTimeBounds( geometry2D->GetTimeBounds() );
assert(m_IndexToWorldTransform.GetPointer()
!= geometry2D->GetIndexToWorldTransform()); // (**) see above.
this->SetFrameOfReferenceID( geometry2D->GetFrameOfReferenceID() );
this->SetImageGeometry( geometry2D->GetImageGeometry() );
geometry2D->UnRegister();
}
void
mitk::SlicedGeometry3D::InitializePlanes(
const mitk::Geometry3D *geometry3D,
mitk::PlaneGeometry::PlaneOrientation planeorientation,
bool top, bool frontside, bool rotated )
{
m_ReferenceGeometry = const_cast< Geometry3D * >( geometry3D );
PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
planeGeometry->InitializeStandardPlane(
geometry3D, top, planeorientation, frontside, rotated );
ScalarType viewSpacing = 1;
unsigned int slices = 1;
switch ( planeorientation )
{
case PlaneGeometry::Transversal:
viewSpacing = geometry3D->GetSpacing()[2];
slices = (unsigned int) geometry3D->GetExtent( 2 );
break;
case PlaneGeometry::Frontal:
viewSpacing = geometry3D->GetSpacing()[1];
slices = (unsigned int) geometry3D->GetExtent( 1 );
break;
case PlaneGeometry::Sagittal:
viewSpacing = geometry3D->GetSpacing()[0];
slices = (unsigned int) geometry3D->GetExtent( 0 );
break;
default:
itkExceptionMacro("unknown PlaneOrientation");
}
mitk::Vector3D normal = this->AdjustNormal( planeGeometry->GetNormal() );
ScalarType directedExtent =
fabs( m_ReferenceGeometry->GetExtentInMM( 0 ) * normal[0] )
+ fabs( m_ReferenceGeometry->GetExtentInMM( 1 ) * normal[1] )
+ fabs( m_ReferenceGeometry->GetExtentInMM( 2 ) * normal[2] );
if ( directedExtent >= viewSpacing )
{
slices = static_cast< int >(directedExtent / viewSpacing + 0.5);
}
else
{
slices = 1;
}
bool flipped = (top == false);
if ( frontside == false )
{
flipped = !flipped;
}
if ( planeorientation == PlaneGeometry::Frontal )
{
flipped = !flipped;
}
this->InitializeEvenlySpaced( planeGeometry, viewSpacing, slices, flipped );
}
void
mitk::SlicedGeometry3D
::ReinitializePlanes( const Point3D &center, const Point3D &referencePoint )
{
// Need a reference frame to align the rotated planes
if ( !m_ReferenceGeometry )
{
return;
}
// Get first plane of plane stack
PlaneGeometry *firstPlane =
dynamic_cast< PlaneGeometry * >( m_Geometry2Ds[0].GetPointer() );
// If plane stack is empty, exit
if ( firstPlane == NULL )
{
return;
}
// Calculate the "directed" spacing when taking the plane (defined by its axes
// vectors and normal) as the reference coordinate frame.
//
// This is done by calculating the radius of the ellipsoid defined by the
// original volume spacing axes, in the direction of the respective axis of the
// reference frame.
mitk::Vector3D axis0 = firstPlane->GetAxisVector(0);
mitk::Vector3D axis1 = firstPlane->GetAxisVector(1);
mitk::Vector3D normal = firstPlane->GetNormal();
normal.Normalize();
Vector3D spacing;
spacing[0] = this->CalculateSpacing( axis0 );
spacing[1] = this->CalculateSpacing( axis1 );
spacing[2] = this->CalculateSpacing( normal );
Superclass::SetSpacing( spacing );
// Now we need to calculate the number of slices in the plane's normal
// direction, so that the entire volume is covered. This is done by first
// calculating the dot product between the volume diagonal (the maximum
// distance inside the volume) and the normal, and dividing this value by
// the directed spacing calculated above.
ScalarType directedExtent =
fabs( m_ReferenceGeometry->GetExtentInMM( 0 ) * normal[0] )
+ fabs( m_ReferenceGeometry->GetExtentInMM( 1 ) * normal[1] )
+ fabs( m_ReferenceGeometry->GetExtentInMM( 2 ) * normal[2] );
if ( directedExtent >= spacing[2] )
{
m_Slices = static_cast< unsigned int >(directedExtent / spacing[2] + 0.5);
}
else
{
m_Slices = 1;
}
// The origin of our "first plane" needs to be adapted to this new extent.
// To achieve this, we first calculate the current distance to the volume's
// center, and then shift the origin in the direction of the normal by the
// difference between this distance and half of the new extent.
double centerOfRotationDistance =
firstPlane->SignedDistanceFromPlane( center );
if ( centerOfRotationDistance > 0 )
{
firstPlane->SetOrigin( firstPlane->GetOrigin()
+ normal * (centerOfRotationDistance - directedExtent / 2.0)
);
m_DirectionVector = normal;
}
else
{
firstPlane->SetOrigin( firstPlane->GetOrigin()
+ normal * (directedExtent / 2.0 + centerOfRotationDistance)
);
m_DirectionVector = -normal;
}
// Now we adjust this distance according with respect to the given reference
// point: we need to make sure that the point is touched by one slice of the
// new slice stack.
double referencePointDistance =
firstPlane->SignedDistanceFromPlane( referencePoint );
int referencePointSlice = static_cast< int >(
referencePointDistance / spacing[2]);
double alignmentValue =
referencePointDistance / spacing[2] - referencePointSlice;
firstPlane->SetOrigin(
firstPlane->GetOrigin() + normal * alignmentValue * spacing[2] );
// Finally, we can clear the previous geometry stack and initialize it with
// our re-initialized "first plane".
m_Geometry2Ds.assign( m_Slices, Geometry2D::Pointer( NULL ) );
if ( m_Slices > 0 )
{
m_Geometry2Ds[0] = firstPlane;
}
// Reinitialize SNC with new number of slices
m_SliceNavigationController->GetSlice()->SetSteps( m_Slices );
this->Modified();
}
double
mitk::SlicedGeometry3D::CalculateSpacing( const mitk::Vector3D &d ) const
{
// Need the spacing of the underlying dataset / geometry
if ( !m_ReferenceGeometry )
{
return 1.0;
}
const mitk::Vector3D &spacing = m_ReferenceGeometry->GetSpacing();
return SlicedGeometry3D::CalculateSpacing( spacing, d );
}
double mitk::SlicedGeometry3D::CalculateSpacing( const mitk::Vector3D spacing, const mitk::Vector3D &d )
{
// The following can be derived from the ellipsoid equation
//
// 1 = x^2/a^2 + y^2/b^2 + z^2/c^2
//
// where (a,b,c) = spacing of original volume (ellipsoid radii)
// and (x,y,z) = scaled coordinates of vector d (according to ellipsoid)
//
double scaling = d[0]*d[0] / (spacing[0] * spacing[0])
+ d[1]*d[1] / (spacing[1] * spacing[1])
+ d[2]*d[2] / (spacing[2] * spacing[2]);
scaling = sqrt( scaling );
return ( sqrt( d[0]*d[0] + d[1]*d[1] + d[2]*d[2] ) / scaling );
}
mitk::Vector3D
mitk::SlicedGeometry3D::AdjustNormal( const mitk::Vector3D &normal ) const
{
Geometry3D::TransformType::Pointer inverse = Geometry3D::TransformType::New();
m_ReferenceGeometry->GetIndexToWorldTransform()->GetInverse( inverse );
Vector3D transformedNormal = inverse->TransformVector( normal );
transformedNormal.Normalize();
return transformedNormal;
}
void
mitk::SlicedGeometry3D::SetImageGeometry( const bool isAnImageGeometry )
{
Superclass::SetImageGeometry( isAnImageGeometry );
mitk::Geometry3D* geometry;
unsigned int s;
for ( s = 0; s < m_Slices; ++s )
{
geometry = m_Geometry2Ds[s];
if ( geometry!=NULL )
{
geometry->SetImageGeometry( isAnImageGeometry );
}
}
}
void
mitk::SlicedGeometry3D::ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry )
{
mitk::Geometry3D* geometry;
unsigned int s;
for ( s = 0; s < m_Slices; ++s )
{
geometry = m_Geometry2Ds[s];
if ( geometry!=NULL )
{
geometry->ChangeImageGeometryConsideringOriginOffset( isAnImageGeometry );
}
}
Superclass::ChangeImageGeometryConsideringOriginOffset( isAnImageGeometry );
}
bool
mitk::SlicedGeometry3D::IsValidSlice( int s ) const
{
return ((s >= 0) && (s < (int)m_Slices));
}
void
mitk::SlicedGeometry3D::SetReferenceGeometry( Geometry3D *referenceGeometry )
{
m_ReferenceGeometry = referenceGeometry;
std::vector<Geometry2D::Pointer>::iterator it;
for ( it = m_Geometry2Ds.begin(); it != m_Geometry2Ds.end(); ++it )
{
(*it)->SetReferenceGeometry( referenceGeometry );
}
}
void
mitk::SlicedGeometry3D::SetSpacing( const mitk::Vector3D &aSpacing )
{
bool hasEvenlySpacedPlaneGeometry = false;
mitk::Point3D origin;
mitk::Vector3D rightDV, bottomDV;
BoundingBox::BoundsArrayType bounds;
assert(aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0);
// In case of evenly-spaced data: re-initialize instances of Geometry2D,
// since the spacing influences them
if ((m_EvenlySpaced) && (m_Geometry2Ds.size() > 0))
{
mitk::Geometry2D::ConstPointer firstGeometry =
m_Geometry2Ds[0].GetPointer();
const PlaneGeometry *planeGeometry =
dynamic_cast< const PlaneGeometry * >( firstGeometry.GetPointer() );
if (planeGeometry != NULL )
{
this->WorldToIndex( planeGeometry->GetOrigin(), origin );
this->WorldToIndex( planeGeometry->GetAxisVector(0), rightDV );
this->WorldToIndex( planeGeometry->GetAxisVector(1), bottomDV );
bounds = planeGeometry->GetBounds();
hasEvenlySpacedPlaneGeometry = true;
}
}
Superclass::SetSpacing(aSpacing);
mitk::Geometry2D::Pointer firstGeometry;
// In case of evenly-spaced data: re-initialize instances of Geometry2D,
// since the spacing influences them
if ( hasEvenlySpacedPlaneGeometry )
{
//create planeGeometry according to new spacing
this->IndexToWorld( origin, origin );
this->IndexToWorld( rightDV, rightDV );
this->IndexToWorld( bottomDV, bottomDV );
mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
planeGeometry->SetImageGeometry( this->GetImageGeometry() );
planeGeometry->SetReferenceGeometry( m_ReferenceGeometry );
planeGeometry->InitializeStandardPlane(
rightDV.Get_vnl_vector(), bottomDV.Get_vnl_vector(), &m_Spacing );
planeGeometry->SetOrigin(origin);
planeGeometry->SetBounds(bounds);
firstGeometry = planeGeometry;
}
else if ( (m_EvenlySpaced) && (m_Geometry2Ds.size() > 0) )
{
firstGeometry = m_Geometry2Ds[0].GetPointer();
}
//clear and reserve
Geometry2D::Pointer gnull=NULL;
m_Geometry2Ds.assign(m_Slices, gnull);
if ( m_Slices > 0 )
{
m_Geometry2Ds[0] = firstGeometry;
}
this->Modified();
}
void
mitk::SlicedGeometry3D
::SetSliceNavigationController( SliceNavigationController *snc )
{
m_SliceNavigationController = snc;
}
mitk::SliceNavigationController *
mitk::SlicedGeometry3D::GetSliceNavigationController()
{
return m_SliceNavigationController;
}
void
mitk::SlicedGeometry3D::SetEvenlySpaced(bool on)
{
if(m_EvenlySpaced!=on)
{
m_EvenlySpaced=on;
this->Modified();
}
}
void
mitk::SlicedGeometry3D
::SetDirectionVector( const mitk::Vector3D& directionVector )
{
Vector3D newDir = directionVector;
newDir.Normalize();
if ( newDir != m_DirectionVector )
{
m_DirectionVector = newDir;
this->Modified();
}
}
void
mitk::SlicedGeometry3D::SetTimeBounds( const mitk::TimeBounds& timebounds )
{
Superclass::SetTimeBounds( timebounds );
unsigned int s;
for ( s = 0; s < m_Slices; ++s )
{
if(m_Geometry2Ds[s].IsNotNull())
{
m_Geometry2Ds[s]->SetTimeBounds( timebounds );
}
}
m_TimeBounds = timebounds;
}
mitk::AffineGeometryFrame3D::Pointer
mitk::SlicedGeometry3D::Clone() const
{
Self::Pointer newGeometry = new SlicedGeometry3D(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
void
mitk::SlicedGeometry3D::PrintSelf( std::ostream& os, itk::Indent indent ) const
{
Superclass::PrintSelf(os,indent);
os << indent << " EvenlySpaced: " << m_EvenlySpaced << std::endl;
if ( m_EvenlySpaced )
{
os << indent << " DirectionVector: " << m_DirectionVector << std::endl;
}
os << indent << " Slices: " << m_Slices << std::endl;
os << std::endl;
os << indent << " GetGeometry2D(0): ";
if ( this->GetGeometry2D(0) == NULL )
{
os << "NULL" << std::endl;
}
else
{
this->GetGeometry2D(0)->Print(os, indent);
}
}
void
mitk::SlicedGeometry3D::ExecuteOperation(Operation* operation)
{
switch ( operation->GetOperationType() )
{
case OpNOTHING:
break;
case OpROTATE:
if ( m_EvenlySpaced )
{
// Need a reference frame to align the rotation
if ( m_ReferenceGeometry )
{
// Clear all generated geometries and then rotate only the first slice.
// The other slices will be re-generated on demand
// Save first slice
Geometry2D::Pointer geometry2D = m_Geometry2Ds[0];
RotationOperation *rotOp = dynamic_cast< RotationOperation * >( operation );
// Generate a RotationOperation using the dataset center instead of
// the supplied rotation center. This is necessary so that the rotated
// zero-plane does not shift away. The supplied center is instead used
// to adjust the slice stack afterwards.
Point3D center = m_ReferenceGeometry->GetCenter();
RotationOperation centeredRotation(
rotOp->GetOperationType(),
center,
rotOp->GetVectorOfRotation(),
rotOp->GetAngleOfRotation()
);
// Rotate first slice
geometry2D->ExecuteOperation( &centeredRotation );
// Clear the slice stack and adjust it according to the center of
// the dataset and the supplied rotation center (see documentation of
// ReinitializePlanes)
this->ReinitializePlanes( center, rotOp->GetCenterOfRotation() );
geometry2D->SetSpacing(this->GetSpacing());
if ( m_SliceNavigationController )
{
m_SliceNavigationController->SelectSliceByPoint(
rotOp->GetCenterOfRotation() );
m_SliceNavigationController->AdjustSliceStepperRange();
}
Geometry3D::ExecuteOperation( &centeredRotation );
}
}
else
{
// Reach through to all slices
for (std::vector<Geometry2D::Pointer>::iterator iter = m_Geometry2Ds.begin();
iter != m_Geometry2Ds.end();
++iter)
{
(*iter)->ExecuteOperation(operation);
}
}
break;
case OpORIENT:
if ( m_EvenlySpaced )
{
// Save first slice
Geometry2D::Pointer geometry2D = m_Geometry2Ds[0];
PlaneGeometry *planeGeometry = dynamic_cast< PlaneGeometry * >(
geometry2D.GetPointer() );
PlaneOperation *planeOp = dynamic_cast< PlaneOperation * >( operation );
// Need a PlaneGeometry, a PlaneOperation and a reference frame to
// carry out the re-orientation
if ( m_ReferenceGeometry && planeGeometry && planeOp )
{
// Clear all generated geometries and then rotate only the first slice.
// The other slices will be re-generated on demand
// Generate a RotationOperation by calculating the angle between
// the current and the requested slice orientation
Point3D center = m_ReferenceGeometry->GetCenter();
const mitk::Vector3D &currentNormal = planeGeometry->GetNormal();
const mitk::Vector3D &newNormal = planeOp->GetNormal();
Vector3D rotationAxis = itk::CrossProduct( newNormal, currentNormal );
vtkFloatingPointType rotationAngle = - atan2(
(double) rotationAxis.GetNorm(),
(double) (newNormal * currentNormal) );
rotationAngle *= 180.0 / vnl_math::pi;
RotationOperation centeredRotation(
mitk::OpROTATE,
center,
rotationAxis,
rotationAngle
);
// Rotate first slice
geometry2D->ExecuteOperation( &centeredRotation );
// Clear the slice stack and adjust it according to the center of
// rotation and plane position (see documentation of ReinitializePlanes)
this->ReinitializePlanes( center, planeOp->GetPoint() );
if ( m_SliceNavigationController )
{
m_SliceNavigationController->SelectSliceByPoint( planeOp->GetPoint() );
m_SliceNavigationController->AdjustSliceStepperRange();
}
Geometry3D::ExecuteOperation( &centeredRotation );
}
}
else
{
// Reach through to all slices
for (std::vector<Geometry2D::Pointer>::iterator iter = m_Geometry2Ds.begin();
iter != m_Geometry2Ds.end();
++iter)
{
(*iter)->ExecuteOperation(operation);
}
}
break;
case OpRESTOREPLANEPOSITION:
if ( m_EvenlySpaced )
{
// Save first slice
Geometry2D::Pointer geometry2D = m_Geometry2Ds[0];
PlaneGeometry* planeGeometry = dynamic_cast< PlaneGeometry * >(
geometry2D.GetPointer() );
RestorePlanePositionOperation *restorePlaneOp = dynamic_cast< RestorePlanePositionOperation* >( operation );
// Need a PlaneGeometry, a PlaneOperation and a reference frame to
// carry out the re-orientation
if ( m_ReferenceGeometry && planeGeometry && restorePlaneOp )
{
// Clear all generated geometries and then rotate only the first slice.
// The other slices will be re-generated on demand
// Rotate first slice
geometry2D->ExecuteOperation( restorePlaneOp );
m_DirectionVector = restorePlaneOp->GetDirectionVector();
double centerOfRotationDistance =
planeGeometry->SignedDistanceFromPlane( m_ReferenceGeometry->GetCenter() );
if ( centerOfRotationDistance > 0 )
{
m_DirectionVector = m_DirectionVector;
}
else
{
m_DirectionVector = -m_DirectionVector;
}
Vector3D spacing = restorePlaneOp->GetSpacing();
Superclass::SetSpacing( spacing );
// /*Now we need to calculate the number of slices in the plane's normal
// direction, so that the entire volume is covered. This is done by first
// calculating the dot product between the volume diagonal (the maximum
// distance inside the volume) and the normal, and dividing this value by
// the directed spacing calculated above.*/
ScalarType directedExtent =
fabs( m_ReferenceGeometry->GetExtentInMM( 0 ) * m_DirectionVector[0] )
+ fabs( m_ReferenceGeometry->GetExtentInMM( 1 ) * m_DirectionVector[1] )
+ fabs( m_ReferenceGeometry->GetExtentInMM( 2 ) * m_DirectionVector[2] );
if ( directedExtent >= spacing[2] )
{
m_Slices = static_cast< unsigned int >(directedExtent / spacing[2] + 0.5);
}
else
{
m_Slices = 1;
}
m_Geometry2Ds.assign( m_Slices, Geometry2D::Pointer( NULL ) );
if ( m_Slices > 0 )
{
m_Geometry2Ds[0] = geometry2D;
}
m_SliceNavigationController->GetSlice()->SetSteps( m_Slices );
this->Modified();
//End Reinitialization
if ( m_SliceNavigationController )
{
m_SliceNavigationController->GetSlice()->SetPos( restorePlaneOp->GetPos() );
m_SliceNavigationController->AdjustSliceStepperRange();
}
Geometry3D::ExecuteOperation(restorePlaneOp);
}
}
else
{
// Reach through to all slices
for (std::vector<Geometry2D::Pointer>::iterator iter = m_Geometry2Ds.begin();
iter != m_Geometry2Ds.end();
++iter)
{
(*iter)->ExecuteOperation(operation);
}
}
break;
}
this->Modified();
}
diff --git a/Core/Code/DataManagement/mitkSlicedGeometry3D.h b/Core/Code/DataManagement/mitkSlicedGeometry3D.h
index 6523b65af6..b4391c4383 100644
--- a/Core/Code/DataManagement/mitkSlicedGeometry3D.h
+++ b/Core/Code/DataManagement/mitkSlicedGeometry3D.h
@@ -1,325 +1,324 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSLICEDGEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD
#define MITKSLICEDGEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD
#include "mitkGeometry3D.h"
#include "mitkPlaneGeometry.h"
namespace mitk {
class SliceNavigationController;
class NavigationController;
/** \brief Describes the geometry of a data object consisting of slices.
*
* A Geometry2D can be requested for each slice. In the case of
* \em evenly-spaced, \em plane geometries (m_EvenlySpaced==true),
* only the 2D-geometry of the first slice has to be set (to an instance of
* PlaneGeometry). The 2D geometries of the other slices are calculated
* by shifting the first slice in the direction m_DirectionVector by
* m_Spacing.z * sliceNumber. The m_Spacing member (which is only
* relevant in the case m_EvenlySpaced==true) descibes the size of a voxel
* (in mm), i.e., m_Spacing.x is the voxel width in the x-direction of the
* plane. It is derived from the reference geometry of this SlicedGeometry3D,
* which usually would be the global geometry describing how datasets are to
* be resliced.
*
* By default, slices are oriented in the direction of one of the main axes
* (x, y, z). However, by means of rotation, it is possible to realign the
* slices in any possible direction. In case of an inclined plane, the spacing
* is derived as a product of the (regular) geometry spacing and the direction
* vector of the plane.
*
* SlicedGeometry3D and the associated Geometry2Ds have to be initialized in
* the method GenerateOutputInformation() of BaseProcess (or CopyInformation /
* UpdateOutputInformation of BaseData, if possible, e.g., by analyzing pic
* tags in Image) subclasses. See also
*
* \sa itk::ProcessObject::GenerateOutputInformation(),
* \sa itk::DataObject::CopyInformation() and
* \a itk::DataObject::UpdateOutputInformation().
*
* Rule: everything is in mm (or ms for temporal information) if not
* stated otherwise.
*
* \warning The hull (i.e., transform, bounding-box and
* time-bounds) is only guaranteed to be up-to-date after calling
* UpdateInformation().
*
* \ingroup Geometry
*/
class MITK_CORE_EXPORT SlicedGeometry3D : public mitk::Geometry3D
{
public:
mitkClassMacro(SlicedGeometry3D, Geometry3D);
/** Method for creation through the object factory. */
itkNewMacro(Self);
/**
* \brief Returns the Geometry2D of the slice (\a s).
*
* If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored
* for the requested slice, and (c) the first slice (s=0)
* is a PlaneGeometry instance, then we calculate the geometry of the
* requested as the plane of the first slice shifted by m_Spacing[3]*s
* in the direction of m_DirectionVector.
*
* \warning The Geometry2Ds are not necessarily up-to-date and not even
* initialized.
*
* The Geometry2Ds have to be initialized in the method
* GenerateOutputInformation() of BaseProcess (or CopyInformation /
* UpdateOutputInformation of BaseData, if possible, e.g., by analyzing
* pic tags in Image) subclasses. See also
*
* \sa itk::ProcessObject::GenerateOutputInformation(),
* \sa itk::DataObject::CopyInformation() and
* \sa itk::DataObject::UpdateOutputInformation().
*/
virtual mitk::Geometry2D* GetGeometry2D( int s ) const;
/**
* \brief Set Geometry2D of slice \a s.
*/
virtual bool SetGeometry2D( mitk::Geometry2D *geometry2D, int s );
//##Documentation
//## @brief When switching from an Image Geometry to a normal Geometry (and the other way around), you have to change the origin as well (See Geometry Documentation)! This function will change the "isImageGeometry" bool flag and changes the origin respectively.
virtual void ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry );
virtual void SetTimeBounds( const mitk::TimeBounds& timebounds );
virtual const mitk::BoundingBox* GetBoundingBox() const;
/**
* \brief Get the number of slices
*/
itkGetConstMacro( Slices, unsigned int );
/**
* \brief Check whether a slice exists
*/
virtual bool IsValidSlice( int s = 0 ) const;
virtual void SetReferenceGeometry( Geometry3D *referenceGeometry );
/**
* \brief Set the spacing (m_Spacing), in direction of the plane normal.
*
* INTERNAL METHOD.
*/
virtual void SetSpacing( const mitk::Vector3D &aSpacing );
/**
* \brief Set the SliceNavigationController corresponding to this sliced
* geometry.
*
* The SNC needs to be informed when the number of slices in the geometry
* changes, which can occur whenthe slices are re-oriented by rotation.
*/
virtual void SetSliceNavigationController(
mitk::SliceNavigationController *snc );
mitk::SliceNavigationController *GetSliceNavigationController();
/**
* \brief Set/Get whether the SlicedGeometry3D is evenly-spaced
* (m_EvenlySpaced)
*
* If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored for
* the requested slice, and (c) the first slice (s=0) is a PlaneGeometry
* instance, then we calculate the geometry of the requested as the plane
* of the first slice shifted by m_Spacing.z * s in the direction of
* m_DirectionVector.
*
* \sa GetGeometry2D
*/
itkGetConstMacro(EvenlySpaced, bool);
virtual void SetEvenlySpaced(bool on = true);
/**
* \brief Set/Get the vector between slices for the evenly-spaced case
* (m_EvenlySpaced==true).
*
* If the direction-vector is (0,0,0) (the default) and the first
* 2D geometry is a PlaneGeometry, then the direction-vector will be
* calculated from the plane normal.
*
* \sa m_DirectionVector
*/
virtual void SetDirectionVector(const mitk::Vector3D& directionVector);
itkGetConstMacro(DirectionVector, const mitk::Vector3D&);
virtual AffineGeometryFrame3D::Pointer Clone() const;
static const std::string SLICES;
const static std::string DIRECTION_VECTOR;
const static std::string EVENLY_SPACED;
/**
* \brief Tell this instance how many Geometry2Ds it shall manage. Bounding
* box and the Geometry2Ds must be set additionally by calling the respective
* methods!
*
* \warning Bounding box and the 2D-geometries must be set additionally: use
* SetBounds(), SetGeometry().
*/
virtual void InitializeSlicedGeometry( unsigned int slices );
/**
* \brief Completely initialize this instance as evenly-spaced with slices
* parallel to the provided Geometry2D that is used as the first slice and
* for spacing calculation.
*
* Initializes the bounding box according to the width/height of the
* Geometry2D and \a slices. The spacing is calculated from the Geometry2D.
*/
virtual void InitializeEvenlySpaced( mitk::Geometry2D *geometry2D,
unsigned int slices, bool flipped=false );
/**
* \brief Completely initialize this instance as evenly-spaced with slices
* parallel to the provided Geometry2D that is used as the first slice and
* for spacing calculation (except z-spacing).
*
* Initializes the bounding box according to the width/height of the
* Geometry2D and \a slices. The x-/y-spacing is calculated from the
* Geometry2D.
*/
virtual void InitializeEvenlySpaced( mitk::Geometry2D *geometry2D,
mitk::ScalarType zSpacing, unsigned int slices, bool flipped=false );
/**
* \brief Completely initialize this instance as evenly-spaced plane slices
* parallel to a side of the provided Geometry3D and using its spacing
* information.
*
* Initializes the bounding box according to the width/height of the
* Geometry3D and the number of slices according to
* Geometry3D::GetExtent(2).
*
* \param planeorientation side parallel to which the slices will be oriented
* \param top if \a true, create plane at top, otherwise at bottom
* (for PlaneOrientation Transversal, for other plane locations respectively)
* \param frontside defines the side of the plane (the definition of
* front/back is somewhat arbitrary)
*
* \param rotate rotates the plane by 180 degree around its normal (the
* definition of rotated vs not rotated is somewhat arbitrary)
*/
virtual void InitializePlanes( const mitk::Geometry3D *geometry3D,
mitk::PlaneGeometry::PlaneOrientation planeorientation, bool top=true,
bool frontside=true, bool rotated=false );
virtual void SetImageGeometry(const bool isAnImageGeometry);
virtual void ExecuteOperation(Operation* operation);
static double CalculateSpacing( const mitk::Vector3D spacing, const mitk::Vector3D &d );
protected:
SlicedGeometry3D();
SlicedGeometry3D(const SlicedGeometry3D& other);
virtual ~SlicedGeometry3D();
/**
* Reinitialize plane stack after rotation. More precisely, the first plane
* of the stack needs to spatially aligned, in two respects:
*
* 1. Re-alignment with respect to the dataset center; this is necessary
* since the distance from the first plane to the center could otherwise
* continuously decrease or increase.
* 2. Re-alignment with respect to a given reference point; the reference
* point is a location which the user wants to be exactly touched by one
* plane of the plane stack. The first plane is minimally shifted to
* ensure this touching. Usually, the reference point would be the
* point around which the geometry is rotated.
*/
virtual void ReinitializePlanes( const Point3D &center,
const Point3D &referencePoint );
ScalarType GetLargestExtent( const Geometry3D *geometry );
void PrintSelf(std::ostream& os, itk::Indent indent) const;
/** Calculate "directed spacing", i.e. the spacing in directions
* non-orthogonal to the coordinate axes. This is done via the
* ellipsoid equation.
*/
double CalculateSpacing( const mitk::Vector3D &direction ) const;
/** The extent of the slice stack, i.e. the number of slices, depends on the
* plane normal. For rotated geometries, the geometry's transform needs to
* be accounted in this calculation.
*/
mitk::Vector3D AdjustNormal( const mitk::Vector3D &normal ) const;
/**
* Container for the 2D-geometries contained within this SliceGeometry3D.
*/
mutable std::vector<Geometry2D::Pointer> m_Geometry2Ds;
/**
* If (a) m_EvenlySpaced==true, (b) we don't have a Geometry2D stored
* for the requested slice, and (c) the first slice (s=0)
* is a PlaneGeometry instance, then we calculate the geometry of the
* requested as the plane of the first slice shifted by m_Spacing.z*s
* in the direction of m_DirectionVector.
*
* \sa GetGeometry2D
*/
bool m_EvenlySpaced;
/**
* Vector between slices for the evenly-spaced case (m_EvenlySpaced==true).
* If the direction-vector is (0,0,0) (the default) and the first
* 2D geometry is a PlaneGeometry, then the direction-vector will be
* calculated from the plane normal.
*/
mutable mitk::Vector3D m_DirectionVector;
/** Number of slices this SliceGeometry3D is descibing. */
unsigned int m_Slices;
/** Underlying Geometry3D for this SlicedGeometry */
mitk::Geometry3D *m_ReferenceGeometry;
/** SNC correcsponding to this geometry; used to reflect changes in the
* number of slices due to rotation. */
//mitk::NavigationController *m_NavigationController;
mitk::SliceNavigationController *m_SliceNavigationController;
};
} // namespace mitk
#endif /* MITKSLICEDGEOMETRY3D_H_HEADER_INCLUDED_C1EBD0AD */
diff --git a/Core/Code/DataManagement/mitkSmartPointerProperty.cpp b/Core/Code/DataManagement/mitkSmartPointerProperty.cpp
index 637623ce60..83b9a6c6f5 100644
--- a/Core/Code/DataManagement/mitkSmartPointerProperty.cpp
+++ b/Core/Code/DataManagement/mitkSmartPointerProperty.cpp
@@ -1,131 +1,130 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSmartPointerProperty.h"
mitk::SmartPointerProperty::ReferenceCountMapType mitk::SmartPointerProperty::m_ReferenceCount;
mitk::SmartPointerProperty::ReferencesUIDMapType mitk::SmartPointerProperty::m_ReferencesUID;
mitk::SmartPointerProperty::ReadInSmartPointersMapType mitk::SmartPointerProperty::m_ReadInInstances;
mitk::SmartPointerProperty::ReadInTargetsMapType mitk::SmartPointerProperty::m_ReadInTargets;
mitk::UIDGenerator mitk::SmartPointerProperty::m_UIDGenerator("POINTER_");
void mitk::SmartPointerProperty::PostProcessXMLReading()
{
for (ReadInSmartPointersMapType::iterator iter = m_ReadInInstances.begin();
iter != m_ReadInInstances.end();
++iter)
{
if ( m_ReadInTargets.find(iter->second) != m_ReadInTargets.end() )
{
iter->first->SetSmartPointer( m_ReadInTargets[ iter->second ] );
}
}
m_ReadInInstances.clear();
}
/// \return The number of SmartPointerProperties that point to @param object
unsigned int mitk::SmartPointerProperty::GetReferenceCountFor(itk::Object* object)
{
if ( m_ReferenceCount.find(object) != m_ReferenceCount.end() )
{
return m_ReferenceCount[object];
}
else
{
return 0;
}
}
void mitk::SmartPointerProperty::RegisterPointerTarget(itk::Object* object, const std::string uid)
{
m_ReadInTargets[uid] = object;
}
std::string mitk::SmartPointerProperty::GetReferenceUIDFor(itk::Object* object)
{
if ( m_ReferencesUID.find(object) != m_ReferencesUID.end() )
{
return m_ReferencesUID[object];
}
else
{
return std::string("invalid");
}
}
bool mitk::SmartPointerProperty::IsEqual(const BaseProperty& property) const
{
return this->m_SmartPointer == static_cast<const Self&>(property).m_SmartPointer;
}
bool mitk::SmartPointerProperty::Assign(const BaseProperty& property)
{
this->m_SmartPointer = static_cast<const Self&>(property).m_SmartPointer;
return true;
}
mitk::SmartPointerProperty::SmartPointerProperty(itk::Object* pointer)
{
SetSmartPointer( pointer );
}
itk::Object::Pointer mitk::SmartPointerProperty::GetSmartPointer() const
{
return m_SmartPointer;
}
itk::Object::Pointer mitk::SmartPointerProperty::GetValue() const
{
return this->GetSmartPointer();
}
void mitk::SmartPointerProperty::SetSmartPointer(itk::Object* pointer)
{
if(m_SmartPointer.GetPointer() != pointer)
{
// keep track of referenced objects
if ( m_SmartPointer.GetPointer() && --m_ReferenceCount[m_SmartPointer.GetPointer()] == 0 ) // if there is no reference left, delete entry
{
m_ReferenceCount.erase( m_SmartPointer.GetPointer() );
m_ReferencesUID.erase( m_SmartPointer.GetPointer() );
}
if ( pointer && ++m_ReferenceCount[pointer] == 1 ) // first reference --> generate UID
{
m_ReferencesUID[pointer] = m_UIDGenerator.GetUID();
}
// change pointer
m_SmartPointer = pointer;
Modified();
}
}
void mitk::SmartPointerProperty::SetValue(const ValueType & value)
{
this->SetSmartPointer(value.GetPointer());
}
std::string mitk::SmartPointerProperty::GetValueAsString() const
{
if ( m_SmartPointer.IsNotNull() )
return m_ReferencesUID[ m_SmartPointer.GetPointer() ];
else
return std::string("NULL");
}
diff --git a/Core/Code/DataManagement/mitkSmartPointerProperty.h b/Core/Code/DataManagement/mitkSmartPointerProperty.h
index d418a191eb..cc07d1a8e9 100644
--- a/Core/Code/DataManagement/mitkSmartPointerProperty.h
+++ b/Core/Code/DataManagement/mitkSmartPointerProperty.h
@@ -1,106 +1,105 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSMARTPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791
#define MITKSMARTPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791
#include <MitkExports.h>
#include "mitkBaseProperty.h"
#include "mitkUIDGenerator.h"
#include<map>
#include<list>
#include<string>
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
//##Documentation
//## @brief Property containing a smart-pointer
//## @ingroup DataManagement
class MITK_CORE_EXPORT SmartPointerProperty : public BaseProperty
{
public:
mitkClassMacro(SmartPointerProperty, BaseProperty);
itkNewMacro(SmartPointerProperty);
mitkNewMacro1Param(SmartPointerProperty, itk::Object*);
typedef itk::Object::Pointer ValueType;
itk::Object::Pointer GetSmartPointer() const;
ValueType GetValue() const;
void SetSmartPointer(itk::Object*);
void SetValue(const ValueType&);
/// mainly for XML output
virtual std::string GetValueAsString() const;
static void PostProcessXMLReading();
/// Return the number of SmartPointerProperties that reference the object given as parameter
static unsigned int GetReferenceCountFor(itk::Object*);
static std::string GetReferenceUIDFor(itk::Object*);
static void RegisterPointerTarget(itk::Object*, const std::string uid);
using BaseProperty::operator=;
protected:
SmartPointerProperty(itk::Object* = NULL);
itk::Object::Pointer m_SmartPointer;
private:
// purposely not implemented
SmartPointerProperty(const SmartPointerProperty&);
SmartPointerProperty& operator=(const SmartPointerProperty&);
virtual bool IsEqual(const BaseProperty&) const;
virtual bool Assign(const BaseProperty&);
typedef std::map<itk::Object*, unsigned int> ReferenceCountMapType;
typedef std::map<itk::Object*, std::string> ReferencesUIDMapType;
typedef std::map<SmartPointerProperty*, std::string> ReadInSmartPointersMapType;
typedef std::map<std::string, itk::Object*> ReadInTargetsMapType;
/// for each itk::Object* count how many SmartPointerProperties point to it
static ReferenceCountMapType m_ReferenceCount;
static ReferencesUIDMapType m_ReferencesUID;
static ReadInSmartPointersMapType m_ReadInInstances;
static ReadInTargetsMapType m_ReadInTargets;
/// to generate unique IDs for the objects pointed at (during XML writing)
static UIDGenerator m_UIDGenerator;
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif /* MITKSMARTPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791 */
diff --git a/Core/Code/DataManagement/mitkStandaloneDataStorage.cpp b/Core/Code/DataManagement/mitkStandaloneDataStorage.cpp
index f7f67a96ea..e4276d5d36 100644
--- a/Core/Code/DataManagement/mitkStandaloneDataStorage.cpp
+++ b/Core/Code/DataManagement/mitkStandaloneDataStorage.cpp
@@ -1,250 +1,249 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStandaloneDataStorage.h"
#include "mitkDataNode.h"
#include "mitkProperties.h"
#include "mitkNodePredicateBase.h"
#include "mitkNodePredicateProperty.h"
#include "mitkGroupTagProperty.h"
#include "itkSimpleFastMutexLock.h"
#include "itkMutexLockHolder.h"
mitk::StandaloneDataStorage::StandaloneDataStorage()
: mitk::DataStorage()
{
}
mitk::StandaloneDataStorage::~StandaloneDataStorage()
{
for(AdjacencyList::iterator it = m_SourceNodes.begin();
it != m_SourceNodes.end(); it++)
{
this->RemoveListeners(it->first);
}
}
bool mitk::StandaloneDataStorage::IsInitialized() const
{
return true;
}
void mitk::StandaloneDataStorage::Add(mitk::DataNode* node, const mitk::DataStorage::SetOfObjects* parents)
{
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
if (!IsInitialized())
throw std::logic_error("DataStorage not initialized");
/* check if node is in its own list of sources */
if ((parents != NULL) && (std::find(parents->begin(), parents->end(), node) != parents->end()))
throw std::invalid_argument("Node is it's own parent");
/* check if node already exists in StandaloneDataStorage */
if (m_SourceNodes.find(node) != m_SourceNodes.end())
throw std::invalid_argument("Node is already in DataStorage");
/* create parent list if it does not exist */
mitk::DataStorage::SetOfObjects::ConstPointer sp;
if (parents != NULL)
sp = parents;
else
sp = mitk::DataStorage::SetOfObjects::New();
/* Store node and parent list in sources adjacency list */
m_SourceNodes.insert(std::make_pair(node, sp));
/* Store node and an empty children list in derivations adjacency list */
mitk::DataStorage::SetOfObjects::Pointer children = mitk::DataStorage::SetOfObjects::New();
m_DerivedNodes.insert(std::make_pair(node, children));
/* create entry in derivations adjacency list for each parent of the new node */
for (SetOfObjects::ConstIterator it = sp->Begin(); it != sp->End(); it++)
{
mitk::DataNode::ConstPointer parent = it.Value().GetPointer();
mitk::DataStorage::SetOfObjects::ConstPointer derivedObjects = m_DerivedNodes[parent]; // get or create pointer to list of derived objects for that parent node
if (derivedObjects.IsNull())
m_DerivedNodes[parent] = mitk::DataStorage::SetOfObjects::New(); // Create a set of Objects, if it does not already exist
mitk::DataStorage::SetOfObjects* deob = const_cast<mitk::DataStorage::SetOfObjects*>(m_DerivedNodes[parent].GetPointer()); // temporarily get rid of const pointer to insert new element
deob->InsertElement(deob->Size(), node); // node is derived from parent. Insert it into the parents list of derived objects
}
// register for ITK changed events
this->AddListeners(node);
}
/* Notify observers */
EmitAddNodeEvent(node);
}
void mitk::StandaloneDataStorage::Remove(const mitk::DataNode* node)
{
if (!IsInitialized())
throw std::logic_error("DataStorage not initialized");
if (node == NULL)
return;
// remove ITK modified event listener
this->RemoveListeners(node);
// muellerm, 22.9.10: add additional reference count to ensure
// that the node is not deleted when removed from the relation map
// while m_Mutex is locked. This would cause the an itk::DeleteEvent
// is thrown and a deadlock will occur when event receivers
// access the DataStorage again in their event processing function
//
mitk::DataNode::ConstPointer nodeGuard(node);
/* Notify observers of imminent node removal */
EmitRemoveNodeEvent(node);
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
/* remove node from both relation adjacency lists */
this->RemoveFromRelation(node, m_SourceNodes);
this->RemoveFromRelation(node, m_DerivedNodes);
}
}
bool mitk::StandaloneDataStorage::Exists(const mitk::DataNode* node) const
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
return (m_SourceNodes.find(node) != m_SourceNodes.end());
}
void mitk::StandaloneDataStorage::RemoveFromRelation(const mitk::DataNode* node, AdjacencyList& relation)
{
for (AdjacencyList::const_iterator mapIter = relation.begin(); mapIter != relation.end(); ++mapIter) // for each node in the relation
if (mapIter->second.IsNotNull()) // if node has a relation list
{
SetOfObjects::Pointer s = const_cast<SetOfObjects*>(mapIter->second.GetPointer()); // search for node to be deleted in the relation list
SetOfObjects::STLContainerType::iterator relationListIter = std::find(s->begin(), s->end(), node); // this assumes, that the relation list does not contain duplicates (which should be safe to assume)
if (relationListIter != s->end()) // if node to be deleted is in relation list
s->erase(relationListIter); // remove it from parentlist
}
/* now remove node from the relation */
AdjacencyList::iterator adIt;
adIt = relation.find(node);
if (adIt != relation.end())
relation.erase(adIt);
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetAll() const
{
itk::MutexLockHolder<itk::SimpleFastMutexLock > locked(m_Mutex);
if (!IsInitialized())
throw std::logic_error("DataStorage not initialized");
mitk::DataStorage::SetOfObjects::Pointer resultset = mitk::DataStorage::SetOfObjects::New();
/* Fill resultset with all objects that are managed by the StandaloneDataStorage object */
unsigned int index = 0;
for (AdjacencyList::const_iterator it = m_SourceNodes.begin(); it != m_SourceNodes.end(); ++it)
if (it->first.IsNull())
continue;
else
resultset->InsertElement(index++, const_cast<mitk::DataNode*>(it->first.GetPointer()));
return SetOfObjects::ConstPointer(resultset);
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetRelations(const mitk::DataNode* node, const AdjacencyList& relation, const NodePredicateBase* condition, bool onlyDirectlyRelated) const
{
if (node == NULL)
throw std::invalid_argument("invalid node");
/* Either read direct relations directly from adjacency list */
if (onlyDirectlyRelated)
{
AdjacencyList::const_iterator it = relation.find(node); // get parents of current node
if ((it == relation.end()) || (it->second.IsNull())) // node not found in list or no set of parents
return SetOfObjects::ConstPointer(mitk::DataStorage::SetOfObjects::New()); // return an empty set
else
return this->FilterSetOfObjects(it->second, condition);
}
/* Or traverse adjacency list to collect all related nodes */
std::vector<mitk::DataNode::ConstPointer> resultset;
std::vector<mitk::DataNode::ConstPointer> openlist;
/* Initialize openlist with node. this will add node to resultset,
but that is necessary to detect circular relations that would lead to endless recursion */
openlist.push_back(node);
while (openlist.size() > 0)
{
mitk::DataNode::ConstPointer current = openlist.back(); // get element that needs to be processed
openlist.pop_back(); // remove last element, because it gets processed now
resultset.push_back(current); // add current element to resultset
AdjacencyList::const_iterator it = relation.find(current); // get parents of current node
if ( (it == relation.end()) // if node not found in list
|| (it->second.IsNull()) // or no set of parents available
|| (it->second->Size() == 0)) // or empty set of parents
continue; // then continue with next node in open list
else
for (SetOfObjects::ConstIterator parentIt = it->second->Begin(); parentIt != it->second->End(); ++parentIt) // for each parent of current node
{
mitk::DataNode::ConstPointer p = parentIt.Value().GetPointer();
if ( !(std::find(resultset.begin(), resultset.end(), p) != resultset.end()) // if it is not already in resultset
&& !(std::find(openlist.begin(), openlist.end(), p) != openlist.end())) // and not already in openlist
openlist.push_back(p); // then add it to openlist, so that it can be processed
}
}
/* now finally copy the results to a proper SetOfObjects variable exluding the initial node and checking the condition if any is given */
mitk::DataStorage::SetOfObjects::Pointer realResultset = mitk::DataStorage::SetOfObjects::New();
if (condition != NULL)
{
for (std::vector<mitk::DataNode::ConstPointer>::iterator resultIt = resultset.begin(); resultIt != resultset.end(); resultIt++)
if ((*resultIt != node) && (condition->CheckNode(*resultIt) == true))
realResultset->InsertElement(realResultset->Size(), mitk::DataNode::Pointer(const_cast<mitk::DataNode*>((*resultIt).GetPointer())));
}
else
{
for (std::vector<mitk::DataNode::ConstPointer>::iterator resultIt = resultset.begin(); resultIt != resultset.end(); resultIt++)
if (*resultIt != node)
realResultset->InsertElement(realResultset->Size(), mitk::DataNode::Pointer(const_cast<mitk::DataNode*>((*resultIt).GetPointer())));
}
return SetOfObjects::ConstPointer(realResultset);
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetSources(const mitk::DataNode* node, const NodePredicateBase* condition, bool onlyDirectSources) const
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
return this->GetRelations(node, m_SourceNodes, condition, onlyDirectSources);
}
mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetDerivations(const mitk::DataNode* node, const NodePredicateBase* condition, bool onlyDirectDerivations) const
{
itk::MutexLockHolder<itk::SimpleFastMutexLock>locked(m_Mutex);
return this->GetRelations(node, m_DerivedNodes, condition, onlyDirectDerivations);
}
void mitk::StandaloneDataStorage::PrintSelf(std::ostream& os, itk::Indent indent) const
{
os << indent << "StandaloneDataStorage:\n";
Superclass::PrintSelf(os, indent);
}
diff --git a/Core/Code/DataManagement/mitkStandaloneDataStorage.h b/Core/Code/DataManagement/mitkStandaloneDataStorage.h
index 47822eab88..15b387305e 100644
--- a/Core/Code/DataManagement/mitkStandaloneDataStorage.h
+++ b/Core/Code/DataManagement/mitkStandaloneDataStorage.h
@@ -1,132 +1,131 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSTANDALONEDATASTORAGE_H_HEADER_INCLUDED_
#define MITKSTANDALONEDATASTORAGE_H_HEADER_INCLUDED_
#include "mitkDataStorage.h"
#include "mitkMessage.h"
#include "itkVectorContainer.h"
#include <map>
namespace mitk {
class NodePredicateBase;
class DataNode;
//##Documentation
//## @brief Data management class that handles 'was created by' relations
//##
//## The StandaloneDataStorage provides data storage and management functionality.
//## It handles a 'was created by' relation by associating each data object with a
//## set of source objects that were used to create the new object was created from.
//## Thus, nodes are stored in a noncyclical directed graph data structure.
//## It is derived from mitk::DataStorage and implements its interface,
//## including AddNodeEvent and RemoveNodeEvent.
//## @ingroup StandaloneDataStorage
class MITK_CORE_EXPORT StandaloneDataStorage : public mitk::DataStorage
{
public:
mitkClassMacro(StandaloneDataStorage, mitk::DataStorage);
itkNewMacro(Self);
//##Documentation
//## @brief Adds a DataNode containing a data object to its internal storage
//##
//## This Method adds a new data object to the StandaloneDataStorage. The new object is
//## passed in the first parameter. The second parameter is a set
//## of source objects, that were used to create this object. The new object will have
//## a 'was created from' relation to its source objects.
//## the addition of a new object will fire the notification mechanism.
//## If the node parameter is NULL or if the DataNode has already been added,
//## an exception will be thrown.
void Add(mitk::DataNode* node, const mitk::DataStorage::SetOfObjects* parents = NULL);
//##Documentation
//## @brief Removes node from the StandaloneDataStorage
//##
void Remove(const mitk::DataNode* node);
//##Documentation
//## @brief Checks if a node exists in the StandaloneDataStorage
//##
virtual bool Exists(const mitk::DataNode* node) const;
//##Documentation
//## @brief returns a set of source objects for a given node that meet the given condition(s).
//##
SetOfObjects::ConstPointer GetSources(const mitk::DataNode* node, const NodePredicateBase* condition = NULL, bool onlyDirectSources = true) const;
//##Documentation
//## @brief returns a set of derived objects for a given node.
//##
//## GetDerivations() returns a set of objects that are derived from the DataNode node.
//## This means, that node was used to create the returned objects. If the parameter
//## onlyDirectDerivations is set to true (default value), only objects that directly have
//## node as one of their source objects will be returned. Otherwise, objects that are
//## derived from derivations of node are returned too.
//## The derived objects can be filtered with a predicate object as described in the GetSubset()
//## method by providing a predicate as the condition parameter.
SetOfObjects::ConstPointer GetDerivations(const mitk::DataNode* node, const NodePredicateBase* condition = NULL, bool onlyDirectDerivations = true) const;
//##Documentation
//## @brief returns a set of all data objects that are stored in the data storage
//##
SetOfObjects::ConstPointer GetAll() const;
/*ITK Mutex */
mutable itk::SimpleFastMutexLock m_Mutex;
protected:
//##Documentation
//## @brief noncyclical directed graph data structure to store the nodes with their relation
typedef std::map<mitk::DataNode::ConstPointer, SetOfObjects::ConstPointer> AdjacencyList;
//##Documentation
//## @brief Standard Constructor for ::New() instantiation
StandaloneDataStorage();
//##Documentation
//## @brief Standard Destructor
virtual ~StandaloneDataStorage();
//##Documentation
//## @brief convenience method to check if the object has been initialized (i.e. a data tree has been set)
bool IsInitialized() const;
//##Documentation
//## @brief Traverses the Relation graph and extracts a list of related elements (e.g. Sources or Derivations)
SetOfObjects::ConstPointer GetRelations(const mitk::DataNode* node, const AdjacencyList& relation, const NodePredicateBase* condition = NULL, bool onlyDirectlyRelated = true) const;
//##Documentation
//## @brief deletes all references to a node in a given relation (used in Remove() and TreeListener)
void RemoveFromRelation(const mitk::DataNode* node, AdjacencyList& relation);
//##Documentation
//## @brief Prints the contents of the StandaloneDataStorage to os. Do not call directly, call ->Print() instead
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
//##Documentation
//## @brief Nodes and their relation are stored in m_SourceNodes
AdjacencyList m_SourceNodes;
//##Documentation
//## @brief Nodes are stored in reverse relation for easier traversal in the opposite direction of the relation
AdjacencyList m_DerivedNodes;
};
} // namespace mitk
#endif /* MITKSTANDALONEDATASTORAGE_H_HEADER_INCLUDED_ */
diff --git a/Core/Code/DataManagement/mitkStateTransitionOperation.cpp b/Core/Code/DataManagement/mitkStateTransitionOperation.cpp
index 3f5d2dcd87..b4aae5babb 100755
--- a/Core/Code/DataManagement/mitkStateTransitionOperation.cpp
+++ b/Core/Code/DataManagement/mitkStateTransitionOperation.cpp
@@ -1,39 +1,38 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStateTransitionOperation.h"
mitk::StateTransitionOperation::StateTransitionOperation(OperationType operationType, State* state, unsigned int time)
: mitk::Operation(operationType), m_State(state), m_Time(time)
{}
mitk::StateTransitionOperation::~StateTransitionOperation()
{
m_State = NULL;
}
mitk::State* mitk::StateTransitionOperation::GetState()
{
return m_State.GetPointer();
}
unsigned int mitk::StateTransitionOperation::GetTime()
{
return m_Time;
}
diff --git a/Core/Code/DataManagement/mitkStateTransitionOperation.h b/Core/Code/DataManagement/mitkStateTransitionOperation.h
index bfc35f029c..38dbc02af1 100755
--- a/Core/Code/DataManagement/mitkStateTransitionOperation.h
+++ b/Core/Code/DataManagement/mitkStateTransitionOperation.h
@@ -1,65 +1,64 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 STATETRANSITIONOPERATION_H_HEADER_INCLUDED_C1695462
#define STATETRANSITIONOPERATION_H_HEADER_INCLUDED_C1695462
#include <MitkExports.h>
#include "mitkOperation.h"
#include "mitkState.h"
namespace mitk {
//##Documentation
//## @brief operation, that changes the stateMachine and sets a state according to a
//## transition to an other state.
//##
//## @ingroup Undo
class MITK_CORE_EXPORT StateTransitionOperation : public Operation
{
public:
/**
* @brief default constructor
* @param[in] operationType The type of the operation
* @param[in] state The state to be stored
* @param[in] time The time according to the state; obligatory when there is only one timestep.
**/
StateTransitionOperation(OperationType operationType, State* state, unsigned int time = 0);
/**
* @brief default constructor
**/
~StateTransitionOperation();
/**
* @brief Return the state
**/
State* GetState();
/**
* @brief Return the time
**/
unsigned int GetTime();
private:
State::Pointer m_State;
unsigned int m_Time;
};
}//namespace mitk
#endif /* STATETRANSITIONOPERATION_H_HEADER_INCLUDED_C1695462 */
diff --git a/Core/Code/DataManagement/mitkStringProperty.cpp b/Core/Code/DataManagement/mitkStringProperty.cpp
index a86f8035f2..c9c294f25d 100644
--- a/Core/Code/DataManagement/mitkStringProperty.cpp
+++ b/Core/Code/DataManagement/mitkStringProperty.cpp
@@ -1,49 +1,48 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStringProperty.h"
const char* mitk::StringProperty::PATH = "path";
mitk::StringProperty::StringProperty( const char* string )
: m_Value()
{
if ( string )
m_Value = string;
}
mitk::StringProperty::StringProperty( const std::string& s )
: m_Value( s )
{
}
bool mitk::StringProperty::IsEqual(const BaseProperty& property ) const
{
return this->m_Value == static_cast<const Self&>(property).m_Value;
}
bool mitk::StringProperty::Assign(const BaseProperty& property )
{
this->m_Value = static_cast<const Self&>(property).m_Value;
return true;
}
std::string mitk::StringProperty::GetValueAsString() const
{
return m_Value;
}
diff --git a/Core/Code/DataManagement/mitkStringProperty.h b/Core/Code/DataManagement/mitkStringProperty.h
index 55f4f14cd7..bec632b8a7 100644
--- a/Core/Code/DataManagement/mitkStringProperty.h
+++ b/Core/Code/DataManagement/mitkStringProperty.h
@@ -1,81 +1,80 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSTRINGPROPERTY_H_HEADER_INCLUDED_C1C02491
#define MITKSTRINGPROPERTY_H_HEADER_INCLUDED_C1C02491
#include <itkConfigure.h>
#include <MitkExports.h>
#include "mitkBaseProperty.h"
#include <string>
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* @brief Property for strings
* @ingroup DataManagement
*/
class MITK_CORE_EXPORT StringProperty : public BaseProperty
{
protected:
std::string m_Value;
StringProperty( const char* string = 0 );
StringProperty( const std::string& s );
public:
mitkClassMacro(StringProperty, BaseProperty);
typedef std::string ValueType;
itkNewMacro(StringProperty);
mitkNewMacro1Param(StringProperty, const char*);
mitkNewMacro1Param(StringProperty, const std::string&)
itkGetStringMacro(Value);
itkSetStringMacro(Value);
virtual std::string GetValueAsString() const;
static const char* PATH;
using BaseProperty::operator=;
private:
// purposely not implemented
StringProperty(const StringProperty&);
StringProperty& operator=(const StringProperty&);
virtual bool IsEqual(const BaseProperty& property ) const;
virtual bool Assign(const BaseProperty& property );
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkSurface.cpp b/Core/Code/DataManagement/mitkSurface.cpp
index cfc0a86e12..a94bed68ad 100644
--- a/Core/Code/DataManagement/mitkSurface.cpp
+++ b/Core/Code/DataManagement/mitkSurface.cpp
@@ -1,383 +1,382 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurface.h"
#include "mitkInteractionConst.h"
#include "mitkSurfaceOperation.h"
#include <vtkPolyData.h>
#include "vtkSmartPointer.h"
mitk::Surface::Surface() :
m_CalculateBoundingBox( false )
{
this->InitializeEmpty();
}
mitk::Surface::Surface(const mitk::Surface& other) : BaseData(other),
m_LargestPossibleRegion(other.m_LargestPossibleRegion),
m_RequestedRegion(other.m_RequestedRegion),
m_CalculateBoundingBox(other.m_CalculateBoundingBox)
{
if(other.m_PolyDataSeries.at(0) != NULL)
{
this->m_PolyDataSeries = std::vector<vtkPolyData*>();
for ( VTKPolyDataSeries::const_iterator it = other.m_PolyDataSeries.begin(); it != other.m_PolyDataSeries.end(); ++it )
{
vtkPolyData* poly = vtkPolyData::New();
poly->DeepCopy(*it);
m_PolyDataSeries.push_back(poly);
//poly->Delete();
}
}
else
{
this->InitializeEmpty();
}
}
mitk::Surface::~Surface()
{
this->ClearData();
}
void mitk::Surface::ClearData()
{
for ( VTKPolyDataSeries::iterator it = m_PolyDataSeries.begin(); it != m_PolyDataSeries.end(); ++it )
{
if ( ( *it ) != NULL )
( *it )->Delete();
}
m_PolyDataSeries.clear();
Superclass::ClearData();
}
void mitk::Surface::InitializeEmpty()
{
vtkPolyData* pdnull = NULL;
m_PolyDataSeries.resize( 1, pdnull );
Superclass::InitializeTimeSlicedGeometry(1);
m_Initialized = true;
}
void mitk::Surface::SetVtkPolyData( vtkPolyData* polydata, unsigned int t )
{
// Adapt the size of the data vector if necessary
this->Expand( t+1 );
if(m_PolyDataSeries[ t ] != NULL)
{
if ( m_PolyDataSeries[ t ] == polydata )
return;
// we do not need the reference on the object any longer
m_PolyDataSeries[ t ]->Delete();
}
m_PolyDataSeries[ t ] = polydata;
// call m_VtkPolyData->Register(NULL) to tell
// the reference counting that we want to keep a
// reference on the object
if(m_PolyDataSeries[ t ] != NULL)
{
m_PolyDataSeries[ t ]->Register( NULL );
}
this->Modified();
m_CalculateBoundingBox = true;
this->UpdateOutputInformation();
}
bool mitk::Surface::IsEmptyTimeStep(unsigned int t) const
{
if(!IsInitialized())
return false;
vtkPolyData* polydata = const_cast<Surface*>(this)->GetVtkPolyData(t);
return
(polydata == NULL) ||
(
(polydata->GetNumberOfVerts() <= 0) &&
(polydata->GetNumberOfPolys() <= 0) &&
(polydata->GetNumberOfStrips() <= 0) &&
(polydata->GetNumberOfLines() <= 0)
);
}
vtkPolyData* mitk::Surface::GetVtkPolyData( unsigned int t )
{
if ( t < m_PolyDataSeries.size() )
{
vtkPolyData* polydata = m_PolyDataSeries[ t ];
if((polydata==NULL) && (GetSource().GetPointer()!=NULL))
{
RegionType requestedregion;
requestedregion.SetIndex(3, t);
requestedregion.SetSize(3, 1);
SetRequestedRegion(&requestedregion);
GetSource()->Update();
}
polydata = m_PolyDataSeries[ t ];
return polydata;
}
else
return NULL;
}
void mitk::Surface::UpdateOutputInformation()
{
if ( this->GetSource() )
{
this->GetSource()->UpdateOutputInformation();
}
if ( ( m_CalculateBoundingBox ) && ( m_PolyDataSeries.size() > 0 ) )
CalculateBoundingBox();
else
GetTimeSlicedGeometry()->UpdateInformation();
}
void mitk::Surface::CalculateBoundingBox()
{
//
// first make sure, that the associated time sliced geometry has
// the same number of geometry 3d's as vtkPolyDatas are present
//
mitk::TimeSlicedGeometry* timeGeometry = GetTimeSlicedGeometry();
if ( timeGeometry->GetTimeSteps() != m_PolyDataSeries.size() )
{
itkExceptionMacro(<<"timeGeometry->GetTimeSteps() != m_PolyDataSeries.size() -- use Initialize(timeSteps) with correct number of timeSteps!");
}
//
// Iterate over the vtkPolyDatas and update the Geometry
// information of each of the items.
//
for ( unsigned int i = 0 ; i < m_PolyDataSeries.size() ; ++i )
{
vtkPolyData* polyData = m_PolyDataSeries[ i ];
vtkFloatingPointType bounds[ ] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
if ( ( polyData != NULL ) && ( polyData->GetNumberOfPoints() > 0 ) )
{
polyData->Update();
polyData->ComputeBounds();
polyData->GetBounds( bounds );
}
mitk::Geometry3D::Pointer g3d = timeGeometry->GetGeometry3D( i );
assert( g3d.IsNotNull() );
g3d->SetFloatBounds( bounds );
}
timeGeometry->UpdateInformation();
mitk::BoundingBox::Pointer bb = const_cast<mitk::BoundingBox*>( timeGeometry->GetBoundingBox() );
itkDebugMacro( << "boundingbox min: "<< bb->GetMinimum());
itkDebugMacro( << "boundingbox max: "<< bb->GetMaximum());
m_CalculateBoundingBox = false;
}
void mitk::Surface::SetRequestedRegionToLargestPossibleRegion()
{
m_RequestedRegion = GetLargestPossibleRegion();
}
bool mitk::Surface::RequestedRegionIsOutsideOfTheBufferedRegion()
{
RegionType::IndexValueType end = m_RequestedRegion.GetIndex(3)+m_RequestedRegion.GetSize(3);
if(((RegionType::IndexValueType)m_PolyDataSeries.size())<end)
return true;
for( RegionType::IndexValueType t=m_RequestedRegion.GetIndex(3); t<end; ++t )
if(m_PolyDataSeries[t]==NULL)
return true;
return false;
}
bool mitk::Surface::VerifyRequestedRegion()
{
if( (m_RequestedRegion.GetIndex(3)>=0) &&
(m_RequestedRegion.GetIndex(3)+m_RequestedRegion.GetSize(3)<=m_PolyDataSeries.size()) )
return true;
return false;
}
void mitk::Surface::SetRequestedRegion( itk::DataObject *data )
{
mitk::Surface *surfaceData;
surfaceData = dynamic_cast<mitk::Surface*>(data);
if (surfaceData)
{
m_RequestedRegion = surfaceData->GetRequestedRegion();
}
else
{
// pointer could not be cast back down
itkExceptionMacro( << "mitk::Surface::SetRequestedRegion(DataObject*) cannot cast " << typeid(data).name() << " to " << typeid(Surface*).name() );
}
}
void mitk::Surface::SetRequestedRegion(Surface::RegionType *region) //by arin
{
if(region!=NULL)
{
m_RequestedRegion = *region;
}
else
{
// pointer could not be cast back down
itkExceptionMacro( << "mitk::Surface::SetRequestedRegion(Surface::RegionType*) cannot cast " << typeid(region).name() << " to " << typeid(Surface*).name() );
}
}
void mitk::Surface::CopyInformation( const itk::DataObject * data)
{
Superclass::CopyInformation( data );
const mitk::Surface* surfaceData;
surfaceData = dynamic_cast<const mitk::Surface*>( data );
if ( surfaceData )
{
m_LargestPossibleRegion = surfaceData->GetLargestPossibleRegion();
}
else
{
// pointer could not be cast back down
itkExceptionMacro( << "mitk::Surface::CopyInformation(const DataObject *data) cannot cast " << typeid(data).name() << " to " << typeid(surfaceData).name() );
}
}
void mitk::Surface::Update()
{
if ( GetSource().IsNull() )
{
for ( VTKPolyDataSeries::iterator it = m_PolyDataSeries.begin() ; it != m_PolyDataSeries.end() ; ++it )
{
if ( ( *it ) != NULL )
( *it )->Update();
}
}
Superclass::Update();
}
void mitk::Surface::Expand( unsigned int timeSteps )
{
// check if the vector is long enough to contain the new element
// at the given position. If not, expand it with sufficient zero-filled elements.
if ( timeSteps > m_PolyDataSeries.size() )
{
Superclass::Expand( timeSteps );
vtkPolyData* pdnull = NULL;
m_PolyDataSeries.resize( timeSteps, pdnull );
m_CalculateBoundingBox = true;
}
}
void mitk::Surface::ExecuteOperation(Operation *operation)
{
switch ( operation->GetOperationType() )
{
case OpSURFACECHANGED:
mitk::SurfaceOperation* surfOp = dynamic_cast<mitk::SurfaceOperation*>(operation);
if( ! surfOp ) break;
unsigned int time = surfOp->GetTimeStep();
if(m_PolyDataSeries[ time ] != NULL)
{
vtkPolyData* updatePoly = surfOp->GetVtkPolyData();
if( updatePoly ){
this->SetVtkPolyData( updatePoly, time );
this->CalculateBoundingBox();
}
}
break;
}
this->Modified();
}
unsigned int mitk::Surface::GetSizeOfPolyDataSeries() const
{
return m_PolyDataSeries.size();
}
void mitk::Surface::Graft( const DataObject* data )
{
const Self* surface;
try
{
surface = dynamic_cast<const Self*>( data );
}
catch(...)
{
itkExceptionMacro( << "mitk::Surface::Graft cannot cast "
<< typeid(data).name() << " to "
<< typeid(const Self *).name() );
return;
}
if(!surface)
{
// pointer could not be cast back down
itkExceptionMacro( << "mitk::Surface::Graft cannot cast "
<< typeid(data).name() << " to "
<< typeid(const Self *).name() );
return;
}
this->CopyInformation( data );
//clear list of PolyData's
m_PolyDataSeries.clear();
// do copy
for (unsigned int i=0; i<surface->GetSizeOfPolyDataSeries(); i++)
{
m_PolyDataSeries.push_back(vtkPolyData::New());
m_PolyDataSeries.back()->DeepCopy( const_cast<mitk::Surface*>(surface)->GetVtkPolyData( i ) );
//CopyStructure( const_cast<mitk::Surface*>(surface)->GetVtkPolyData( i ) );
}
}
void mitk::Surface::PrintSelf( std::ostream& os, itk::Indent indent ) const
{
Superclass::PrintSelf(os, indent);
os << indent << "\nNumber PolyDatas: " << m_PolyDataSeries.size() << "\n";
unsigned int count = 0;
for (VTKPolyDataSeries::const_iterator it = m_PolyDataSeries.begin(); it != m_PolyDataSeries.end(); ++it)
{
vtkPolyData* pd = *it;
if(pd != NULL)
{
os << "\n";
os << indent << "PolyData at time step " << count << ". \n";
os << indent << "Number of cells " << pd->GetNumberOfCells() << ": \n";
os << indent << "Number of points " << pd->GetNumberOfPoints() << ": \n\n";
os << indent << "VTKPolyData : \n";
pd->Print(os);
}
else
os << indent << "\nEmpty PolyData at time step " << count << ".\n";
count++;
}
}
diff --git a/Core/Code/DataManagement/mitkSurface.h b/Core/Code/DataManagement/mitkSurface.h
index 7eeae09582..2e33f10588 100644
--- a/Core/Code/DataManagement/mitkSurface.h
+++ b/Core/Code/DataManagement/mitkSurface.h
@@ -1,116 +1,115 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSURFACEDATA_H_HEADER_INCLUDED
#define MITKSURFACEDATA_H_HEADER_INCLUDED
#include "mitkBaseData.h"
#include "itkImageRegion.h"
class vtkPolyData;
namespace mitk {
//##Documentation
//## @brief Class for storing surfaces (vtkPolyData)
//## @ingroup Data
class MITK_CORE_EXPORT Surface : public BaseData
{
protected:
public:
// not yet the best chioce of a region-type for surfaces, but it works for the time being
typedef itk::ImageRegion< 5 > RegionType;
mitkClassMacro(Surface, BaseData);
itkNewMacro(Self);
mitkCloneMacro(Surface);
virtual void SetVtkPolyData(vtkPolyData* polydata, unsigned int t = 0);
virtual vtkPolyData* GetVtkPolyData(unsigned int t = 0);
virtual void UpdateOutputInformation();
virtual void SetRequestedRegionToLargestPossibleRegion();
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
virtual bool VerifyRequestedRegion();
virtual void SetRequestedRegion(itk::DataObject *data);
virtual void SetRequestedRegion(Surface::RegionType *region);
virtual void CopyInformation(const itk::DataObject *data);
virtual bool IsEmptyTimeStep(unsigned int t) const;
unsigned int GetSizeOfPolyDataSeries() const;
virtual void Update();
virtual void Expand( unsigned int timeSteps = 1 );
virtual void Graft( const DataObject* data );
const RegionType& GetLargestPossibleRegion() const
{
m_LargestPossibleRegion.SetIndex(3, 0);
m_LargestPossibleRegion.SetSize(3, GetTimeSlicedGeometry()->GetTimeSteps());
return m_LargestPossibleRegion;
}
//##Documentation
//## Get the region object that defines the size and starting index
//## for the region of the image requested (i.e., the region of the
//## image to be operated on by a filter).
virtual const RegionType& GetRequestedRegion() const
{
return m_RequestedRegion;
}
void CalculateBoundingBox();
virtual void PrintSelf( std::ostream& os, itk::Indent indent ) const;
virtual void ExecuteOperation(Operation *operation);
protected:
typedef std::vector< vtkPolyData* > VTKPolyDataSeries;
Surface();
Surface(const Surface& other);
virtual ~Surface();
virtual void ClearData();
virtual void InitializeEmpty();
//member variables
VTKPolyDataSeries m_PolyDataSeries; /// variable holds the poly datas of the surface
mutable RegionType m_LargestPossibleRegion; /// variable holds the largest possible region the surface is contained in
RegionType m_RequestedRegion;
bool m_CalculateBoundingBox; /// flag to calculate the bounding box
};
} // namespace mitk
#endif /* MITKSURFACEDATA_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkSurfaceOperation.cpp b/Core/Code/DataManagement/mitkSurfaceOperation.cpp
index 7659ad9e4b..7e622dc81e 100644
--- a/Core/Code/DataManagement/mitkSurfaceOperation.cpp
+++ b/Core/Code/DataManagement/mitkSurfaceOperation.cpp
@@ -1,38 +1,37 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurfaceOperation.h"
mitk::SurfaceOperation::SurfaceOperation(mitk::OperationType operationType, vtkPolyData* polyData, unsigned int t)
: mitk::Operation(operationType), m_polyData(polyData), m_timeStep(t)
{
}
mitk::SurfaceOperation::~SurfaceOperation()
{
}
vtkPolyData* mitk::SurfaceOperation::GetVtkPolyData()
{
return m_polyData;
}
unsigned int mitk::SurfaceOperation::GetTimeStep()
{
return m_timeStep;
}
diff --git a/Core/Code/DataManagement/mitkSurfaceOperation.h b/Core/Code/DataManagement/mitkSurfaceOperation.h
index d2f2e7afb0..66e572c298 100644
--- a/Core/Code/DataManagement/mitkSurfaceOperation.h
+++ b/Core/Code/DataManagement/mitkSurfaceOperation.h
@@ -1,54 +1,53 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#pragma once
#include <MitkExports.h>
#include "mitkOperation.h"
#include <vtkPolyData.h>
namespace mitk {
/*
* @brief Operation that stores polydata for changing surfaces
*/
class MITK_CORE_EXPORT SurfaceOperation : public Operation
{
public:
/*
* Constructor
* @param operationType type of the operation (OpSURFACECHANGED)
* @param polyData the polydata object to replace in the surface
* @param t the time step
*/
SurfaceOperation(mitk::OperationType operationType, vtkPolyData* polyData, unsigned int t);
virtual ~SurfaceOperation();
vtkPolyData* GetVtkPolyData();
unsigned int GetTimeStep();
private:
vtkPolyData* m_polyData;
unsigned int m_timeStep;
};
}; // end namespace mitk
diff --git a/Core/Code/DataManagement/mitkThinPlateSplineCurvedGeometry.cpp b/Core/Code/DataManagement/mitkThinPlateSplineCurvedGeometry.cpp
index d7f9d60d49..06c6472cc9 100644
--- a/Core/Code/DataManagement/mitkThinPlateSplineCurvedGeometry.cpp
+++ b/Core/Code/DataManagement/mitkThinPlateSplineCurvedGeometry.cpp
@@ -1,103 +1,102 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkThinPlateSplineCurvedGeometry.h"
#include <vtkThinPlateSplineTransform.h>
#include <vtkPoints.h>
mitk::ThinPlateSplineCurvedGeometry::ThinPlateSplineCurvedGeometry()
{
m_InterpolatingAbstractTransform = m_ThinPlateSplineTransform = vtkThinPlateSplineTransform::New();
m_VtkTargetLandmarks = vtkPoints::New();
m_VtkProjectedLandmarks = vtkPoints::New();
m_ThinPlateSplineTransform->SetInverseIterations(5000);
}
mitk::ThinPlateSplineCurvedGeometry::ThinPlateSplineCurvedGeometry(const ThinPlateSplineCurvedGeometry& other ) : Superclass(other)
{
this->SetSigma(other.GetSigma());
}
mitk::ThinPlateSplineCurvedGeometry::~ThinPlateSplineCurvedGeometry()
{
// don't need to delete m_ThinPlateSplineTransform, because it is
// the same as m_InterpolatingAbstractTransform, which will be deleted
// by the superclass.
if(m_VtkTargetLandmarks!=NULL)
m_VtkTargetLandmarks->Delete();
if(m_VtkProjectedLandmarks!=NULL)
m_VtkProjectedLandmarks->Delete();
}
bool mitk::ThinPlateSplineCurvedGeometry::IsValid() const
{
return m_TargetLandmarks.IsNotNull() && (m_TargetLandmarks->Size() >= 3) && m_LandmarkProjector.IsNotNull();
}
void mitk::ThinPlateSplineCurvedGeometry::SetSigma(float sigma)
{
m_ThinPlateSplineTransform->SetSigma(sigma);
}
float mitk::ThinPlateSplineCurvedGeometry::GetSigma() const
{
return m_ThinPlateSplineTransform->GetSigma();
}
void mitk::ThinPlateSplineCurvedGeometry::ComputeGeometry()
{
Superclass::ComputeGeometry();
const mitk::PointSet::DataType::PointsContainer *finalTargetLandmarks, *projectedTargetLandmarks;
finalTargetLandmarks = m_LandmarkProjector->GetFinalTargetLandmarks();
projectedTargetLandmarks = m_LandmarkProjector->GetProjectedLandmarks();
mitk::PointSet::DataType::PointsContainer::ConstIterator targetIt, projectedIt;
targetIt = finalTargetLandmarks->Begin();
projectedIt = projectedTargetLandmarks->Begin();
//initialize Thin-Plate-Spline
m_VtkTargetLandmarks->Reset();
m_VtkProjectedLandmarks->Reset();
vtkIdType id;
int size=finalTargetLandmarks->Size();
for(id=0; id < size; ++id, ++targetIt, ++projectedIt)
{
const mitk::PointSet::PointType& target = targetIt->Value();
m_VtkTargetLandmarks->InsertPoint(id, target[0], target[1], target[2]);
const mitk::PointSet::PointType& projected = projectedIt->Value();
m_VtkProjectedLandmarks->InsertPoint(id, projected[0], projected[1], projected[2]);
}
m_VtkTargetLandmarks->Modified();
m_VtkProjectedLandmarks->Modified();
m_ThinPlateSplineTransform->SetSourceLandmarks(m_VtkProjectedLandmarks);
m_ThinPlateSplineTransform->SetTargetLandmarks(m_VtkTargetLandmarks);
}
mitk::AffineGeometryFrame3D::Pointer mitk::ThinPlateSplineCurvedGeometry::Clone() const
{
mitk::AffineGeometryFrame3D::Pointer newGeometry = new Self(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
diff --git a/Core/Code/DataManagement/mitkThinPlateSplineCurvedGeometry.h b/Core/Code/DataManagement/mitkThinPlateSplineCurvedGeometry.h
index ecf988245b..2fb32d3261 100644
--- a/Core/Code/DataManagement/mitkThinPlateSplineCurvedGeometry.h
+++ b/Core/Code/DataManagement/mitkThinPlateSplineCurvedGeometry.h
@@ -1,69 +1,68 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKTHINPLATESPLINECURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#define MITKTHINPLATESPLINECURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C
#include "mitkLandmarkProjectorBasedCurvedGeometry.h"
class vtkPoints;
class vtkThinPlateSplineTransform;
namespace mitk {
//##Documentation
//## @brief Thin-plate-spline-based landmark-based curved geometry
//##
//## @ingroup Geometry
class MITK_CORE_EXPORT ThinPlateSplineCurvedGeometry : public LandmarkProjectorBasedCurvedGeometry
{
public:
mitkClassMacro(ThinPlateSplineCurvedGeometry, LandmarkProjectorBasedCurvedGeometry);
itkNewMacro(Self);
virtual void ComputeGeometry();
virtual AffineGeometryFrame3D::Pointer Clone() const;
vtkThinPlateSplineTransform* GetThinPlateSplineTransform() const
{
return m_ThinPlateSplineTransform;
}
virtual void SetSigma(float sigma);
virtual float GetSigma() const;
virtual bool IsValid() const;
protected:
ThinPlateSplineCurvedGeometry();
ThinPlateSplineCurvedGeometry(const ThinPlateSplineCurvedGeometry& other );
virtual ~ThinPlateSplineCurvedGeometry();
vtkThinPlateSplineTransform* m_ThinPlateSplineTransform;
vtkPoints* m_VtkTargetLandmarks;
vtkPoints* m_VtkProjectedLandmarks;
};
} // namespace mitk
#endif /* MITKTHINPLATESPLINECURVEDGEOMETRY_H_HEADER_INCLUDED_C1C68A2C */
diff --git a/Core/Code/DataManagement/mitkTimeSlicedGeometry.cpp b/Core/Code/DataManagement/mitkTimeSlicedGeometry.cpp
index a80a942880..6e547d6e8a 100644
--- a/Core/Code/DataManagement/mitkTimeSlicedGeometry.cpp
+++ b/Core/Code/DataManagement/mitkTimeSlicedGeometry.cpp
@@ -1,417 +1,416 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTimeSlicedGeometry.h"
void mitk::TimeSlicedGeometry::UpdateInformation()
{
if(m_TimeSteps==0) return;
unsigned long maxModifiedTime = 0, curModifiedTime;
mitk::ScalarType stmin, stmax;
stmin= ScalarTypeNumericTraits::NonpositiveMin();
stmax= ScalarTypeNumericTraits::max();
TimeBounds timeBounds;
timeBounds[0]=stmax; timeBounds[1]=stmin;
mitk::BoundingBox::Pointer boundingBox=mitk::BoundingBox::New();
mitk::BoundingBox::PointsContainer::Pointer pointscontainer=mitk::BoundingBox::PointsContainer::New();
unsigned int t;
mitk::Geometry3D* geometry3d;
mitk::BoundingBox::ConstPointer nextBoundingBox;
mitk::BoundingBox::PointIdentifier pointid=0;
// Need to check for zero bounding boxes
mitk::ScalarType zeropoint[]={0,0,0,0,0,0};
BoundingBox::BoundsArrayType itkBoundsZero(zeropoint);
for(t=0; t < m_TimeSteps; ++t)
{
geometry3d = GetGeometry3D(t);
assert(geometry3d!=NULL);
curModifiedTime = geometry3d->GetMTime();
if(maxModifiedTime < curModifiedTime)
maxModifiedTime = curModifiedTime;
const TimeBounds & curTimeBounds = geometry3d->GetTimeBounds();
if((curTimeBounds[0] > stmin) && (curTimeBounds[0] < timeBounds[0]))
timeBounds[0] = curTimeBounds[0];
if((curTimeBounds[1] < stmax) && (curTimeBounds[1] > timeBounds[1]))
timeBounds[1] = curTimeBounds[1];
nextBoundingBox = geometry3d->GetBoundingBox();
assert(nextBoundingBox.IsNotNull());
// Only respect non-zero BBes
if (nextBoundingBox->GetBounds() == itkBoundsZero)
{
continue;
}
const mitk::BoundingBox::PointsContainer * nextPoints = nextBoundingBox->GetPoints();
if(nextPoints!=NULL)
{
mitk::BoundingBox::PointsContainer::ConstIterator pointsIt = nextPoints->Begin();
while (pointsIt != nextPoints->End() )
{
pointscontainer->InsertElement( pointid++, pointsIt->Value());
++pointsIt;
}
}
}
if(!(timeBounds[0] < stmax))
{
timeBounds[0] = stmin;
timeBounds[1] = stmax;
}
m_TimeBounds = timeBounds;
assert(timeBounds[0]<=timeBounds[1]);
boundingBox->SetPoints(pointscontainer);
boundingBox->ComputeBoundingBox();
m_BoundingBox = boundingBox;
SetIndexToWorldTransform(GetGeometry3D(0)->GetIndexToWorldTransform());
if(this->GetMTime() < maxModifiedTime)
Modified();
}
mitk::Geometry3D* mitk::TimeSlicedGeometry::GetGeometry3D(int t) const
{
mitk::Geometry3D::Pointer geometry3d = NULL;
if(IsValidTime(t))
{
geometry3d = m_Geometry3Ds[t];
//if (a) we don't have a Geometry3D stored for the requested time,
//(b) m_EvenlyTimed is activated and (c) the first geometry (t=0)
//is set, then we clone the geometry and set the m_TimeBounds accordingly.
if((m_EvenlyTimed) && (geometry3d.IsNull()))
{
const Geometry3D* firstgeometry=m_Geometry3Ds[0].GetPointer();
assert(firstgeometry != NULL);
mitk::Geometry3D::Pointer requestedgeometry;
requestedgeometry = dynamic_cast<Geometry3D*>(firstgeometry->Clone().GetPointer());
if ( requestedgeometry.IsNull() ) itkExceptionMacro("Geometry is NULL!");
TimeBounds timebounds = requestedgeometry->GetTimeBounds();
if(timebounds[1]<ScalarTypeNumericTraits::max())
{
mitk::ScalarType later = (timebounds[1]-timebounds[0])*t;
timebounds[0]+=later; timebounds[1]+=later;
requestedgeometry->SetTimeBounds(timebounds);
}
geometry3d = requestedgeometry;
m_Geometry3Ds[t] = geometry3d;
}
}
else
return NULL;
return geometry3d;
}
bool mitk::TimeSlicedGeometry::SetGeometry3D(mitk::Geometry3D* geometry3D, int t)
{
if(IsValidTime(t))
{
m_Geometry3Ds[t]=geometry3D;
return true;
}
return false;
}
int mitk::TimeSlicedGeometry::MSToTimeStep(mitk::ScalarType time_in_ms) const
{
if(time_in_ms < m_TimeBounds[0])
return -1;
if(time_in_ms >= m_TimeBounds[1])
return m_TimeSteps;
if(m_EvenlyTimed)
{
if(m_TimeBounds[0] == m_TimeBounds[1])
return 0;
if((m_TimeBounds[0]>ScalarTypeNumericTraits::NonpositiveMin()) && (m_TimeBounds[1]<ScalarTypeNumericTraits::max()))
{
return (int) ceil(((time_in_ms - m_TimeBounds[0])/(m_TimeBounds[1]-m_TimeBounds[0])*m_TimeSteps)-0.5);
}
return 0;
}
else
{
unsigned int t;
for ( t = 0; t < m_TimeSteps; ++t )
{
const TimeBounds& timeBounds = GetGeometry3D( t )->GetTimeBounds();
if( (timeBounds[0] <= time_in_ms) && (time_in_ms <= timeBounds[1]) )
{
return t;
}
}
}
return 0;
}
mitk::ScalarType mitk::TimeSlicedGeometry::TimeStepToMS(int timestep) const
{
if(IsValidTime(timestep)==false)
return ScalarTypeNumericTraits::max();
if(m_EvenlyTimed)
{
if ( timestep == 0 )
return m_TimeBounds[0];
else
{
assert( ! (m_TimeBounds[0] == ScalarTypeNumericTraits::NonpositiveMin() && m_TimeBounds[1] == ScalarTypeNumericTraits::max() ) );
return ((mitk::ScalarType)timestep)/m_TimeSteps*(m_TimeBounds[1]-m_TimeBounds[0])+m_TimeBounds[0];
}
}
else
{
return GetGeometry3D(timestep)->GetTimeBounds()[0];
}
}
int mitk::TimeSlicedGeometry::TimeStepToTimeStep(
const mitk::TimeSlicedGeometry *referenceGeometry, int t) const
{
int timeStep;
if ( referenceGeometry->GetTimeSteps() > 1 )
{
// referenceGeometry is nD+t
timeStep = this->MSToTimeStep( referenceGeometry->TimeStepToMS( t ) );
}
else
{
// referenceGEometry is nD (only one time step)
timeStep = 0;
}
return timeStep;
}
void mitk::TimeSlicedGeometry::InitializeEvenlyTimed(unsigned int timeSteps)
{
Geometry3D::Pointer geometry3D = Geometry3D::New();
geometry3D->Initialize();
InitializeEvenlyTimed(geometry3D, timeSteps);
}
void mitk::TimeSlicedGeometry::InitializeEvenlyTimed(mitk::Geometry3D* geometry3D, unsigned int timeSteps)
{
assert(geometry3D!=NULL);
geometry3D->Register();
InitializeEmpty(timeSteps);
AffineTransform3D::Pointer transform = AffineTransform3D::New();
transform->SetMatrix(geometry3D->GetIndexToWorldTransform()->GetMatrix());
transform->SetOffset(geometry3D->GetIndexToWorldTransform()->GetOffset());
SetIndexToWorldTransform(transform);
SetBounds(geometry3D->GetBounds());
SetGeometry3D(geometry3D, 0);
SetEvenlyTimed();
UpdateInformation();
SetFrameOfReferenceID(geometry3D->GetFrameOfReferenceID());
SetImageGeometry(geometry3D->GetImageGeometry());
geometry3D->UnRegister();
}
void mitk::TimeSlicedGeometry::InitializeEmpty(unsigned int timeSteps)
{
m_IndexToWorldTransform = NULL;
Superclass::Initialize();
m_TimeSteps = timeSteps;
// initialize with empty geometries
Geometry3D::Pointer gnull=NULL;
m_Geometry3Ds.assign(m_TimeSteps, gnull);
}
void mitk::TimeSlicedGeometry::ExpandToNumberOfTimeSteps( unsigned int timeSteps )
{
if( timeSteps <= m_TimeSteps ) return;
if(m_TimeSteps == 1)
{
Geometry3D* g3d = m_Geometry3Ds[0];
const TimeBounds & timeBounds = g3d->GetTimeBounds();
if( (timeBounds[0] == ScalarTypeNumericTraits::NonpositiveMin()) ||
(timeBounds[1]==ScalarTypeNumericTraits::max())
)
{
mitk::ScalarType timeBounds[] = {0.0, 1.0};
m_Geometry3Ds[0]->SetTimeBounds( timeBounds );
}
}
// Expand to Number of time steps; initialize with empty geometries
Geometry3D::Pointer gnull=NULL;
m_Geometry3Ds.resize(timeSteps, gnull);
m_TimeSteps = timeSteps;
UpdateInformation();
}
mitk::TimeSlicedGeometry::TimeSlicedGeometry() : m_TimeSteps(0), m_EvenlyTimed(false)
{
}
mitk::TimeSlicedGeometry::TimeSlicedGeometry(const TimeSlicedGeometry& other) : Geometry3D(other), m_TimeSteps(other.m_TimeSteps), m_EvenlyTimed(other.m_EvenlyTimed)
{
m_Geometry3Ds.resize(m_TimeSteps);
unsigned int t;
for(t=0; t<m_TimeSteps; ++t)
{
if(other.m_Geometry3Ds[t].IsNull())
{
assert(other.m_EvenlyTimed);
SetGeometry3D(NULL,t);
}
else
{
SetGeometry3D(dynamic_cast<Geometry3D*>(other.m_Geometry3Ds[t]->Clone().GetPointer()), t);
}
}
}
mitk::TimeSlicedGeometry::~TimeSlicedGeometry()
{
}
void mitk::TimeSlicedGeometry::SetImageGeometry(const bool isAnImageGeometry)
{
Superclass::SetImageGeometry(isAnImageGeometry);
mitk::Geometry3D* geometry3d;
unsigned int t;
for(t=0; t<m_TimeSteps; ++t)
{
geometry3d = m_Geometry3Ds[t];
if(geometry3d!=NULL)
geometry3d->SetImageGeometry(isAnImageGeometry);
}
}
void mitk::TimeSlicedGeometry::ChangeImageGeometryConsideringOriginOffset(const bool isAnImageGeometry)
{
mitk::Geometry3D* geometry3d;
unsigned int t;
for(t=0; t<m_TimeSteps; ++t)
{
geometry3d = m_Geometry3Ds[t];
if(geometry3d!=NULL)
geometry3d->ChangeImageGeometryConsideringOriginOffset(isAnImageGeometry);
}
Superclass::ChangeImageGeometryConsideringOriginOffset(isAnImageGeometry);
}
void mitk::TimeSlicedGeometry::SetEvenlyTimed(bool on)
{
m_EvenlyTimed = on;
Modified();
}
bool mitk::TimeSlicedGeometry::IsValidTime(int t) const
{
return (t>=0) && (t< (int)m_TimeSteps);
}
void mitk::TimeSlicedGeometry::CopyTimes(const mitk::TimeSlicedGeometry* timeslicedgeometry, unsigned int t, unsigned int endtimeindex)
{
if(endtimeindex >= timeslicedgeometry->GetTimeSteps())
endtimeindex = timeslicedgeometry->GetTimeSteps()-1;
if(endtimeindex >= this->GetTimeSteps())
endtimeindex = this->GetTimeSteps()-1;
for(; t <= endtimeindex; ++t)
{
mitk::Geometry3D* geometry3d = GetGeometry3D(t);
mitk::Geometry3D* othergeometry3d = timeslicedgeometry->GetGeometry3D(t);
assert((geometry3d!=NULL) && (othergeometry3d!=NULL));
geometry3d->SetTimeBounds(othergeometry3d->GetTimeBounds());
}
UpdateInformation();
}
mitk::AffineGeometryFrame3D::Pointer mitk::TimeSlicedGeometry::Clone() const
{
Self::Pointer newGeometry = new TimeSlicedGeometry(*this);
newGeometry->UnRegister();
return newGeometry.GetPointer();
}
void mitk::TimeSlicedGeometry::PrintSelf(std::ostream& os, itk::Indent indent) const
{
//Superclass::PrintSelf(os,indent);
os << indent << " EvenlyTimed: " << m_EvenlyTimed << std::endl;
os << indent << " TimeSteps: " << m_TimeSteps << std::endl;
os << std::endl;
os << indent << " GetGeometry3D(0): ";
if(GetGeometry3D(0)==NULL)
os << "NULL" << std::endl;
else
GetGeometry3D(0)->Print(os, indent);
}
void mitk::TimeSlicedGeometry::ExecuteOperation(Operation* operation)
{
// reach through to all time steps
for (std::vector<Geometry3D::Pointer>::iterator iter = m_Geometry3Ds.begin();
iter != m_Geometry3Ds.end();
++iter)
{
(*iter)->ExecuteOperation(operation);
}
Geometry3D::ExecuteOperation(operation);
this->Modified();
}
diff --git a/Core/Code/DataManagement/mitkTimeSlicedGeometry.h b/Core/Code/DataManagement/mitkTimeSlicedGeometry.h
index 27726dad24..62452482c7 100644
--- a/Core/Code/DataManagement/mitkTimeSlicedGeometry.h
+++ b/Core/Code/DataManagement/mitkTimeSlicedGeometry.h
@@ -1,178 +1,177 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 TIMESLICEDGEOMETRY_H_HEADER_INCLUDED_C1EBD0AD
#define TIMESLICEDGEOMETRY_H_HEADER_INCLUDED_C1EBD0AD
#include "mitkGeometry3D.h"
namespace mitk {
//##Documentation
//## @brief Describes a geometry consisting of several geometries which
//## exist at different times.
//##
//## The geometry contains m_TimeSteps geometries, which can be accessed
//## using GetGeometry3D(int t). To convert between world-time in
//## milliseconds and the integer timestep-number use MSToTimeStep.
//## The hull (in space and time) of the TimeSlicedGeometry contains all
//## contained geometries.
//## @warning The hull (i.e., transform, bounding-box and
//## time-bounds) is only guaranteed to be up-to-date after calling
//## UpdateInformation().
//##
//## TimeSlicedGeometry and the associated Geometry3Ds have to be
//## initialized in the method GenerateOutputInformation() of BaseProcess (or
//## CopyInformation/ UpdateOutputInformation of BaseData, if possible, e.g.,
//## by analyzing pic tags in Image) subclasses. See also
//## itk::ProcessObject::GenerateOutputInformation(),
//## itk::DataObject::CopyInformation() and
//## itk::DataObject::UpdateOutputInformation().
//##
//## @ingroup Geometry
class MITK_CORE_EXPORT TimeSlicedGeometry : public Geometry3D
{
public:
mitkClassMacro(TimeSlicedGeometry, Geometry3D);
itkNewMacro(Self);
//##Documentation
//## @brief Re-calculate the hull of the contained geometries.
//##
//## The transforms, bounding-box and time-bounds of this
//## geometry (stored in members of the super-class Geometry3D)
//## are re-calculated from the contained geometries.
void UpdateInformation();
//##Documentation
//## @brief Get the number of time-steps
itkGetConstMacro(TimeSteps, unsigned int);
//##Documentation
//## @brief Set/Get whether the TimeSlicedGeometry is evenly-timed (m_EvenlyTimed)
//##
//## If (a) we don't have a Geometry3D stored for the requested time,
//## (b) m_EvenlyTimed is activated and (c) the first geometry (t=0)
//## is set, then we clone the geometry and set the m_TimeBounds accordingly.
//## \sa GetGeometry3D
itkGetConstMacro(EvenlyTimed, bool);
virtual void SetEvenlyTimed(bool on = true);
//##Documentation
//## @brief Set the Geometry3D for time @a t
virtual bool SetGeometry3D(mitk::Geometry3D* geometry3D, int t);
//##Documentation
//## @brief When switching from an Image Geometry to a normal Geometry (and the other way around), you have to change the origin as well (See Geometry Documentation)! This function will change the "isImageGeometry" bool flag and changes the origin respectively.
virtual void ChangeImageGeometryConsideringOriginOffset( const bool isAnImageGeometry );
//##Documentation
//## @brief Get the Geometry3D at time @a t
virtual mitk::Geometry3D* GetGeometry3D(int t) const;
//##Documentation
//## @brief Test whether @a t is a valid time step
virtual bool IsValidTime(int t) const;
//##Documentation
//## @brief Convert time in ms to a time step
virtual int MSToTimeStep(mitk::ScalarType time_in_ms) const;
//##Documentation
//## @brief Convert time step to time in ms
virtual mitk::ScalarType TimeStepToMS(int timestep) const;
//##Documentation
//## @brief Convert time step in the reference TimeSlicedGeometry to time step
//## in this TimeSlicedGeometry.
virtual int TimeStepToTimeStep(const mitk::TimeSlicedGeometry *referenceGeometry, int t) const;
//##Documentation
//## @brief Completely initialize this instance as evenly-timed with
//## \a timeSteps geometries of type Geometry3D, each initialized by
//## Geometry3D::Initialize().
virtual void InitializeEvenlyTimed(unsigned int timeSteps);
//##Documentation
//## @brief Completely initialize this instance as evenly-timed with
//## \a timeSteps geometries identical to the provided Geometry3D
//## except for the time bounds
virtual void InitializeEvenlyTimed(mitk::Geometry3D* geometry3D, unsigned int timeSteps);
//##Documentation
//## @brief Initialize this instance to contain \a timeSteps
//## geometries, but without setting them yet
virtual void InitializeEmpty(unsigned int timeSteps);
//##Documentation
//## @brief Expand the number of time steps contained
//## to \a timeSteps.
//##
//## New, additional time steps will be initialized empty.
//## Only enlargement of the time steps vector is intended and possible.
virtual void ExpandToNumberOfTimeSteps( unsigned int timeSteps );
virtual void SetImageGeometry(const bool isAnImageGeometry);
//##Documentation
//## @brief Copy the m_TimeBounds of the geometries contained
//## in timeslicedgeometry into the geometries contained in this
//## TimeSlicedGeometry object.
//##
//## Useful for initialization of the TimeSlicedGeometry of the
//## output in GenerateOutputInformation() methods of process objects,
//## see for example BoundingObjectCutter::GenerateOutputInformation().
//## @param t start time index
//## @param endtimeindex (endtimeindex) is the time index of
//## the last geometry whose time-bounds are copied. If
//## timeslicedgeometry or this TimeSlicedGeometry object does
//## not contain enough geometries, endtimeindex is reduced
//## appropriately.
void CopyTimes(const mitk::TimeSlicedGeometry* timeslicedgeometry, unsigned int t=0, unsigned int endtimeindex = itk::NumericTraits<unsigned int>::max());
//##Documentation
//## @brief duplicates the geometry
virtual AffineGeometryFrame3D::Pointer Clone() const;
TimeSlicedGeometry::Pointer CloneCopy() const;
virtual void ExecuteOperation(Operation* operation);
protected:
TimeSlicedGeometry();
TimeSlicedGeometry(const TimeSlicedGeometry& other);
virtual ~TimeSlicedGeometry();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
mutable std::vector<Geometry3D::Pointer> m_Geometry3Ds;
//##Documentation
//## @brief Number of time steps
unsigned int m_TimeSteps;
//##Documentation
//## @brief \a true in case the time steps have equal length
bool m_EvenlyTimed;
static const std::string EVENLY_TIMED;
static const std::string TIME_STEPS;
};
} // namespace mitk
#endif /* TIMESLICEDGEOMETRY_H_HEADER_INCLUDED_C1EBD0AD */
diff --git a/Core/Code/DataManagement/mitkTransferFunction.cpp b/Core/Code/DataManagement/mitkTransferFunction.cpp
index 0f46aec249..d5f9aa6cd2 100644
--- a/Core/Code/DataManagement/mitkTransferFunction.cpp
+++ b/Core/Code/DataManagement/mitkTransferFunction.cpp
@@ -1,310 +1,309 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTransferFunction.h"
#include "mitkImageToItk.h"
#include "mitkHistogramGenerator.h"
#include <itkRGBPixel.h>
#include <vector>
namespace mitk
{
TransferFunction::TransferFunction()
{
m_ScalarOpacityFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
m_ColorTransferFunction = vtkSmartPointer<vtkColorTransferFunction>::New();
m_GradientOpacityFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
m_ScalarOpacityFunction->Initialize();
m_ScalarOpacityFunction->AddPoint(0,1);
m_GradientOpacityFunction->Initialize();
m_GradientOpacityFunction->AddPoint(0,1);
m_ColorTransferFunction->RemoveAllPoints();
m_ColorTransferFunction->SetColorSpaceToHSV();
m_ColorTransferFunction->AddRGBPoint(0,1,1,1);
}
TransferFunction::~TransferFunction()
{
}
bool TransferFunction::operator==(Self& other)
{
if ((m_Min != other.m_Min) || (m_Max != other.m_Max))
return false;
bool sizes = (m_ScalarOpacityFunction->GetSize() == other.m_ScalarOpacityFunction->GetSize())
&& (m_GradientOpacityFunction->GetSize() == other.m_GradientOpacityFunction->GetSize())
&& (m_ColorTransferFunction->GetSize() == other.m_ColorTransferFunction->GetSize());
if (sizes == false)
return false;
for (int i = 0; i < m_ScalarOpacityFunction->GetSize(); i++ )
{
double myVal[4];
double otherVal[4];
m_ScalarOpacityFunction->GetNodeValue(i, myVal);
other.m_ScalarOpacityFunction->GetNodeValue(i, otherVal);
bool equal = (myVal[0] == otherVal[0])
&& (myVal[1] == otherVal[1])
&& (myVal[2] == otherVal[2])
&& (myVal[3] == otherVal[3]);
if (equal == false)
return false;
}
for (int i = 0; i < m_GradientOpacityFunction->GetSize(); i++ )
{
double myVal[4];
double otherVal[4];
m_GradientOpacityFunction->GetNodeValue(i, myVal);
other.m_GradientOpacityFunction->GetNodeValue(i, otherVal);
bool equal = (myVal[0] == otherVal[0])
&& (myVal[1] == otherVal[1])
&& (myVal[2] == otherVal[2])
&& (myVal[3] == otherVal[3]);
if (equal == false)
return false;
}
for (int i = 0; i < m_ColorTransferFunction->GetSize(); i++ )
{
double myVal[6];
double otherVal[6];
m_ColorTransferFunction->GetNodeValue(i, myVal);
other.m_ColorTransferFunction->GetNodeValue(i, otherVal);
bool equal = (myVal[0] == otherVal[0]) // X
&& (myVal[1] == otherVal[1]) // R
&& (myVal[2] == otherVal[2]) // G
&& (myVal[3] == otherVal[3]) // B
&& (myVal[4] == otherVal[4]) // midpoint
&& (myVal[5] == otherVal[5]); // sharpness
if (equal == false)
return false;
}
return true;
}
void TransferFunction::SetScalarOpacityPoints(TransferFunction::ControlPoints points)
{
m_ScalarOpacityFunction->RemoveAllPoints();
for(unsigned int i=0; i<=points.size()-1;i++)
{
this->AddScalarOpacityPoint(points[i].first, points[i].second);
}
}
void TransferFunction::SetGradientOpacityPoints(TransferFunction::ControlPoints points)
{
m_GradientOpacityFunction->RemoveAllPoints();
for(unsigned int i=0; i<=points.size()-1;i++)
{
this->AddGradientOpacityPoint(points[i].first, points[i].second);
}
}
void TransferFunction::SetRGBPoints(TransferFunction::RGBControlPoints rgbpoints)
{
m_ColorTransferFunction->RemoveAllPoints();
for(unsigned int i=0; i<=rgbpoints.size()-1;i++)
{
this->AddRGBPoint(rgbpoints[i].first, rgbpoints[i].second[0],
rgbpoints[i].second[1], rgbpoints[i].second[2]);
}
}
void TransferFunction::AddScalarOpacityPoint(double x, double value)
{
m_ScalarOpacityFunction->AddPoint(x, value);
}
void TransferFunction::AddGradientOpacityPoint(double x, double value)
{
m_GradientOpacityFunction->AddPoint(x, value);
}
void TransferFunction::AddRGBPoint(double x, double r, double g, double b)
{
m_ColorTransferFunction->AddRGBPoint(x, r, g, b);
}
TransferFunction::ControlPoints &TransferFunction::GetScalarOpacityPoints()
{
// Retrieve data points from VTK transfer function and store them in a vector
m_ScalarOpacityPoints.clear();
vtkFloatingPointType *data = m_ScalarOpacityFunction->GetDataPointer();
for ( int i = 0; i < m_ScalarOpacityFunction->GetSize(); ++i )
{
m_ScalarOpacityPoints.push_back( std::make_pair( data[i*2], data[i*2+1] ));
}
return m_ScalarOpacityPoints;
}
TransferFunction::ControlPoints &TransferFunction::GetGradientOpacityPoints()
{
// Retrieve data points from VTK transfer function and store them in a vector
m_GradientOpacityPoints.clear();
vtkFloatingPointType *data = m_GradientOpacityFunction->GetDataPointer();
for ( int i = 0; i < m_GradientOpacityFunction->GetSize(); ++i )
{
m_GradientOpacityPoints.push_back( std::make_pair( data[i*2], data[i*2+1] ));
}
return m_GradientOpacityPoints;
}
TransferFunction::RGBControlPoints &TransferFunction::GetRGBPoints()
{
// Retrieve data points from VTK transfer function and store them in a vector
m_RGBPoints.clear();
vtkFloatingPointType *data = m_ColorTransferFunction->GetDataPointer();
for ( int i = 0; i < m_ColorTransferFunction->GetSize(); ++i )
{
double rgb[] = { data[i*4+1], data[i*4+2], data[i*4+3] };
m_RGBPoints.push_back( std::make_pair( data[i*4], rgb ));
}
return m_RGBPoints;
}
int TransferFunction::RemoveScalarOpacityPoint(double x)
{
return m_ScalarOpacityFunction->RemovePoint(x);
}
int TransferFunction::RemoveGradientOpacityPoint(double x)
{
return m_GradientOpacityFunction->RemovePoint(x);
}
int TransferFunction::RemoveRGBPoint(double x)
{
return m_ColorTransferFunction->RemovePoint(x);
}
void TransferFunction::ClearScalarOpacityPoints()
{
m_ScalarOpacityFunction->RemoveAllPoints();
}
void TransferFunction::ClearGradientOpacityPoints()
{
m_GradientOpacityFunction->RemoveAllPoints();
}
void TransferFunction::ClearRGBPoints()
{
m_ColorTransferFunction->RemoveAllPoints();
}
void TransferFunction::InitializeByItkHistogram(
const itk::Statistics::Histogram<double>* histogram)
{
m_Histogram = histogram;
m_Min = (int)GetHistogram()->GetBinMin(0,0);
m_Max = (int)GetHistogram()->GetBinMax(0, GetHistogram()->Size()-1);
/*
m_ScalarOpacityFunction->Initialize();
m_ScalarOpacityFunction->AddPoint(m_Min,0.0);
m_ScalarOpacityFunction->AddPoint(0.0,0.0);
m_ScalarOpacityFunction->AddPoint(m_Max,1.0);
m_GradientOpacityFunction->Initialize();
m_GradientOpacityFunction->AddPoint(m_Min,0.0);
m_GradientOpacityFunction->AddPoint(0.0,1.0);
m_GradientOpacityFunction->AddPoint((m_Max*0.125),1.0);
m_GradientOpacityFunction->AddPoint((m_Max*0.2),1.0);
m_GradientOpacityFunction->AddPoint((m_Max*0.25),1.0);
m_GradientOpacityFunction->AddPoint(m_Max,1.0);
m_ColorTransferFunction->RemoveAllPoints();
m_ColorTransferFunction->AddRGBPoint(m_Min,1,0,0);
m_ColorTransferFunction->AddRGBPoint(m_Max,1,1,0);
m_ColorTransferFunction->SetColorSpaceToHSV();
MITK_INFO << "min/max in tf-c'tor:" << m_Min << "/" << m_Max << std::endl;
*/
}
void TransferFunction::InitializeByMitkImage( const Image * image )
{
HistogramGenerator::Pointer histGen= HistogramGenerator::New();
histGen->SetImage(image);
histGen->SetSize(256);
histGen->ComputeHistogram();
m_Histogram = histGen->GetHistogram();
m_Min = (int)GetHistogram()->GetBinMin(0,0);
m_Max = (int)GetHistogram()->GetBinMax(0, GetHistogram()->Size()-1);
m_ScalarOpacityFunction->Initialize();
m_ScalarOpacityFunction->AddPoint(m_Min,0.0);
m_ScalarOpacityFunction->AddPoint(0.0,0.0);
m_ScalarOpacityFunction->AddPoint(m_Max,1.0);
m_GradientOpacityFunction->Initialize();
m_GradientOpacityFunction->AddPoint(m_Min,0.0);
m_GradientOpacityFunction->AddPoint(0.0,1.0);
m_GradientOpacityFunction->AddPoint((m_Max*0.125),1.0);
m_GradientOpacityFunction->AddPoint((m_Max*0.2),1.0);
m_GradientOpacityFunction->AddPoint((m_Max*0.25),1.0);
m_GradientOpacityFunction->AddPoint(m_Max,1.0);
m_ColorTransferFunction->RemoveAllPoints();
m_ColorTransferFunction->AddRGBPoint(m_Min,1,0,0);
m_ColorTransferFunction->AddRGBPoint(m_Max,1,1,0);
m_ColorTransferFunction->SetColorSpaceToHSV();
//MITK_INFO << "min/max in tf-c'tor:" << m_Min << "/" << m_Max << std::endl;
}
void TransferFunction::InitializeHistogram( const Image * image )
{
HistogramGenerator::Pointer histGen= HistogramGenerator::New();
histGen->SetImage(image);
histGen->SetSize(256);
histGen->ComputeHistogram();
m_Histogram = histGen->GetHistogram();
m_Min = (int)GetHistogram()->GetBinMin(0,0);
m_Max = (int)GetHistogram()->GetBinMax(0, GetHistogram()->Size()-1);
}
void TransferFunction::PrintSelf(std::ostream &os, itk::Indent indent) const
{
os << indent << "ScalarOpacity: ";
m_ScalarOpacityFunction->PrintHeader(os, vtkIndent());
os << indent << "GradientOpacity: ";
m_GradientOpacityFunction->PrintHeader(os, vtkIndent());
os << indent << "ColorTransfer: ";
m_ColorTransferFunction->PrintHeader(os, vtkIndent());
os << indent << "Min: " << m_Min << ", Max: " << m_Max << std::endl;
}
}// namespace
diff --git a/Core/Code/DataManagement/mitkTransferFunction.h b/Core/Code/DataManagement/mitkTransferFunction.h
index 3f19cbd2b6..3060bfa0d7 100644
--- a/Core/Code/DataManagement/mitkTransferFunction.h
+++ b/Core/Code/DataManagement/mitkTransferFunction.h
@@ -1,196 +1,195 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITK_TRANSFER_FUNCTION_H_HEADER_INCLUDED
#define MITK_TRANSFER_FUNCTION_H_HEADER_INCLUDED
#include "mitkHistogramGenerator.h"
#include <MitkExports.h>
#include "mitkImage.h"
#include <itkObject.h>
#include <itkRGBPixel.h>
#include <itkHistogram.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkSmartPointer.h>
#include <vector>
#include <algorithm>
#include <set>
namespace mitk {
/**
* \brief Wrapper class for VTK scalar opacity, gradient opacity, and color
* transfer functions.
*
* Holds a copy of each of the three standard VTK transfer functions (scalar
* opacity, gradient opacity, color) and provides an interface for manipulating
* their control points. Each original function can be retrieved by a Get()
* method.
*
* NOTE: Currently, transfer function initialization based on histograms or
* computed-tomography-presets is also provided by this class, but will likely
* be separated into a specific initializer class.
*/
class MITK_CORE_EXPORT TransferFunction : public itk::Object
{
public:
typedef std::vector<std::pair<double, double> > ControlPoints;
typedef std::vector<std::pair<double, itk::RGBPixel<double> > > RGBControlPoints;
mitkClassMacro(TransferFunction, itk::DataObject);
itkNewMacro(Self);
/** \brief Get/Set min/max of transfer function range for initialization. */
itkSetMacro(Min,int);
/** \brief Get/Set min/max of transfer function range for initialization. */
itkSetMacro(Max,int);
/** \brief Get/Set min/max of transfer function range for initialization. */
itkGetMacro(Min,int);
/** \brief Get/Set min/max of transfer function range for initialization. */
itkGetMacro(Max,int);
/** \brief Get/Set wrapped vtk transfer function. */
itkGetMacro(ScalarOpacityFunction,vtkPiecewiseFunction*);
/** \brief Get/Set wrapped vtk transfer function. */
itkGetMacro(GradientOpacityFunction,vtkPiecewiseFunction*);
/** \brief Get/Set wrapped vtk transfer function. */
itkGetMacro(ColorTransferFunction,vtkColorTransferFunction*);
itkSetMacro(ColorTransferFunction,vtkSmartPointer<vtkColorTransferFunction>);
/** \brief Get histogram used for transfer function initialization. */
itkGetConstObjectMacro(Histogram,HistogramGenerator::HistogramType);
/** \brief Initialize transfer function based on the histogram of an mitk::Image. */
void InitializeByMitkImage(const mitk::Image* image);
/** \brief Initialize transfer function based on the specified histogram. */
void InitializeByItkHistogram(const itk::Statistics::Histogram<double>* histogram);
/** \brief Initialize the internal histogram and min/max range based on the
* specified mitk::Image. */
void InitializeHistogram( const mitk::Image* image );
/** \brief Insert control points and values into the scalar opacity transfer
* function. */
void SetScalarOpacityPoints(TransferFunction::ControlPoints points);
/** \brief Insert control points and values into the gradient opacity transfer
* function. */
void SetGradientOpacityPoints(TransferFunction::ControlPoints points);
/** \brief Insert control points and RGB values into the color transfer
* function. */
void SetRGBPoints(TransferFunction::RGBControlPoints rgbpoints);
/** \brief Add a single control point to the scalar opacity transfer function. */
void AddScalarOpacityPoint(double x, double value);
/** \brief Add a single control point to the gradient opacity transfer function. */
void AddGradientOpacityPoint(double x, double value);
/** \brief Add a single control point to the color opacity transfer function. */
void AddRGBPoint(double x, double r, double g, double b);
/** \brief Get a copy of the scalar opacity transfer function control-points. */
TransferFunction::ControlPoints &GetScalarOpacityPoints();
/** \brief Get a copy of the gradient opacity transfer function control-points. */
TransferFunction::ControlPoints &GetGradientOpacityPoints();
/** \brief Get a copy of the color transfer function control-points. */
TransferFunction::RGBControlPoints &GetRGBPoints();
/** \brief Remove the specified control point from the scalar opacity transfer
* function. */
int RemoveScalarOpacityPoint(double x);
/** \brief Remove the specified control point from the gradient opacity transfer
* function. */
int RemoveGradientOpacityPoint(double x);
/** \brief Remove the specified control point from the color transfer function. */
int RemoveRGBPoint(double x);
/** \brief Removes all control points from the scalar opacity transfer function. */
void ClearScalarOpacityPoints();
/** \brief Removes all control points from the gradient opacity transfer
* function. */
void ClearGradientOpacityPoints();
/** \brief Removes all control points from the color transfer function. */
void ClearRGBPoints();
bool operator==(Self& other);
protected:
TransferFunction();
virtual ~TransferFunction();
void PrintSelf(std::ostream &os, itk::Indent indent) const;
/** Wrapped VTK scalar opacity transfer function */
vtkSmartPointer<vtkPiecewiseFunction> m_ScalarOpacityFunction;
/** Wrapped VTK gradient opacity transfer function */
vtkSmartPointer<vtkPiecewiseFunction> m_GradientOpacityFunction;
/** Wrapped VTK color transfer function */
vtkSmartPointer<vtkColorTransferFunction> m_ColorTransferFunction;
/** Current range of transfer function (used for initialization) */
int m_Min;
/** Current range of transfer function (used for initialization) */
int m_Max;
/** Specified or calculated histogram (used for initialization) */
mitk::HistogramGenerator::HistogramType::ConstPointer m_Histogram;
private:
/** Temporary STL style copy of VTK internal control points */
TransferFunction::ControlPoints m_ScalarOpacityPoints;
/** Temporary STL style copy of VTK internal control points */
TransferFunction::ControlPoints m_GradientOpacityPoints;
/** Temporary STL style copy of VTK internal control points */
TransferFunction::RGBControlPoints m_RGBPoints;
};
}
#endif /* MITK_TRANSFER_FUNCTION_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkTransferFunctionInitializer.cpp b/Core/Code/DataManagement/mitkTransferFunctionInitializer.cpp
index c43f2d9d3f..b69404a16e 100644
--- a/Core/Code/DataManagement/mitkTransferFunctionInitializer.cpp
+++ b/Core/Code/DataManagement/mitkTransferFunctionInitializer.cpp
@@ -1,300 +1,299 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-05-10 18:06:04 +0200 (Mo, 10 Mai 2010) $
-Version: $Revision: 22790 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTransferFunctionInitializer.h"
static const char* presetNames[] = { "choose an internal transferfunction preset",
"CT Generic",
"CT Black & White",
"CT Thorax large",
"CT Thorax small",
"CT Bone",
"CT Bone (with Gradient)",
"CT Cardiac",
"MR Generic" };
static int numPresetNames = sizeof( presetNames ) / sizeof( char * );
namespace mitk
{
TransferFunctionInitializer::TransferFunctionInitializer(mitk::TransferFunction::Pointer transferFunction)
{
if (transferFunction.IsNotNull())
{
m_transferFunction = transferFunction;
}
}
TransferFunctionInitializer::~TransferFunctionInitializer()
{
}
void TransferFunctionInitializer::GetPresetNames(std::vector<std::string>& names)
{
for (int i = 0; i < numPresetNames; ++i)
{
names.push_back(presetNames[i]);
}
}
void TransferFunctionInitializer::SetTransferFunction(mitk::TransferFunction::Pointer transferFunction)
{
m_transferFunction = transferFunction;
}
void TransferFunctionInitializer::SetTransferFunctionMode( int mode )
{
if(m_transferFunction)
{
m_Mode = mode;
this->InitTransferFunctionMode();
}
}
void TransferFunctionInitializer::RemoveAllPoints()
{
m_transferFunction->GetScalarOpacityFunction()->RemoveAllPoints();
m_transferFunction->GetColorTransferFunction()->RemoveAllPoints();
m_transferFunction->GetGradientOpacityFunction()->RemoveAllPoints();
}
void TransferFunctionInitializer::SetModified()
{
m_transferFunction->GetScalarOpacityFunction()->Modified();
m_transferFunction->GetColorTransferFunction()->Modified();
m_transferFunction->GetGradientOpacityFunction()->Modified();
}
void TransferFunctionInitializer::InitTransferFunctionMode()
{
if(m_transferFunction)
{
this->RemoveAllPoints();
switch( this->m_Mode )
{
case TF_CT_DEFAULT:
this->SetCtDefaultMode();
break;
case TF_CT_BLACK_WHITE:
this->SetCtBlackWhiteMode();
break;
case TF_CT_THORAX_LARGE:
this->SetCtThoraxLargeMode();
break;
case TF_CT_THORAX_SMALL:
this->SetCtThoraxSmallMode();
break;
case TF_CT_BONE:
this->SetCtBoneMode();
break;
case TF_CT_BONE_GRADIENT:
this->SetCtBoneGradientMode();
break;
case TF_CT_CARDIAC:
this->SetCtCardiacMode();
break;
case TF_MR_GENERIC:
this->SetMrGenericMode();
break;
default:
itkExceptionMacro(<< "No Mode set!");
break;
}
this->SetModified();
} else {
itkExceptionMacro(<< "No Transferfunction set!");
}
}
void TransferFunctionInitializer::SetCtDefaultMode()
{
// grayvalue->opacity
m_transferFunction->GetScalarOpacityFunction()->AddPoint(132.108911,0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(197.063492,0.041333);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(1087.917989,0.700000);
// gradient at grayvalue->opacity
m_transferFunction->GetGradientOpacityFunction()->AddPoint(560.695000,1.000000);
// grayvalue->color
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(176.881890,0.650980,0.000000,0.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(239.427822,0.933333,0.000000,0.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(301.973753,1.000000,0.800000,0.062745);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(495.866142,1.000000,0.905882,0.666667);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(677.249344,1.000000,0.882353,0.215686);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(808.595801,1.000000,1.000000,1.000000);
}
void TransferFunctionInitializer::SetCtBlackWhiteMode()
{
//Set Opacity
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 135.063521, 0.0 );
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 948.137931, 1.0 );
//Set Color
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 122.088929, 0.352941, 0.352941, 0.352941);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 372.931034, 1.000000, 1.000000, 1.000000 );
//Set Gradient
m_transferFunction->GetGradientOpacityFunction()->Initialize();
m_transferFunction->GetGradientOpacityFunction()->AddPoint( 560.695000, 1);
}
void TransferFunctionInitializer::SetCtThoraxLargeMode()
{
// grayvalue->opacity
m_transferFunction->GetScalarOpacityFunction()->AddPoint(76.721239,0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(139.524336,0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(274.458333,0.228650);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(638.420139,0.721763);
// gradient at grayvalue->opacity
m_transferFunction->GetGradientOpacityFunction()->AddPoint(560.695000,1.000000);
// grayvalue->color
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 85.382743,0.478431,0.000000,0.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 198.201327,0.933333,0.000000,0.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 254.610619,1.000000,0.800000,0.062745);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 336.0907085,1.000000,0.905882,0.666667);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 630.672566,1.000000,1.000000,1.000000);
}
void TransferFunctionInitializer::SetCtThoraxSmallMode()
{
// grayvalue->opacity
m_transferFunction->GetScalarOpacityFunction()->AddPoint(147.216912,0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(274.458333,0.228650);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(430.330882,0.675532);
// gradient at grayvalue->opacity
m_transferFunction->GetGradientOpacityFunction()->AddPoint(560.695000,1.000000);
// grayvalue->color
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 129.607774,0.478431,0.000000,0.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 213.812721,0.933333,0.000000,0.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 348.540636,1.000000,0.800000,0.062745);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 500.419118,1.000000,0.898039,0.776471);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 579.268382,1.000000,1.000000,1.000000);
}
void TransferFunctionInitializer::SetCtBoneMode()
{
// grayvalue->opacity
m_transferFunction->GetScalarOpacityFunction()->AddPoint(126.413793,0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(178.312160,0.014663);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(247.509982,0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(1013.010889,1.000000);
// gradient at grayvalue->opacity
m_transferFunction->GetGradientOpacityFunction()->AddPoint(485.377495,1.000000);
// grayvalue->color
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 312.382940,1.000000,0.564706,0.274510);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 455.103448,1.000000,0.945098,0.768627);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 623.773140,1.000000,0.800000,0.333333);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 796.767695,1.000000,0.901961,0.815686);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 930.838475,1.000000,1.000000,1.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(1073.558984,1.000000,0.839216,0.423529);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(1220.604356,1.000000,0.772549,0.490196);
}
void TransferFunctionInitializer::SetCtBoneGradientMode()
{
// grayvalue->opacity
m_transferFunction->GetScalarOpacityFunction()->AddPoint(126.413793,0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(186.961887,0.146628);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(247.509982,0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint(1013.010889,1.000000);
// gradient at grayvalue->opacity
m_transferFunction->GetGradientOpacityFunction()->AddPoint(22.617060,0.000000);
m_transferFunction->GetGradientOpacityFunction()->AddPoint(65.865699,1.000000);
// grayvalue->color
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 312.382940,1.000000,0.564706,0.274510);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 455.103448,1.000000,0.945098,0.768627);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 623.773140,1.000000,0.800000,0.333333);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 796.767695,1.000000,0.901961,0.815686);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 930.838475,1.000000,1.000000,1.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(1073.558984,1.000000,0.839216,0.423529);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint(1220.604356,1.000000,0.772549,0.490196);
}
void TransferFunctionInitializer::SetCtCardiacMode()
{
//Set Opacity
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 150.246824, 0.000000 );
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 179.974592, 0.202346);
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 276.589837, 0.000000);
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 781.961887, 1.000000);
//Set Color
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 395.500907,1.000000,0.000000,0.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 410.364791,1.000000,0.749020,0.000000);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 484.684211,1.000000,0.878431,0.662745);
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 588.731397,1.000000,0.784314,0.482353);
//Set Gradient
m_transferFunction->GetGradientOpacityFunction()->AddPoint( 246.862069, 0.215827 );
}
void TransferFunctionInitializer::SetMrGenericMode()
{
//Set Opacity
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 0, 0 );
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 20, 0 );
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 40, 0.15 );
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 120, 0.3 );
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 220, 0.375 );
m_transferFunction->GetScalarOpacityFunction()->AddPoint( 1024, 0.5);
//Set Color
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 0, 0, 0, 0 );
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 20, 0.168627, 0, 0 );
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 40, 0.403922, 0.145098, 0.0784314 );
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 120, 0.780392, 0.607843, 0.380392 );
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 220, 0.847059, 0.835294, 0.788235 );
m_transferFunction->GetColorTransferFunction()->AddRGBPoint( 1024, 1, 1, 1 );
//Set Gradient
m_transferFunction->GetGradientOpacityFunction()->AddPoint( 0, 1 );
m_transferFunction->GetGradientOpacityFunction()->AddPoint( 255, 1);
}
mitk::TransferFunction::Pointer TransferFunctionInitializer::GetTransferFunction()
{
return m_transferFunction;
}
} // namespace
diff --git a/Core/Code/DataManagement/mitkTransferFunctionInitializer.h b/Core/Code/DataManagement/mitkTransferFunctionInitializer.h
index d644e09a4b..834b3432a2 100644
--- a/Core/Code/DataManagement/mitkTransferFunctionInitializer.h
+++ b/Core/Code/DataManagement/mitkTransferFunctionInitializer.h
@@ -1,99 +1,98 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-05-10 18:06:04 +0200 (Mo, 10 Mai 2010) $
-Version: $Revision: 22790 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITK_TRANSFER_FUNCTION_MODE_CREATOR_H_HEADER_INCLUDED
#define MITK_TRANSFER_FUNCTION_MODE_CREATOR_H_HEADER_INCLUDED
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkSmartPointer.h>
#include "mitkTransferFunction.h"
#include <itkObject.h>
#include <itkObjectFactory.h>
#include <MitkExports.h>
namespace mitk {
/**
* \brief Wrapper class for VTK scalar opacity, gradient opacity, and color
* transfer functions.
*
* Holds a copy of each of the three standard VTK transfer functions (scalar
* opacity, gradient opacity, color) and provides an interface for manipulating
* their control points. Each original function can be retrieved by a Get()
* method.
*
* NOTE: Currently, transfer function initialization based on histograms or
* computed-tomography-presets is also provided by this class, but will likely
* be separated into a specific initializer class.
*/
class MITK_CORE_EXPORT TransferFunctionInitializer : public itk::Object
{
public:
mitkClassMacro(TransferFunctionInitializer, itk::Object);
itkNewMacro( TransferFunctionInitializer );
mitkNewMacro1Param(TransferFunctionInitializer, TransferFunction::Pointer);
static void GetPresetNames(std::vector<std::string>& presetNames);
void SetTransferFunction(TransferFunction::Pointer transferFunction);
mitk::TransferFunction::Pointer GetTransferFunction();
void SetTransferFunctionMode(int mode);
void InitTransferFunctionMode();
protected:
TransferFunctionInitializer(TransferFunction::Pointer transferFunction = NULL);
virtual ~TransferFunctionInitializer();
private:
int m_Mode;
mitk::TransferFunction::Pointer m_transferFunction;
//Define Transfer Function
enum TransferFunctionMode{
TF_CT_DEFAULT,
TF_CT_BLACK_WHITE,
TF_CT_THORAX_LARGE,
TF_CT_THORAX_SMALL,
TF_CT_BONE,
TF_CT_BONE_GRADIENT,
TF_CT_CARDIAC,
TF_MR_GENERIC
};
//remove all old points
void RemoveAllPoints();
void SetModified();
void SetCtDefaultMode();
void SetCtBlackWhiteMode();
void SetCtThoraxLargeMode();
void SetCtThoraxSmallMode();
void SetCtBoneMode();
void SetCtBoneGradientMode();
void SetCtCardiacMode();
void SetMrGenericMode();
};
}
#endif /* MITK_TRANSFER_FUNCTION_MODE_CREATOR_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkTransferFunctionProperty.cpp b/Core/Code/DataManagement/mitkTransferFunctionProperty.cpp
index f2cbca7289..789c626576 100644
--- a/Core/Code/DataManagement/mitkTransferFunctionProperty.cpp
+++ b/Core/Code/DataManagement/mitkTransferFunctionProperty.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTransferFunctionProperty.h"
namespace mitk {
bool TransferFunctionProperty::IsEqual(const BaseProperty& property) const
{
return *(this->m_Value) == *(static_cast<const Self&>(property).m_Value);
}
bool TransferFunctionProperty::Assign(const BaseProperty& property)
{
this->m_Value = static_cast<const Self&>(property).m_Value;
return true;
}
std::string TransferFunctionProperty::GetValueAsString() const
{
std::stringstream myStr;
myStr << GetValue();
return myStr.str();
}
TransferFunctionProperty::TransferFunctionProperty()
: BaseProperty()
{}
TransferFunctionProperty::TransferFunctionProperty( mitk::TransferFunction::Pointer value )
: BaseProperty(), m_Value( value )
{}
} // namespace mitk
diff --git a/Core/Code/DataManagement/mitkTransferFunctionProperty.h b/Core/Code/DataManagement/mitkTransferFunctionProperty.h
index 8b4d05c7e9..261dd0c167 100644
--- a/Core/Code/DataManagement/mitkTransferFunctionProperty.h
+++ b/Core/Code/DataManagement/mitkTransferFunctionProperty.h
@@ -1,74 +1,73 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKTRANFERFUNCTIONPROPERTY_H_HEADER_INCLUDED
#define MITKTRANFERFUNCTIONPROPERTY_H_HEADER_INCLUDED
#include "mitkBaseProperty.h"
#include "mitkTransferFunction.h"
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
class MITK_CORE_EXPORT TransferFunctionProperty : public BaseProperty
{
public:
typedef mitk::TransferFunction::Pointer ValueType;
mitkClassMacro(TransferFunctionProperty, BaseProperty);
itkNewMacro(TransferFunctionProperty);
mitkNewMacro1Param(TransferFunctionProperty, mitk::TransferFunction::Pointer);
itkSetMacro(Value, mitk::TransferFunction::Pointer );
itkGetConstMacro(Value, mitk::TransferFunction::Pointer );
std::string GetValueAsString() const;
using BaseProperty::operator=;
protected:
mitk::TransferFunction::Pointer m_Value;
TransferFunctionProperty();
TransferFunctionProperty( mitk::TransferFunction::Pointer value );
private:
// purposely not implemented
TransferFunctionProperty(const TransferFunctionProperty&);
TransferFunctionProperty& operator=(const TransferFunctionProperty&);
virtual bool IsEqual(const BaseProperty& property) const;
virtual bool Assign(const BaseProperty& property);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif /* MITKTRANFERFUNCTIONPROPERTY_H_HEADER_INCLUDED */
diff --git a/Core/Code/DataManagement/mitkVector.cpp b/Core/Code/DataManagement/mitkVector.cpp
index 5bea5b3fb8..80dd142454 100644
--- a/Core/Code/DataManagement/mitkVector.cpp
+++ b/Core/Code/DataManagement/mitkVector.cpp
@@ -1,24 +1,23 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVector.h"
#include <vtkSystemIncludes.h>
#include <vtkMatrix4x4.h>
const mitk::ScalarType mitk::eps = vnl_math::float_eps*100;
const mitk::ScalarType mitk::sqrteps = vnl_math::float_sqrteps;
extern const double mitk::large = VTK_LARGE_FLOAT;
diff --git a/Core/Code/DataManagement/mitkVector.h b/Core/Code/DataManagement/mitkVector.h
index c4e3fde5de..db7f43d72e 100644
--- a/Core/Code/DataManagement/mitkVector.h
+++ b/Core/Code/DataManagement/mitkVector.h
@@ -1,440 +1,439 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKVECTOR_H_HEADER_INCLUDED_C1EBD0AD
#define MITKVECTOR_H_HEADER_INCLUDED_C1EBD0AD
// this is needed for memcopy in ITK
// can be removed when fixed in ITK
#include <cstring>
#include <itkPoint.h>
#include <float.h>
#include <itkIndex.h>
#include <itkContinuousIndex.h>
#include <itkVector.h>
#include <itkMatrix.h>
#include <itkTransform.h>
#include <vnl/vnl_quaternion.h>
#include <MitkExports.h>
#ifndef DOXYGEN_SKIP
namespace mitk {
typedef float ScalarType;
typedef itk::Matrix<ScalarType, 3, 3> Matrix3D;
typedef itk::Matrix<ScalarType,4,4> Matrix4D;
typedef vnl_matrix_fixed<ScalarType, 3, 3> VnlMatrix3D;
typedef itk::Transform<ScalarType, 3, 3> Transform3D;
typedef vnl_vector<ScalarType> VnlVector;
typedef vnl_vector_ref<ScalarType> VnlVectorRef;
typedef itk::Point<ScalarType,2> Point2D;
typedef itk::Point<ScalarType,3> Point3D;
typedef itk::Point<ScalarType,4> Point4D;
typedef itk::Point<int,2> Point2I;
typedef itk::Point<int,3> Point3I;
typedef itk::Point<int,4> Point4I;
typedef itk::Vector<ScalarType,2> Vector2D;
typedef itk::Vector<ScalarType,3> Vector3D;
typedef itk::Index<3> Index3D;
typedef itk::ContinuousIndex<ScalarType, 3> ContinuousIndex3D;
typedef vnl_quaternion<ScalarType> Quaternion;
//##Documentation
//##@brief enumeration of the type a point can be
enum PointSpecificationType
{
PTUNDEFINED = 0,
PTSTART,
PTCORNER,
PTEDGE,
PTEND
};
typedef itk::NumericTraits<mitk::ScalarType> ScalarTypeNumericTraits;
MITK_CORE_EXPORT extern const ScalarType eps;
MITK_CORE_EXPORT extern const ScalarType sqrteps;
MITK_CORE_EXPORT extern const double large;
template <class T> class VectorTraits {
public:
typedef T ValueType;
};
template <> class VectorTraits<VnlVector> {
public:
typedef ScalarType ValueType;
};
template<> class VectorTraits<double[4]> {
public:
typedef double ValueType;
};
template<> class VectorTraits< itk::Index<5> > {
public:
typedef itk::Index<5>::IndexValueType ValueType;
};
template<> class VectorTraits< itk::Index<3> > {
public:
typedef itk::Index<3>::IndexValueType ValueType;
};
template<> class VectorTraits< long int [3]> {
public:
typedef long int ValueType;
};
template<> class VectorTraits< float [3]> {
public:
typedef float ValueType;
};
template<> class VectorTraits< double [3]> {
public:
typedef double ValueType;
};
template<> class VectorTraits< vnl_vector_fixed<ScalarType, 3> > {
public:
typedef ScalarType ValueType;
};
template<> class VectorTraits< long unsigned int[3]> {
public:
typedef long unsigned int ValueType;
};
template<> class VectorTraits< unsigned int *> {
public:
typedef unsigned int ValueType;
};
template<> class VectorTraits< ScalarType[4] > {
public:
typedef ScalarType ValueType;
};
template<> class VectorTraits< itk::Vector<float,3> > {
public:
typedef float ValueType;
};
template<> class VectorTraits< itk::Point<float,3> > {
public:
typedef float ValueType;
};
template<> class VectorTraits< itk::Point<float,4> > {
public:
typedef float ValueType;
};
template<> class VectorTraits< itk::Vector<double,3> > {
public:
typedef double ValueType;
};
template<> class VectorTraits< itk::Point<double,3> > {
public:
typedef double ValueType;
};
template<> class VectorTraits< itk::Vector<int,3> > {
public:
typedef int ValueType;
};
template<> class VectorTraits< itk::Point<int,3> > {
public:
typedef int ValueType;
};
template <class Tin, class Tout>
inline void itk2vtk(const Tin& in, Tout& out)
{
out[0]=(typename VectorTraits<Tout>::ValueType)(in[0]);
out[1]=(typename VectorTraits<Tout>::ValueType)(in[1]);
out[2]=(typename VectorTraits<Tout>::ValueType)(in[2]);
}
template <class Tin, class Tout>
inline void vtk2itk(const Tin& in, Tout& out)
{
out[0]=(typename VectorTraits<Tout>::ValueType)(in[0]);
out[1]=(typename VectorTraits<Tout>::ValueType)(in[1]);
out[2]=(typename VectorTraits<Tout>::ValueType)(in[2]);
}
template <class Tout>
inline void FillVector3D(Tout& out, ScalarType x, ScalarType y, ScalarType z)
{
out[0] = (typename VectorTraits<Tout>::ValueType)x;
out[1] = (typename VectorTraits<Tout>::ValueType)y;
out[2] = (typename VectorTraits<Tout>::ValueType)z;
}
template <class Tout>
inline void FillVector4D(Tout& out, ScalarType x, ScalarType y, ScalarType z, ScalarType t)
{
out[0] = (typename VectorTraits<Tout>::ValueType)x;
out[1] = (typename VectorTraits<Tout>::ValueType)y;
out[2] = (typename VectorTraits<Tout>::ValueType)z;
out[3] = (typename VectorTraits<Tout>::ValueType)t;
}
template <class Tin, class Tout>
inline void vnl2vtk(const vnl_vector<Tin>& in, Tout *out)
{
unsigned int i;
for(i=0; i<in.size();++i)
out[i]=(Tout) (in[i]);
}
template <class Tin, class Tout>
inline void vtk2vnl(const Tin *in, vnl_vector<Tout>& out)
{
unsigned int i;
for(i=0; i<out.size();++i)
out[i]=(Tout) (in[i]);
}
template <class Tin, class Tout>
inline void vtk2vnlref(const Tin *in, vnl_vector_ref<Tout>& out)
{
unsigned int i;
for(i=0; i<out.size();++i)
out[i]=(Tout) (in[i]);
}
template <class Tin, class Tout, unsigned int n>
inline void vnl2vtk(const vnl_vector_fixed<Tin, n>& in, Tout *out)
{
unsigned int i;
for(i=0; i<in.size();++i)
out[i]=(Tout) (in[i]);
}
template <class Tin, class Tout, unsigned int n>
inline void vtk2vnl(const Tin *in, vnl_vector_fixed<Tout, n>& out)
{
unsigned int i;
for(i=0; i<out.size();++i)
out[i]=(Tout) (in[i]);
}
template <class T, unsigned int NVectorDimension>
itk::Vector<T, NVectorDimension> operator+(const itk::Vector<T, NVectorDimension> &vector, const itk::Point<T, NVectorDimension> &point)
{
itk::Vector<T, NVectorDimension> sub;
for( unsigned int i=0; i<NVectorDimension; i++)
{
sub[i] = vector[i]+point[i];
}
return sub;
}
template <class T, unsigned int NVectorDimension>
inline itk::Vector<T, NVectorDimension>& operator+=(itk::Vector<T, NVectorDimension> &vector, const itk::Point<T, NVectorDimension> &point)
{
for( unsigned int i=0; i<NVectorDimension; i++)
{
vector[i] += point[i];
}
return vector;
}
template <class T, unsigned int NVectorDimension>
itk::Vector<T, NVectorDimension> operator-(const itk::Vector<T, NVectorDimension> &vector, const itk::Point<T, NVectorDimension> &point)
{
itk::Vector<T, NVectorDimension> sub;
for( unsigned int i=0; i<NVectorDimension; i++)
{
sub[i] = vector[i]-point[i];
}
return sub;
}
template <class T, unsigned int NVectorDimension>
inline itk::Vector<T, NVectorDimension>& operator-=(itk::Vector<T, NVectorDimension> &vector, const itk::Point<T, NVectorDimension> &point)
{
for( unsigned int i=0; i<NVectorDimension; i++)
{
vector[i] -= point[i];
}
return vector;
}
/*!
\brief Check for matrix equality with a user defined accuracy. As an equality metric the root mean squared error (RMS) of all elements is calculated.
\param matrix1 first vnl matrix
\param matrix2 second vnl matrix
\epsilon user defined accuracy bounds
*/
template <typename TCoordRep, unsigned int NRows, unsigned int NCols>
inline bool MatrixEqualRMS(const vnl_matrix_fixed<TCoordRep,NRows,NCols>& matrix1,const vnl_matrix_fixed<TCoordRep,NRows,NCols>& matrix2,mitk::ScalarType epsilon=mitk::eps)
{
if ( (matrix1.rows() == matrix2.rows()) && (matrix1.cols() == matrix2.cols()) )
{
vnl_matrix_fixed<TCoordRep,NRows,NCols> differenceMatrix = matrix1-matrix2;
if (differenceMatrix.rms()<epsilon)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
/*!
\brief Check for matrix equality with a user defined accuracy. As an equality metric the root mean squared error (RMS) of all elements is calculated.
\param matrix1 first itk matrix
\param matrix2 second itk matrix
\epsilon user defined accuracy bounds
*/
template <typename TCoordRep, unsigned int NRows, unsigned int NCols>
inline bool MatrixEqualRMS(const itk::Matrix<TCoordRep, NRows, NCols>& matrix1,const itk::Matrix<TCoordRep, NRows, NCols>& matrix2,mitk::ScalarType epsilon=mitk::eps)
{
return mitk::MatrixEqualRMS(matrix1.GetVnlMatrix(),matrix2.GetVnlMatrix(),epsilon);
}
/*!
\brief Check for element-wise matrix equality with a user defined accuracy.
\param matrix1 first vnl matrix
\param matrix2 second vnl matrix
\epsilon user defined accuracy bounds
*/
template <typename TCoordRep, unsigned int NRows, unsigned int NCols>
inline bool MatrixEqualElementWise(const vnl_matrix_fixed<TCoordRep,NRows,NCols>& matrix1,const vnl_matrix_fixed<TCoordRep,NRows,NCols>& matrix2,mitk::ScalarType epsilon=mitk::eps)
{
if ( (matrix1.rows() == matrix2.rows()) && (matrix1.cols() == matrix2.cols()) )
{
for( unsigned int r=0; r<NRows; r++)
{
for( unsigned int c=0; c<NCols; c++ )
{
TCoordRep difference = fabs(matrix1(r,c)-matrix2(r,c));
if (difference>epsilon)
{
return false;
}
}
}
return true;
}
else
{
return false;
}
}
/*!
\brief Check for element-wise matrix equality with a user defined accuracy.
\param matrix1 first itk matrix
\param matrix2 second itk matrix
\epsilon user defined accuracy bounds
*/
template <typename TCoordRep, unsigned int NRows, unsigned int NCols>
inline bool MatrixEqualElementWise(const itk::Matrix<TCoordRep, NRows, NCols>& matrix1,const itk::Matrix<TCoordRep, NRows, NCols>& matrix2,mitk::ScalarType epsilon=mitk::eps)
{
return mitk::MatrixEqualElementWise(matrix1.GetVnlMatrix(),matrix2.GetVnlMatrix(),epsilon);
}
template <typename TCoordRep, unsigned int NPointDimension>
inline bool Equal(const itk::Vector<TCoordRep, NPointDimension>& vector1, const itk::Vector<TCoordRep, NPointDimension>& vector2)
{
typename itk::Vector<TCoordRep, NPointDimension>::VectorType diff = vector1-vector2;
return diff.GetSquaredNorm() < mitk::eps;
}
template <typename TCoordRep, unsigned int NPointDimension>
inline bool Equal(const itk::Point<TCoordRep, NPointDimension>& vector1, const itk::Point<TCoordRep, NPointDimension>& vector2)
{
typename itk::Point<TCoordRep, NPointDimension>::VectorType diff = vector1-vector2;
return diff.GetSquaredNorm() < mitk::eps;
}
inline bool Equal(const mitk::VnlVector& vector1, const mitk::VnlVector& vector2)
{
mitk::VnlVector diff = vector1-vector2;
return diff.squared_magnitude() < mitk::eps;
}
inline bool Equal(double scalar1, double scalar2)
{
return fabs(scalar1-scalar2) < mitk::eps;
}
template <typename TCoordRep, unsigned int NPointDimension>
inline bool Equal(const vnl_vector_fixed<TCoordRep, NPointDimension> & vector1, const vnl_vector_fixed<TCoordRep, NPointDimension>& vector2)
{
vnl_vector_fixed<TCoordRep, NPointDimension> diff = vector1-vector2;
return diff.squared_magnitude() < mitk::eps;
}
template <typename U, typename V, unsigned int NRows, unsigned int NColumns>
inline void TransferMatrix(const itk::Matrix<U, NRows, NColumns>& in, itk::Matrix<V, NRows, NColumns>& out)
{
for (unsigned int i = 0; i < in.RowDimensions; ++i)
for (unsigned int j = 0; j < in.ColumnDimensions; ++j)
out[i][j] = in[i][j];
}
} // namespace mitk
#endif //DOXYGEN_SKIP
/*
* This part of the code has been shifted here to avoid compiler clashes
* caused by including <itkAffineGeometryFrame.h> before the declaration of
* the Equal() methods above. This problem occurs when using MSVC and is
* probably related to a compiler bug.
*/
#include <itkAffineGeometryFrame.h>
namespace mitk
{
typedef itk::AffineGeometryFrame<ScalarType, 3>::TransformType AffineTransform3D;
}
#define mitkSetConstReferenceMacro(name,type) \
virtual void Set##name (const type & _arg) \
{ \
itkDebugMacro("setting " << #name " to " << _arg ); \
if (this->m_##name != _arg) \
{ \
this->m_##name = _arg; \
this->Modified(); \
} \
}
#define mitkSetVectorMacro(name,type) \
mitkSetConstReferenceMacro(name,type)
#define mitkGetVectorMacro(name,type) \
itkGetConstReferenceMacro(name,type)
#endif /* MITKVECTOR_H_HEADER_INCLUDED_C1EBD0AD */
diff --git a/Core/Code/DataManagement/mitkVtkInterpolationProperty.cpp b/Core/Code/DataManagement/mitkVtkInterpolationProperty.cpp
index 4c0b16eb91..54b19822d4 100644
--- a/Core/Code/DataManagement/mitkVtkInterpolationProperty.cpp
+++ b/Core/Code/DataManagement/mitkVtkInterpolationProperty.cpp
@@ -1,92 +1,91 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <vtkProperty.h>
#include "mitkVtkInterpolationProperty.h"
mitk::VtkInterpolationProperty::VtkInterpolationProperty( )
{
AddInterpolationTypes();
SetValue( static_cast<IdType>( VTK_GOURAUD ) );
}
mitk::VtkInterpolationProperty::VtkInterpolationProperty( const IdType& value )
{
AddInterpolationTypes();
if ( IsValidEnumerationValue( value ) )
{
SetValue( value ) ;
}
else
{
SetValue( static_cast<IdType>( VTK_GOURAUD ) );
}
}
mitk::VtkInterpolationProperty::VtkInterpolationProperty( const std::string& value )
{
AddInterpolationTypes();
if ( IsValidEnumerationValue( value ) )
{
SetValue( value );
}
else
{
SetValue( static_cast<IdType>( VTK_GOURAUD ) );
}
}
int mitk::VtkInterpolationProperty::GetVtkInterpolation()
{
return static_cast<int>( GetValueAsId() );
}
void mitk::VtkInterpolationProperty::SetInterpolationToFlat()
{
SetValue( static_cast<IdType>( VTK_FLAT ) );
}
void mitk::VtkInterpolationProperty::SetInterpolationToGouraud()
{
SetValue( static_cast<IdType>( VTK_GOURAUD ) );
}
void mitk::VtkInterpolationProperty::SetInterpolationToPhong()
{
SetValue( static_cast<IdType>( VTK_PHONG ) );
}
void mitk::VtkInterpolationProperty::AddInterpolationTypes()
{
AddEnum( "Flat", static_cast<IdType>( VTK_FLAT ) );
AddEnum( "Gouraud", static_cast<IdType>( VTK_GOURAUD ) );
AddEnum( "Phong", static_cast<IdType>( VTK_PHONG ) );
}
bool mitk::VtkInterpolationProperty::AddEnum( const std::string& name, const IdType& id )
{
return Superclass::AddEnum( name, id );
}
diff --git a/Core/Code/DataManagement/mitkVtkInterpolationProperty.h b/Core/Code/DataManagement/mitkVtkInterpolationProperty.h
index 40564bc993..9dc69577cc 100644
--- a/Core/Code/DataManagement/mitkVtkInterpolationProperty.h
+++ b/Core/Code/DataManagement/mitkVtkInterpolationProperty.h
@@ -1,120 +1,119 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 _MITK_VTK_INTERPOLATION_PROPERTY__H_
#define _MITK_VTK_INTERPOLATION_PROPERTY__H_
#include "mitkEnumerationProperty.h"
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* Encapsulates the enumeration vtkInterpolation. Valid values are
* (VTK constant/Id/string representation):
* VTK_FLAT/0/Flat, VTK_GOURAUD/1/Gouraud, VTK_PHONG/2/Phong
* Default is the Gouraud interpolation
*/
class MITK_CORE_EXPORT VtkInterpolationProperty : public EnumerationProperty
{
public:
mitkClassMacro( VtkInterpolationProperty, EnumerationProperty );
itkNewMacro(VtkInterpolationProperty);
mitkNewMacro1Param(VtkInterpolationProperty, const IdType&);
mitkNewMacro1Param(VtkInterpolationProperty, const std::string&);
/**
* Returns the current interpolation value as defined by VTK constants.
* @returns the current interpolation as VTK constant.
*/
virtual int GetVtkInterpolation();
/**
* Sets the interpolation type to VTK_FLAT.
*/
virtual void SetInterpolationToFlat();
/**
* Sets the interpolation type to VTK_WIREFRAME.
*/
virtual void SetInterpolationToGouraud();
/**
* Sets the interpolation type to VTK_SURFACE.
*/
virtual void SetInterpolationToPhong();
using BaseProperty::operator=;
protected:
/**
* Constructor. Sets the representation to a default value of surface(2)
*/
VtkInterpolationProperty( );
/**
* Constructor. Sets the interpolation to the given value. If it is not
* valid, the interpolation is set to gouraud(1)
* @param value the integer representation of the interpolation
*/
VtkInterpolationProperty( const IdType& value );
/**
* Constructor. Sets the interpolation to the given value. If it is not
* valid, the representation is set to gouraud(1)
* @param value the string representation of the interpolation
*/
VtkInterpolationProperty( const std::string& value );
/**
* this function is overridden as protected, so that the user may not add
* additional invalid interpolation types.
*/
virtual bool AddEnum( const std::string& name, const IdType& id );
/**
* Adds the enumeration types as defined by vtk to the list of known
* enumeration values.
*/
virtual void AddInterpolationTypes();
private:
// purposely not implemented
VtkInterpolationProperty(const VtkInterpolationProperty&);
VtkInterpolationProperty& operator=(const VtkInterpolationProperty&);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // end of namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkVtkRepresentationProperty.cpp b/Core/Code/DataManagement/mitkVtkRepresentationProperty.cpp
index 3a6532f2fb..6189dc0b61 100644
--- a/Core/Code/DataManagement/mitkVtkRepresentationProperty.cpp
+++ b/Core/Code/DataManagement/mitkVtkRepresentationProperty.cpp
@@ -1,91 +1,90 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <vtkProperty.h>
#include "mitkVtkRepresentationProperty.h"
mitk::VtkRepresentationProperty::VtkRepresentationProperty( )
{
AddRepresentationTypes();
SetValue( static_cast<IdType>( VTK_SURFACE ) );
}
mitk::VtkRepresentationProperty::VtkRepresentationProperty( const IdType& value )
{
AddRepresentationTypes();
if ( IsValidEnumerationValue( value ) )
{
SetValue( value );
}
else
{
SetValue( static_cast<IdType>( VTK_SURFACE ) );
}
}
mitk::VtkRepresentationProperty::VtkRepresentationProperty( const std::string& value )
{
AddRepresentationTypes();
if ( IsValidEnumerationValue( value ) )
{
SetValue( value );
}
else
{
SetValue( static_cast<IdType>( VTK_SURFACE ) );
}
}
int mitk::VtkRepresentationProperty::GetVtkRepresentation()
{
return static_cast<int>( GetValueAsId() );
}
void mitk::VtkRepresentationProperty::SetRepresentationToPoints()
{
SetValue( static_cast<IdType>( VTK_POINTS ) );
}
void mitk::VtkRepresentationProperty::SetRepresentationToWireframe()
{
SetValue( static_cast<IdType>( VTK_WIREFRAME ) );
}
void mitk::VtkRepresentationProperty::SetRepresentationToSurface()
{
SetValue( static_cast<IdType>( VTK_SURFACE ) );
}
void mitk::VtkRepresentationProperty::AddRepresentationTypes()
{
AddEnum( "Points", static_cast<IdType>( VTK_POINTS ) );
AddEnum( "Wireframe", static_cast<IdType>( VTK_WIREFRAME ) );
AddEnum( "Surface", static_cast<IdType>( VTK_SURFACE ) );
}
bool mitk::VtkRepresentationProperty::AddEnum( const std::string& name, const IdType& id )
{
return Superclass::AddEnum( name, id );
}
diff --git a/Core/Code/DataManagement/mitkVtkRepresentationProperty.h b/Core/Code/DataManagement/mitkVtkRepresentationProperty.h
index 5798682cf6..2f2d85067c 100644
--- a/Core/Code/DataManagement/mitkVtkRepresentationProperty.h
+++ b/Core/Code/DataManagement/mitkVtkRepresentationProperty.h
@@ -1,119 +1,118 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 _MITK_VTK_REPRESENTATION_PROPERTY__H_
#define _MITK_VTK_REPRESENTATION_PROPERTY__H_
#include "mitkEnumerationProperty.h"
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* Encapsulates the enumeration vtkRepresentation. Valid values are
* (VTK constant/Id/string representation):
* VTK_POINTS/0/Points, VTK_WIREFRAME/1/Wireframe, VTK_SURFACE/2/Surface
* Default is the Surface representation
*/
class MITK_CORE_EXPORT VtkRepresentationProperty : public EnumerationProperty
{
public:
mitkClassMacro( VtkRepresentationProperty, EnumerationProperty );
itkNewMacro(VtkRepresentationProperty);
mitkNewMacro1Param(VtkRepresentationProperty, const IdType&);
mitkNewMacro1Param(VtkRepresentationProperty, const std::string&);
/**
* Returns the current representation value as defined by VTK constants.
* @returns the current representation as VTK constant.
*/
virtual int GetVtkRepresentation();
/**
* Sets the representation type to VTK_POINTS.
*/
virtual void SetRepresentationToPoints();
/**
* Sets the representation type to VTK_WIREFRAME.
*/
virtual void SetRepresentationToWireframe();
/**
* Sets the representation type to VTK_SURFACE.
*/
virtual void SetRepresentationToSurface();
using BaseProperty::operator=;
protected:
/**
* Constructor. Sets the representation to a default value of Surface(2)
*/
VtkRepresentationProperty( );
/**
* Constructor. Sets the representation to the given value. If it is not
* valid, the representation is set to Surface(2)
* @param value the integer representation of the representation
*/
VtkRepresentationProperty( const IdType& value );
/**
* Constructor. Sets the representation to the given value. If it is not
* valid, the representation is set to Surface(2)
* @param value the string representation of the representation
*/
VtkRepresentationProperty( const std::string& value );
/**
* this function is overridden as protected, so that the user may not add
* additional invalid representation types.
*/
virtual bool AddEnum( const std::string& name, const IdType& id );
/**
* Adds the enumeration types as defined by vtk to the list of known
* enumeration values.
*/
virtual void AddRepresentationTypes();
private:
// purposely not implemented
VtkRepresentationProperty(const VtkRepresentationProperty&);
VtkRepresentationProperty& operator=(const VtkRepresentationProperty&);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // end of namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.cpp b/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.cpp
index 15087887e6..bb1a133fef 100644
--- a/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.cpp
+++ b/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.cpp
@@ -1,92 +1,91 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <vtkProperty.h>
#include "mitkVtkResliceInterpolationProperty.h"
mitk::VtkResliceInterpolationProperty::VtkResliceInterpolationProperty( )
{
this->AddInterpolationTypes();
this->SetValue( static_cast<IdType>( VTK_RESLICE_NEAREST ) );
}
mitk::VtkResliceInterpolationProperty::VtkResliceInterpolationProperty( const IdType& value )
{
this->AddInterpolationTypes();
if ( IsValidEnumerationValue( value ) )
{
this->SetValue( value ) ;
}
else
{
this->SetValue( static_cast<IdType>( VTK_RESLICE_NEAREST ) );
}
}
mitk::VtkResliceInterpolationProperty::VtkResliceInterpolationProperty( const std::string& value )
{
this->AddInterpolationTypes();
if ( IsValidEnumerationValue( value ) )
{
this->SetValue( value );
}
else
{
this->SetValue( static_cast<IdType>( VTK_RESLICE_NEAREST ) );
}
}
int mitk::VtkResliceInterpolationProperty::GetInterpolation()
{
return static_cast<int>( this->GetValueAsId() );
}
void mitk::VtkResliceInterpolationProperty::SetInterpolationToNearest()
{
this->SetValue( static_cast<IdType>( VTK_RESLICE_NEAREST ) );
}
void mitk::VtkResliceInterpolationProperty::SetInterpolationToLinear()
{
this->SetValue( static_cast<IdType>( VTK_RESLICE_LINEAR ) );
}
void mitk::VtkResliceInterpolationProperty::SetInterpolationToCubic()
{
this->SetValue( static_cast<IdType>( VTK_RESLICE_CUBIC ) );
}
void mitk::VtkResliceInterpolationProperty::AddInterpolationTypes()
{
AddEnum( "Nearest", static_cast<IdType>( VTK_RESLICE_NEAREST ) );
AddEnum( "Linear", static_cast<IdType>( VTK_RESLICE_LINEAR ) );
AddEnum( "Cubic", static_cast<IdType>( VTK_RESLICE_CUBIC ) );
}
bool mitk::VtkResliceInterpolationProperty::AddEnum( const std::string& name, const IdType& id )
{
return Superclass::AddEnum( name, id );
}
diff --git a/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.h b/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.h
index b569917780..90d4288a61 100644
--- a/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.h
+++ b/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.h
@@ -1,116 +1,115 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 _MITK_VTK_RESLICE_INTERPOLATION_PROPERTY__H_
#define _MITK_VTK_RESLICE_INTERPOLATION_PROPERTY__H_
#include "mitkEnumerationProperty.h"
#include <vtkImageReslice.h>
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* Encapsulates the enumeration for reslice interpolation. Valid values are
* (VTK constant/Id/string representation):
* VTK_RESLICE_NEAREST, VTK_RESLICE_LINEAR, VTK_RESLICE_CUBIC
* Default is VTK_RESLICE_NEAREST
*/
class MITK_CORE_EXPORT VtkResliceInterpolationProperty : public EnumerationProperty
{
public:
mitkClassMacro( VtkResliceInterpolationProperty, EnumerationProperty );
itkNewMacro(VtkResliceInterpolationProperty);
mitkNewMacro1Param(VtkResliceInterpolationProperty, const IdType&);
mitkNewMacro1Param(VtkResliceInterpolationProperty, const std::string&);
/**
* Returns the current interpolation value as defined by VTK constants.
*/
virtual int GetInterpolation();
/**
* Sets the interpolation type to VTK_RESLICE_NEAREST.
*/
virtual void SetInterpolationToNearest();
/**
* Sets the interpolation type to VTK_RESLICE_LINEAR.
*/
virtual void SetInterpolationToLinear();
/**
* Sets the interpolation type to VTK_RESLICE_CUBIC.
*/
virtual void SetInterpolationToCubic();
using BaseProperty::operator=;
protected:
/** Sets reslice interpolation mode to default (VTK_RESLICE_NEAREST).
*/
VtkResliceInterpolationProperty( );
/**
* Constructor. Sets reslice interpolation to the given value.
*/
VtkResliceInterpolationProperty( const IdType& value );
/**
* Constructor. Sets reslice interpolation to the given value.
*/
VtkResliceInterpolationProperty( const std::string& value );
/**
* this function is overridden as protected, so that the user may not add
* additional invalid interpolation types.
*/
virtual bool AddEnum( const std::string& name, const IdType& id );
/**
* Adds the enumeration types as defined by vtk to the list of known
* enumeration values.
*/
virtual void AddInterpolationTypes();
private:
// purposely not implemented
VtkResliceInterpolationProperty(const VtkResliceInterpolationProperty&);
VtkResliceInterpolationProperty& operator=(const VtkResliceInterpolationProperty&);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // end of namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkVtkScalarModeProperty.cpp b/Core/Code/DataManagement/mitkVtkScalarModeProperty.cpp
index c3f95c779d..7be79389b7 100644
--- a/Core/Code/DataManagement/mitkVtkScalarModeProperty.cpp
+++ b/Core/Code/DataManagement/mitkVtkScalarModeProperty.cpp
@@ -1,95 +1,94 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <vtkAbstractMapper.h>
#include "mitkVtkScalarModeProperty.h"
mitk::VtkScalarModeProperty::VtkScalarModeProperty( )
{
AddInterpolationTypes();
SetScalarModeToDefault();
}
mitk::VtkScalarModeProperty::VtkScalarModeProperty( const IdType& value )
{
AddInterpolationTypes();
if ( IsValidEnumerationValue( value ) )
{
SetValue( value ) ;
}
else
{
SetScalarModeToDefault();
}
}
mitk::VtkScalarModeProperty::VtkScalarModeProperty( const std::string& value )
{
AddInterpolationTypes();
if ( IsValidEnumerationValue( value ) )
{
SetValue( value );
}
else
{
SetScalarModeToDefault();
}
}
int mitk::VtkScalarModeProperty::GetVtkScalarMode()
{
return static_cast<int>( GetValueAsId() );
}
void mitk::VtkScalarModeProperty::SetScalarModeToDefault()
{
SetValue( static_cast<IdType>( VTK_SCALAR_MODE_DEFAULT ) );
}
void mitk::VtkScalarModeProperty::SetScalarModeToPointData()
{
SetValue( static_cast<IdType>( VTK_SCALAR_MODE_USE_POINT_DATA ) );
}
void mitk::VtkScalarModeProperty::SetScalarModeToCellData()
{
SetValue( static_cast<IdType>( VTK_SCALAR_MODE_USE_CELL_DATA ) );
}
void mitk::VtkScalarModeProperty::SetScalarModeToPointFieldData()
{
SetValue( static_cast<IdType>( VTK_SCALAR_MODE_USE_POINT_FIELD_DATA ) );
}
void mitk::VtkScalarModeProperty::SetScalarModeToCellFieldData()
{
SetValue( static_cast<IdType>( VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ) );
}
void mitk::VtkScalarModeProperty::AddInterpolationTypes()
{
AddEnum( "Default", static_cast<IdType>( VTK_SCALAR_MODE_DEFAULT ) );
AddEnum( "PointData", static_cast<IdType>( VTK_SCALAR_MODE_USE_POINT_DATA ) );
AddEnum( "CellData", static_cast<IdType>( VTK_SCALAR_MODE_USE_CELL_DATA ) );
AddEnum( "PointFieldData", static_cast<IdType>( VTK_SCALAR_MODE_USE_POINT_FIELD_DATA ) );
AddEnum( "CellFieldData", static_cast<IdType>( VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ) );
}
bool mitk::VtkScalarModeProperty::AddEnum( const std::string& name, const IdType& id )
{
return Superclass::AddEnum( name, id );
}
diff --git a/Core/Code/DataManagement/mitkVtkScalarModeProperty.h b/Core/Code/DataManagement/mitkVtkScalarModeProperty.h
index c0117dd11c..7b92b98d33 100644
--- a/Core/Code/DataManagement/mitkVtkScalarModeProperty.h
+++ b/Core/Code/DataManagement/mitkVtkScalarModeProperty.h
@@ -1,118 +1,117 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 _MITK_VTK_SCALARMODE_PROPERTY__H_
#define _MITK_VTK_SCALARMODE_PROPERTY__H_
#include "mitkEnumerationProperty.h"
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* Encapsulates the enumeration vtkInterpolation. Valid values are
* (VTK constant/Id/string representation):
* \li VTK_SCALAR_MODE_DEFAULT/0/Default,
* \li VTK_SCALAR_MODE_USE_POINT_DATA/1/PointData,
* \li VTK_SCALAR_MODE_USE_CELL_DATA/2/CellData
* \li VTK_SCALAR_MODE_USE_POINT_FIELD_DATA/3/PointFieldData
* \li VTK_SCALAR_MODE_USE_CELL_FIELD_DATA/4/CellFieldData
*/
class MITK_CORE_EXPORT VtkScalarModeProperty : public EnumerationProperty
{
public:
mitkClassMacro( VtkScalarModeProperty, EnumerationProperty );
itkNewMacro(VtkScalarModeProperty);
mitkNewMacro1Param(VtkScalarModeProperty, const IdType&);
mitkNewMacro1Param(VtkScalarModeProperty, const std::string&);
/**
* Returns the current scalar mode value as defined by VTK constants.
* @returns the current scalar mode as VTK constant.
*/
virtual int GetVtkScalarMode();
virtual void SetScalarModeToDefault();
virtual void SetScalarModeToPointData();
virtual void SetScalarModeToCellData();
virtual void SetScalarModeToPointFieldData();
virtual void SetScalarModeToCellFieldData();
using BaseProperty::operator=;
protected:
/**
* Constructor. Sets the representation to a default value of surface(2)
*/
VtkScalarModeProperty( );
/**
* \brief Sets the scalar mode to the given value. If it is not
* valid, the scalar mode is set to default (0).
* @param value the integer representation of the scalar mode
*/
VtkScalarModeProperty( const IdType& value );
/**
* \brief Sets the scalar mode to the given value. If it is not
* valid, the representation is set to default (0).
* @param value the string representation of the scalar mode
*/
VtkScalarModeProperty( const std::string& value );
/**
* this function is overridden as protected, so that the user may not add
* additional invalid scalar mode types.
*/
virtual bool AddEnum( const std::string& name, const IdType& id );
/**
* Adds the enumeration types as defined by vtk to the list of known
* enumeration values.
*/
virtual void AddInterpolationTypes();
private:
// purposely not implemented
VtkScalarModeProperty(const VtkScalarModeProperty&);
VtkScalarModeProperty& operator=(const VtkScalarModeProperty&);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // end of namespace mitk
#endif //_MITK_VTK_SCALARMODE_PROPERTY__H_
diff --git a/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.cpp b/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.cpp
index acd0211d44..23f5511c73 100644
--- a/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.cpp
+++ b/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.cpp
@@ -1,79 +1,78 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <vtkProperty.h>
#include "mitkVtkVolumeRenderingProperty.h"
mitk::VtkVolumeRenderingProperty::VtkVolumeRenderingProperty( )
{
this->AddRenderingTypes();
this->SetValue( static_cast<IdType>( VTK_RAY_CAST_COMPOSITE_FUNCTION ) );
}
mitk::VtkVolumeRenderingProperty::VtkVolumeRenderingProperty( const IdType& value )
{
this->AddRenderingTypes();
if ( IsValidEnumerationValue( value ) )
{
this->SetValue( value ) ;
}
else
MITK_INFO << "Warning: invalid rendering configuration" << std::endl;
}
mitk::VtkVolumeRenderingProperty::VtkVolumeRenderingProperty( const std::string& value )
{
this->AddRenderingTypes();
if ( IsValidEnumerationValue( value ) )
{
this->SetValue( value );
}
else
MITK_INFO << "Warning: invalid rendering configuration" << std::endl;
}
int mitk::VtkVolumeRenderingProperty::GetRenderingType()
{
return static_cast<int>( this->GetValueAsId() );
}
void mitk::VtkVolumeRenderingProperty::SetRenderingTypeToMIP()
{
this->SetValue( static_cast<IdType>( VTK_VOLUME_RAY_CAST_MIP_FUNCTION ) );
}
void mitk::VtkVolumeRenderingProperty::SetRenderingTypeToComposite()
{
this->SetValue( static_cast<IdType>( VTK_RAY_CAST_COMPOSITE_FUNCTION ) );
}
void mitk::VtkVolumeRenderingProperty::AddRenderingTypes()
{
AddEnum( "MIP", static_cast<IdType>( VTK_VOLUME_RAY_CAST_MIP_FUNCTION ) );
AddEnum( "COMPOSITE", static_cast<IdType> (VTK_RAY_CAST_COMPOSITE_FUNCTION));
}
bool mitk::VtkVolumeRenderingProperty::AddEnum( const std::string& name, const IdType& id )
{
return Superclass::AddEnum( name, id );
}
diff --git a/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.h b/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.h
index 467c2def5c..fef5a40bdd 100644
--- a/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.h
+++ b/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.h
@@ -1,112 +1,111 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_VTK_VOLUME_RENDERING_PROPERTY__H_
#define _MITK_VTK_VOLUME_RENDERING_PROPERTY__H_
#include "mitkEnumerationProperty.h"
#define VTK_RAY_CAST_COMPOSITE_FUNCTION 1
#define VTK_VOLUME_RAY_CAST_MIP_FUNCTION 2
namespace mitk
{
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
/**
* Encapsulates the enumeration for volume rendering. Valid values are
* (VTK constant/Id/string representation):
* VTK_VOLUME_RAY_CAST_MIP_FUNCTION
* VTK_RAY_CAST_COMPOSITE_FUNCTION
* Default is NULL
*/
class MITK_CORE_EXPORT VtkVolumeRenderingProperty : public EnumerationProperty
{
public:
mitkClassMacro( VtkVolumeRenderingProperty, EnumerationProperty );
itkNewMacro(VtkVolumeRenderingProperty);
mitkNewMacro1Param(VtkVolumeRenderingProperty, const IdType&);
mitkNewMacro1Param(VtkVolumeRenderingProperty, const std::string&);
/**
* Returns the current volume rendering type
*/
virtual int GetRenderingType();
/**
* Sets the rendering type to VTK_VOLUME_RAY_CAST_MIP_FUNCTION
*/
virtual void SetRenderingTypeToMIP();
/**
* Sets the rendering type to VTK_RAY_CAST_COMPOSITE_FUNCTION
*/
virtual void SetRenderingTypeToComposite();
using BaseProperty::operator=;
protected:
/** Sets rendering type to default (VTK_RAY_CAST_COMPOSITE_FUNCTION).
*/
VtkVolumeRenderingProperty( );
/**
* Constructor. Sets rendering type to the given value.
*/
VtkVolumeRenderingProperty( const IdType& value );
/**
* Constructor. Sets rendering type to the given value.
*/
VtkVolumeRenderingProperty( const std::string& value );
/**
* this function is overridden as protected, so that the user may not add
* additional invalid rendering types.
*/
virtual bool AddEnum( const std::string& name, const IdType& id );
/**
* Adds the enumeration types as defined by vtk to the list of known
* enumeration values.
*/
virtual void AddRenderingTypes();
private:
// purposely not implemented
VtkVolumeRenderingProperty(const VtkVolumeRenderingProperty&);
VtkVolumeRenderingProperty& operator=(const VtkVolumeRenderingProperty&);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // end of namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkWeakPointer.h b/Core/Code/DataManagement/mitkWeakPointer.h
index f565a4b98c..7f440c8319 100644
--- a/Core/Code/DataManagement/mitkWeakPointer.h
+++ b/Core/Code/DataManagement/mitkWeakPointer.h
@@ -1,227 +1,226 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 14123 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkWeakPointer_h
#define __mitkWeakPointer_h
#include <MitkExports.h>
#include "mitkMessage.h"
#include <itkCommand.h>
#include <iostream>
namespace mitk
{
/** \class WeakPointer
* \brief Implements a weak reference to an object.
*
* Extends the standard itk WeakPointer by listening to delete events of itk::Objects.
* When an itk::Object is deleted the WeakPointer sets its internal Pointer to 0.
* This enables checking against 0 and avoids crashes by accessing changed memory.
* Furthermore it dispatches Modified events with the mitkMessageDelegate system which is
* much easier to use.
*/
template <class TObjectType>
class WeakPointer
{
public:
/** Extract infoirmation from template parameter. */
typedef TObjectType ObjectType;
typedef Message1<const itk::Object*> itkObjectEvent;
//##Documentation
//## @brief AddEvent is emitted when the object pointed to gets deleted
itkObjectEvent ObjectDelete;
//##Documentation
//## @brief AddEvent is emitted when the object pointed to gets modified
itkObjectEvent ObjectModified;
/** Constructor. */
WeakPointer ()
: m_DeleteObserverTag(-1)
, m_ModifiedObserverTag(-1)
, m_Pointer(0)
{
}
/** Copy constructor. */
WeakPointer (const WeakPointer<ObjectType> &p)
: m_DeleteObserverTag(-1)
, m_ModifiedObserverTag(-1)
, m_Pointer(p.m_Pointer)
{
this->AddDeleteAndModifiedObserver();
}
/** Constructor to pointer p. */
WeakPointer (ObjectType *p)
: m_DeleteObserverTag(-1),
m_ModifiedObserverTag(-1),
m_Pointer(p)
{
this->AddDeleteAndModifiedObserver();
}
/** Destructor. */
~WeakPointer ()
{
this->RemoveDeleteAndModifiedObserver();
m_Pointer = 0;
}
/** Overload operator ->. */
ObjectType *operator -> () const
{ return m_Pointer; }
/** Return pointer to object. */
operator ObjectType * () const
{ return m_Pointer; }
/** Template comparison operators. */
template <typename R>
bool operator == (R r) const
{
return (m_Pointer == (ObjectType*)r);
}
template <typename R>
bool operator != (R r) const
{
return (m_Pointer != (ObjectType*)r);
}
/** Access function to pointer. */
ObjectType *GetPointer () const
{ return m_Pointer; }
/** Comparison of pointers. Less than comparison. */
bool operator < (const WeakPointer &r) const
{ return (void*)m_Pointer < (void*) r.m_Pointer; }
/** Comparison of pointers. Greater than comparison. */
bool operator > (const WeakPointer &r) const
{ return (void*)m_Pointer > (void*) r.m_Pointer; }
/** Comparison of pointers. Less than or equal to comparison. */
bool operator <= (const WeakPointer &r) const
{ return (void*)m_Pointer <= (void*) r.m_Pointer; }
/** Comparison of pointers. Greater than or equal to comparison. */
bool operator >= (const WeakPointer &r) const
{ return (void*)m_Pointer >= (void*) r.m_Pointer; }
/** Test if the pointer has been initialized */
bool IsNotNull() const
{ return m_Pointer != 0; }
bool IsNull() const
{ return m_Pointer == 0; }
/** Overload operator assignment. */
WeakPointer &operator = (const WeakPointer &r)
{ return this->operator = (r.GetPointer()); }
/** Overload operator assignment. */
WeakPointer &operator = (ObjectType *r)
{
this->RemoveDeleteAndModifiedObserver();
m_Pointer = r;
this->AddDeleteAndModifiedObserver();
return *this;
}
/** Function to print object pointed to. */
ObjectType *Print (std::ostream& os) const
{
// This prints the object pointed to by the pointer
(*m_Pointer).Print(os);
return m_Pointer;
}
///
/// \brief Gets called when the object is deleted or modified.
///
void OnObjectDelete( const itk::Object *caller, const itk::EventObject & )
{
// do not unsubscribe from this object. this would invalidate the iterator of the
// event listener vector (in itk::Object) and would lead to a crash
// instead: do nothing->object is going to be dead soon...
//this->RemoveDeleteAndModifiedObserver();
m_Pointer = 0;
m_DeleteObserverTag = -1;
m_ModifiedObserverTag = -1;
ObjectDelete.Send(caller);
}
void OnObjectModified( const itk::Object *caller, const itk::EventObject & )
{
ObjectModified.Send(caller);
}
private:
void AddDeleteAndModifiedObserver()
{
if(m_DeleteObserverTag == -1 && m_ModifiedObserverTag == -1 && m_Pointer != 0)
{
// add observer for delete event
typename itk::MemberCommand<WeakPointer<TObjectType> >::Pointer onObjectDelete =
itk::MemberCommand<WeakPointer<TObjectType> >::New();
onObjectDelete->SetCallbackFunction(this, &WeakPointer<TObjectType>::OnObjectDelete);
m_DeleteObserverTag = m_Pointer->AddObserver(itk::DeleteEvent(), onObjectDelete);
// add observer for modified event
typename itk::MemberCommand<WeakPointer<TObjectType> >::Pointer onObjectModified =
itk::MemberCommand<WeakPointer<TObjectType> >::New();
onObjectModified->SetCallbackFunction(this, &WeakPointer<TObjectType>::OnObjectModified);
m_ModifiedObserverTag = m_Pointer->AddObserver(itk::ModifiedEvent(), onObjectModified);
}
}
void RemoveDeleteAndModifiedObserver()
{
if(m_DeleteObserverTag >= 0 && m_ModifiedObserverTag >= 0 && m_Pointer != 0)
{
m_Pointer->RemoveObserver(m_DeleteObserverTag);
m_Pointer->RemoveObserver(m_ModifiedObserverTag);
m_DeleteObserverTag = -1;
m_ModifiedObserverTag = -1;
}
}
long m_DeleteObserverTag;
long m_ModifiedObserverTag;
/** The pointer to the object referred to by this smart pointer. */
ObjectType* m_Pointer;
};
template <typename T>
std::ostream& operator<< (std::ostream& os, WeakPointer<T> p)
{
p.Print(os);
return os;
}
} // end namespace mitk
#endif
diff --git a/Core/Code/DataManagement/mitkWeakPointerProperty.cpp b/Core/Code/DataManagement/mitkWeakPointerProperty.cpp
index 9e3696b4ae..e832400222 100644
--- a/Core/Code/DataManagement/mitkWeakPointerProperty.cpp
+++ b/Core/Code/DataManagement/mitkWeakPointerProperty.cpp
@@ -1,69 +1,68 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkWeakPointerProperty.h"
bool mitk::WeakPointerProperty::IsEqual(const BaseProperty& property) const
{
return this->m_WeakPointer == static_cast<const Self&>(property).m_WeakPointer;
}
bool mitk::WeakPointerProperty::Assign(const BaseProperty& property)
{
this->m_WeakPointer = static_cast<const Self&>(property).m_WeakPointer;
return true;
}
mitk::WeakPointerProperty::WeakPointerProperty(itk::Object* pointer) : m_WeakPointer(pointer)
{
}
mitk::WeakPointerProperty::~WeakPointerProperty()
{
}
std::string mitk::WeakPointerProperty::GetValueAsString() const
{
std::stringstream ss;
ss << m_WeakPointer.GetPointer();
return ss.str();
}
mitk::WeakPointerProperty::ValueType mitk::WeakPointerProperty::GetWeakPointer() const
{
return m_WeakPointer.GetPointer();
}
mitk::WeakPointerProperty::ValueType mitk::WeakPointerProperty::GetValue() const
{
return GetWeakPointer();
}
void mitk::WeakPointerProperty::SetWeakPointer(itk::Object* pointer)
{
if(m_WeakPointer.GetPointer() != pointer)
{
m_WeakPointer = pointer;
Modified();
}
}
void mitk::WeakPointerProperty::SetValue(const ValueType &value)
{
SetWeakPointer(value.GetPointer());
}
diff --git a/Core/Code/DataManagement/mitkWeakPointerProperty.h b/Core/Code/DataManagement/mitkWeakPointerProperty.h
index 05b401db60..90a0c50456 100644
--- a/Core/Code/DataManagement/mitkWeakPointerProperty.h
+++ b/Core/Code/DataManagement/mitkWeakPointerProperty.h
@@ -1,81 +1,80 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKWEAKPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791
#define MITKWEAKPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791
#include <MitkExports.h>
#include "mitkBaseProperty.h"
#include "itkWeakPointer.h"
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
//##Documentation
//## @brief Property containing a smart-pointer
//##
//## @ingroup DataManagement
class MITK_CORE_EXPORT WeakPointerProperty : public BaseProperty
{
public:
mitkClassMacro(WeakPointerProperty, BaseProperty);
itkNewMacro(WeakPointerProperty);
mitkNewMacro1Param(WeakPointerProperty, itk::Object*);
virtual ~WeakPointerProperty();
typedef itk::WeakPointer<itk::Object> ValueType;
ValueType GetWeakPointer() const;
ValueType GetValue() const;
void SetWeakPointer(itk::Object* pointer);
void SetValue(const ValueType& value);
virtual std::string GetValueAsString() const;
using BaseProperty::operator=;
protected:
itk::WeakPointer<itk::Object> m_WeakPointer;
WeakPointerProperty(itk::Object* pointer = 0);
private:
// purposely not implemented
WeakPointerProperty(const WeakPointerProperty&);
WeakPointerProperty& operator=(const WeakPointerProperty&);
virtual bool IsEqual(const BaseProperty& property) const;
virtual bool Assign(const BaseProperty& property);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif /* MITKWEAKPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791 */
diff --git a/Core/Code/IO/mitkBaseDataIOFactory.cpp b/Core/Code/IO/mitkBaseDataIOFactory.cpp
index fa7c9619f4..8a82346d34 100644
--- a/Core/Code/IO/mitkBaseDataIOFactory.cpp
+++ b/Core/Code/IO/mitkBaseDataIOFactory.cpp
@@ -1,94 +1,93 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "mitkBaseDataIOFactory.h"
#include "mitkBaseProcess.h"
#include "mitkIOAdapter.h"
#include "mitkConfig.h"
namespace mitk
{
std::vector<BaseData::Pointer> BaseDataIO::LoadBaseDataFromFile(const std::string path, const std::string filePrefix, const std::string filePattern, bool series)
{
// factories are instantiated in mitk::CoreObjectFactory and other, potentially MITK external places
std::vector<BaseData::Pointer> result;
std::list<IOAdapterBase::Pointer> possibleIOAdapter;
std::list<LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("mitkIOAdapter");
for( std::list<LightObject::Pointer>::iterator i = allobjects.begin();
i != allobjects.end();
++i)
{
IOAdapterBase* io = dynamic_cast<IOAdapterBase*>(i->GetPointer());
if(io)
{
possibleIOAdapter.push_back(io);
}
else
{
MITK_ERROR << "Error BaseDataIO factory did not return an IOAdapterBase: "
<< (*i)->GetNameOfClass()
<< std::endl;
}
}
for( std::list<IOAdapterBase::Pointer>::iterator k = possibleIOAdapter.begin();
k != possibleIOAdapter.end();
++k )
{
bool canReadFile = false;
if ( series )
canReadFile = (*k)->CanReadFile(filePrefix, filePrefix, filePattern); // we have to provide a filename without extension here to
else // prevent the "normal" (non-series) readers to report that
canReadFile = (*k)->CanReadFile(path, filePrefix, filePattern); // they could read the file
if( canReadFile )
{
BaseProcess::Pointer ioObject = (*k)->CreateIOProcessObject(path, filePrefix, filePattern);
ioObject->Update();
int numberOfContents = static_cast<int>(ioObject->GetNumberOfOutputs());
if (numberOfContents > 0)
{
BaseData::Pointer baseData;
for(int i=0; i<numberOfContents; ++i)
{
baseData = dynamic_cast<BaseData*>(ioObject->GetOutputs()[i].GetPointer());
if (baseData) // this is what's wanted, right?
{
result.push_back( baseData );
}
}
}
break;
}
}
return result;
}
} // end namespace itk
diff --git a/Core/Code/IO/mitkBaseDataIOFactory.h b/Core/Code/IO/mitkBaseDataIOFactory.h
index 2546765116..704788e684 100644
--- a/Core/Code/IO/mitkBaseDataIOFactory.h
+++ b/Core/Code/IO/mitkBaseDataIOFactory.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkBaseDataIO_h
#define __mitkBaseDataIO_h
#include "mitkBaseData.h"
#include "itkObject.h"
namespace mitk
{
/*!
@brief BaseDataIO creates instances of BaseData objects using an object factory.
@todo Add file writing method, move writers into a similar factory scheme
@ingroup IO
*/
class MITK_CORE_EXPORT BaseDataIO : public itk::Object
{
public:
/** Standard class typedefs. */
typedef BaseDataIO Self;
typedef itk::Object Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class Methods used to interface with the registered factories */
/** Run-time type information (and related methods). */
itkTypeMacro(BaseDataIO, Object);
/** Create the appropriate BaseData depending on the particulars of the file. */
static std::vector<mitk::BaseData::Pointer> LoadBaseDataFromFile(const std::string path, const std::string filePrefix, const std::string filePattern, bool series);
protected:
BaseDataIO();
~BaseDataIO();
private:
BaseDataIO(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkCoreDataNodeReader.cpp b/Core/Code/IO/mitkCoreDataNodeReader.cpp
index 536d5726df..16f77b367a 100644
--- a/Core/Code/IO/mitkCoreDataNodeReader.cpp
+++ b/Core/Code/IO/mitkCoreDataNodeReader.cpp
@@ -1,49 +1,48 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkCoreDataNodeReader.h"
#include <mitkDataNodeFactory.h>
#include <mitkDataStorage.h>
namespace mitk {
int CoreDataNodeReader::Read(const std::string &fileName, DataStorage &storage)
{
mitk::DataNodeFactory::Pointer nodeReader = mitk::DataNodeFactory::New();
// the ITK Nrrd file reader cannot handle '/' in file path on Win 64bit
std::string name(fileName);
std::replace(name.begin(), name.end(), '\\', '/');
nodeReader->SetFileName(name);
nodeReader->Update();
int n = 0;
for ( unsigned int i = 0 ; i < nodeReader->GetNumberOfOutputs( ); ++i )
{
mitk::DataNode::Pointer node;
node = nodeReader->GetOutput(i);
if ( node->GetData() != NULL )
{
storage.Add(node);
++n;
}
}
return n;
}
}
diff --git a/Core/Code/IO/mitkCoreDataNodeReader.h b/Core/Code/IO/mitkCoreDataNodeReader.h
index 1aad362380..b27fdf1338 100644
--- a/Core/Code/IO/mitkCoreDataNodeReader.h
+++ b/Core/Code/IO/mitkCoreDataNodeReader.h
@@ -1,37 +1,36 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKCOREDATANODEREADER_H
#define MITKCOREDATANODEREADER_H
#include <mitkIDataNodeReader.h>
namespace mitk {
class CoreDataNodeReader : public itk::LightObject, public mitk::IDataNodeReader
{
public:
itkNewMacro(CoreDataNodeReader)
int Read(const std::string& fileName, mitk::DataStorage& storage);
};
}
#endif // MITKCOREDATANODEREADER_H
diff --git a/Core/Code/IO/mitkDicomSeriesReader.cpp b/Core/Code/IO/mitkDicomSeriesReader.cpp
index 12d1850b9c..18a1b9b43e 100644
--- a/Core/Code/IO/mitkDicomSeriesReader.cpp
+++ b/Core/Code/IO/mitkDicomSeriesReader.cpp
@@ -1,1132 +1,1131 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
// uncomment for learning more about the internal sorting mechanisms
//#define MBILOG_ENABLE_DEBUG
#include <mitkDicomSeriesReader.h>
#include <itkGDCMSeriesFileNames.h>
#include <gdcmAttribute.h>
#include <gdcmPixmapReader.h>
#include <gdcmStringFilter.h>
#include <gdcmDirectory.h>
#include <gdcmScanner.h>
#include "mitkProperties.h"
namespace mitk
{
typedef itk::GDCMSeriesFileNames DcmFileNamesGeneratorType;
const DicomSeriesReader::TagToPropertyMapType& DicomSeriesReader::GetDICOMTagsToMITKPropertyMap()
{
static bool initialized = false;
static TagToPropertyMapType dictionary;
if (!initialized)
{
/*
Selection criteria:
- no sequences because we cannot represent that
- nothing animal related (specied, breed registration number), MITK focusses on human medical image processing.
- only general attributes so far
When extending this, we should make use of a real dictionary (GDCM/DCMTK and lookup the tag names there)
*/
// Patient module
dictionary["0010|0010"] = "dicom.patient.PatientsName";
dictionary["0010|0020"] = "dicom.patient.PatientID";
dictionary["0010|0030"] = "dicom.patient.PatientsBirthDate";
dictionary["0010|0040"] = "dicom.patient.PatientsSex";
dictionary["0010|0032"] = "dicom.patient.PatientsBirthTime";
dictionary["0010|1000"] = "dicom.patient.OtherPatientIDs";
dictionary["0010|1001"] = "dicom.patient.OtherPatientNames";
dictionary["0010|2160"] = "dicom.patient.EthnicGroup";
dictionary["0010|4000"] = "dicom.patient.PatientComments";
dictionary["0012|0062"] = "dicom.patient.PatientIdentityRemoved";
dictionary["0012|0063"] = "dicom.patient.DeIdentificationMethod";
// General Study module
dictionary["0020|000d"] = "dicom.study.StudyInstanceUID";
dictionary["0008|0020"] = "dicom.study.StudyDate";
dictionary["0008|0030"] = "dicom.study.StudyTime";
dictionary["0008|0090"] = "dicom.study.ReferringPhysiciansName";
dictionary["0020|0010"] = "dicom.study.StudyID";
dictionary["0008|0050"] = "dicom.study.AccessionNumber";
dictionary["0008|1030"] = "dicom.study.StudyDescription";
dictionary["0008|1048"] = "dicom.study.PhysiciansOfRecord";
dictionary["0008|1060"] = "dicom.study.NameOfPhysicianReadingStudy";
// General Series module
dictionary["0008|0060"] = "dicom.series.Modality";
dictionary["0020|000e"] = "dicom.series.SeriesInstanceUID";
dictionary["0020|0011"] = "dicom.series.SeriesNumber";
dictionary["0020|0060"] = "dicom.series.Laterality";
dictionary["0008|0021"] = "dicom.series.SeriesDate";
dictionary["0008|0031"] = "dicom.series.SeriesTime";
dictionary["0008|1050"] = "dicom.series.PerformingPhysiciansName";
dictionary["0018|1030"] = "dicom.series.ProtocolName";
dictionary["0008|103e"] = "dicom.series.SeriesDescription";
dictionary["0008|1070"] = "dicom.series.OperatorsName";
dictionary["0018|0015"] = "dicom.series.BodyPartExamined";
dictionary["0018|5100"] = "dicom.series.PatientPosition";
dictionary["0028|0108"] = "dicom.series.SmallestPixelValueInSeries";
dictionary["0028|0109"] = "dicom.series.LargestPixelValueInSeries";
// VOI LUT module
dictionary["0028|1050"] = "dicom.voilut.WindowCenter";
dictionary["0028|1051"] = "dicom.voilut.WindowWidth";
dictionary["0028|1055"] = "dicom.voilut.WindowCenterAndWidthExplanation";
initialized = true;
}
return dictionary;
}
DataNode::Pointer
DicomSeriesReader::LoadDicomSeries(const StringContainer &filenames, bool sort, bool check_4d, UpdateCallBackMethod callback)
{
DataNode::Pointer node = DataNode::New();
if (DicomSeriesReader::LoadDicomSeries(filenames, *node, sort, check_4d, callback))
{
if( filenames.empty() )
{
return NULL;
}
return node;
}
else
{
return NULL;
}
}
bool
DicomSeriesReader::LoadDicomSeries(const StringContainer &filenames, DataNode &node, bool sort, bool check_4d, UpdateCallBackMethod callback)
{
if( filenames.empty() )
{
MITK_WARN << "Calling LoadDicomSeries with empty filename string container. Probably invalid application logic.";
node.SetData(NULL);
return true; // this is not actually an error but the result is very simple
}
DcmIoType::Pointer io = DcmIoType::New();
try
{
if (io->CanReadFile(filenames.front().c_str()))
{
io->SetFileName(filenames.front().c_str());
io->ReadImageInformation();
switch (io->GetComponentType())
{
case DcmIoType::UCHAR:
DicomSeriesReader::LoadDicom<unsigned char>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::CHAR:
DicomSeriesReader::LoadDicom<char>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::USHORT:
DicomSeriesReader::LoadDicom<unsigned short>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::SHORT:
DicomSeriesReader::LoadDicom<short>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::UINT:
DicomSeriesReader::LoadDicom<unsigned int>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::INT:
DicomSeriesReader::LoadDicom<int>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::ULONG:
DicomSeriesReader::LoadDicom<long unsigned int>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::LONG:
DicomSeriesReader::LoadDicom<long int>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::FLOAT:
DicomSeriesReader::LoadDicom<float>(filenames, node, sort, check_4d, callback);
break;
case DcmIoType::DOUBLE:
DicomSeriesReader::LoadDicom<double>(filenames, node, sort, check_4d, callback);
break;
default:
MITK_ERROR << "Found unsupported DICOM pixel type: (enum value) " << io->GetComponentType();
}
if (node.GetData())
{
return true;
}
}
}
catch(itk::MemoryAllocationError& e)
{
MITK_ERROR << "Out of memory. Cannot load DICOM series: " << e.what();
}
catch(std::exception& e)
{
MITK_ERROR << "Error encountered when loading DICOM series:" << e.what();
}
catch(...)
{
MITK_ERROR << "Unspecified error encountered when loading DICOM series.";
}
return false;
}
bool
DicomSeriesReader::IsDicom(const std::string &filename)
{
DcmIoType::Pointer io = DcmIoType::New();
return io->CanReadFile(filename.c_str());
}
bool
DicomSeriesReader::IsPhilips3DDicom(const std::string &filename)
{
DcmIoType::Pointer io = DcmIoType::New();
if (io->CanReadFile(filename.c_str()))
{
//Look at header Tag 3001,0010 if it is "Philips3D"
gdcm::Reader reader;
reader.SetFileName(filename.c_str());
reader.Read();
gdcm::DataSet &data_set = reader.GetFile().GetDataSet();
gdcm::StringFilter sf;
sf.SetFile(reader.GetFile());
if (data_set.FindDataElement(gdcm::Tag(0x3001, 0x0010)) &&
(sf.ToString(gdcm::Tag(0x3001, 0x0010)) == "Philips3D "))
{
return true;
}
}
return false;
}
bool
DicomSeriesReader::ReadPhilips3DDicom(const std::string &filename, mitk::Image::Pointer output_image)
{
// Now get PhilipsSpecific Tags
gdcm::PixmapReader reader;
reader.SetFileName(filename.c_str());
reader.Read();
gdcm::DataSet &data_set = reader.GetFile().GetDataSet();
gdcm::StringFilter sf;
sf.SetFile(reader.GetFile());
gdcm::Attribute<0x0028,0x0011> dimTagX; // coloumns || sagittal
gdcm::Attribute<0x3001,0x1001, gdcm::VR::UL, gdcm::VM::VM1> dimTagZ; //I have no idea what is VM1. // (Philips specific) // transversal
gdcm::Attribute<0x0028,0x0010> dimTagY; // rows || coronal
gdcm::Attribute<0x0028,0x0008> dimTagT; // how many frames
gdcm::Attribute<0x0018,0x602c> spaceTagX; // Spacing in X , unit is "physicalTagx" (usually centimeter)
gdcm::Attribute<0x0018,0x602e> spaceTagY;
gdcm::Attribute<0x3001,0x1003, gdcm::VR::FD, gdcm::VM::VM1> spaceTagZ; // (Philips specific)
gdcm::Attribute<0x0018,0x6024> physicalTagX; // if 3, then spacing params are centimeter
gdcm::Attribute<0x0018,0x6026> physicalTagY;
gdcm::Attribute<0x3001,0x1002, gdcm::VR::US, gdcm::VM::VM1> physicalTagZ; // (Philips specific)
dimTagX.Set(data_set);
dimTagY.Set(data_set);
dimTagZ.Set(data_set);
dimTagT.Set(data_set);
spaceTagX.Set(data_set);
spaceTagY.Set(data_set);
spaceTagZ.Set(data_set);
physicalTagX.Set(data_set);
physicalTagY.Set(data_set);
physicalTagZ.Set(data_set);
unsigned int
dimX = dimTagX.GetValue(),
dimY = dimTagY.GetValue(),
dimZ = dimTagZ.GetValue(),
dimT = dimTagT.GetValue(),
physicalX = physicalTagX.GetValue(),
physicalY = physicalTagY.GetValue(),
physicalZ = physicalTagZ.GetValue();
float
spaceX = spaceTagX.GetValue(),
spaceY = spaceTagY.GetValue(),
spaceZ = spaceTagZ.GetValue();
if (physicalX == 3) // spacing parameter in cm, have to convert it to mm.
spaceX = spaceX * 10;
if (physicalY == 3) // spacing parameter in cm, have to convert it to mm.
spaceY = spaceY * 10;
if (physicalZ == 3) // spacing parameter in cm, have to convert it to mm.
spaceZ = spaceZ * 10;
// Ok, got all necessary Tags!
// Now read Pixeldata (7fe0,0010) X x Y x Z x T Elements
const gdcm::Pixmap &pixels = reader.GetPixmap();
gdcm::RAWCodec codec;
codec.SetPhotometricInterpretation(gdcm::PhotometricInterpretation::MONOCHROME2);
codec.SetPixelFormat(pixels.GetPixelFormat());
codec.SetPlanarConfiguration(0);
gdcm::DataElement out;
codec.Decode(data_set.GetDataElement(gdcm::Tag(0x7fe0, 0x0010)), out);
const gdcm::ByteValue *bv = out.GetByteValue();
const char *new_pixels = bv->GetPointer();
// Create MITK Image + Geometry
typedef itk::Image<unsigned char, 4> ImageType; //Pixeltype might be different sometimes? Maybe read it out from header
ImageType::RegionType myRegion;
ImageType::SizeType mySize;
ImageType::IndexType myIndex;
ImageType::SpacingType mySpacing;
ImageType::Pointer imageItk = ImageType::New();
mySpacing[0] = spaceX;
mySpacing[1] = spaceY;
mySpacing[2] = spaceZ;
mySpacing[3] = 1;
myIndex[0] = 0;
myIndex[1] = 0;
myIndex[2] = 0;
myIndex[3] = 0;
mySize[0] = dimX;
mySize[1] = dimY;
mySize[2] = dimZ;
mySize[3] = dimT;
myRegion.SetSize( mySize);
myRegion.SetIndex( myIndex );
imageItk->SetSpacing(mySpacing);
imageItk->SetRegions( myRegion);
imageItk->Allocate();
imageItk->FillBuffer(0);
itk::ImageRegionIterator<ImageType> iterator(imageItk, imageItk->GetLargestPossibleRegion());
iterator.GoToBegin();
unsigned long pixCount = 0;
unsigned long planeSize = dimX*dimY;
unsigned long planeCount = 0;
unsigned long timeCount = 0;
unsigned long numberOfSlices = dimZ;
while (!iterator.IsAtEnd())
{
unsigned long adressedPixel =
pixCount
+ (numberOfSlices-1-planeCount)*planeSize // add offset to adress the first pixel of current plane
+ timeCount*numberOfSlices*planeSize; // add time offset
iterator.Set( new_pixels[ adressedPixel ] );
pixCount++;
++iterator;
if (pixCount == planeSize)
{
pixCount = 0;
planeCount++;
}
if (planeCount == numberOfSlices)
{
planeCount = 0;
timeCount++;
}
if (timeCount == dimT)
{
break;
}
}
mitk::CastToMitkImage(imageItk, output_image);
return true; // actually never returns false yet.. but exception possible
}
DicomSeriesReader::TwoStringContainers
DicomSeriesReader::AnalyzeFileForITKImageSeriesReaderSpacingAssumption(
const StringContainer& files,
const gdcm::Scanner::MappingType& tagValueMappings_)
{
// result.first = files that fit ITK's assumption
// result.second = files that do not fit, should be run through AnalyzeFileForITKImageSeriesReaderSpacingAssumption() again
TwoStringContainers result;
// we const_cast here, because I could not use a map.at(), which would make the code much more readable
gdcm::Scanner::MappingType& tagValueMappings = const_cast<gdcm::Scanner::MappingType&>(tagValueMappings_);
const gdcm::Tag tagImagePositionPatient(0x0020,0x0032); // Image Position (Patient)
const gdcm::Tag tagImageOrientation(0x0020, 0x0037); // Image Orientation
Vector3D fromFirstToSecondOrigin; fromFirstToSecondOrigin.Fill(0.0);
bool fromFirstToSecondOriginInitialized(false);
Point3D thisOrigin;
Point3D lastOrigin;
lastOrigin.Fill(0.0f);
Point3D lastDifferentOrigin;
lastDifferentOrigin.Fill(0.0f);
bool lastOriginInitialized(false);
MITK_DEBUG << "--------------------------------------------------------------------------------";
MITK_DEBUG << "Analyzing files for z-spacing assumption of ITK's ImageSeriesReader ";
unsigned int fileIndex(0);
for (StringContainer::const_iterator fileIter = files.begin();
fileIter != files.end();
++fileIter, ++fileIndex)
{
bool fileFitsIntoPattern(false);
std::string thisOriginString;
// Read tag value into point3D. PLEASE replace this by appropriate GDCM code if you figure out how to do that
const char* value = tagValueMappings[fileIter->c_str()][tagImagePositionPatient];
if (value)
{
thisOriginString = value;
}
std::istringstream originReader(thisOriginString);
std::string coordinate;
unsigned int dim(0);
while( std::getline( originReader, coordinate, '\\' ) ) thisOrigin[dim++] = atof(coordinate.c_str());
if (dim != 3)
{
MITK_ERROR << "Reader implementation made wrong assumption on tag (0020,0032). Found " << dim << "instead of 3 values.";
}
MITK_DEBUG << " " << fileIndex << " " << *fileIter
<< " at "
<< thisOriginString << "(" << thisOrigin[0] << "," << thisOrigin[1] << "," << thisOrigin[2] << ")";
if ( lastOriginInitialized && (thisOrigin == lastOrigin) )
{
MITK_DEBUG << " ==> Sort away " << *fileIter << " for separate time step"; // we already have one occupying this position
result.second.push_back( *fileIter );
fileFitsIntoPattern = false;
}
else
{
if (!fromFirstToSecondOriginInitialized && lastOriginInitialized) // calculate vector as soon as possible when we get a new position
{
fromFirstToSecondOrigin = thisOrigin - lastDifferentOrigin;
fromFirstToSecondOriginInitialized = true;
// Now make sure this direction is along the normal vector of the first slice
// If this is NOT the case, then we have a data set with a TILTED GANTRY geometry,
// which cannot be loaded into a single mitk::Image at the moment
// Again ugly code to read tag Image Orientation into two vEctors
Vector3D right; right.Fill(0.0);
Vector3D up; right.Fill(0.0); // might be down as well, but it is just a name at this point
std::string thisOrientationString;
const char* value = tagValueMappings[fileIter->c_str()][tagImageOrientation];
if (value)
{
thisOrientationString = value;
}
std::istringstream orientationReader(thisOrientationString);
std::string coordinate;
unsigned int dim(0);
while( std::getline( orientationReader, coordinate, '\\' ) )
if (dim<3) right[dim++] = atof(coordinate.c_str());
else up[dim++ - 3] = atof(coordinate.c_str());
if (dim != 6)
{
MITK_ERROR << "Reader implementation made wrong assumption on tag (0020,0037). Found " << dim << "instead of 6 values.";
}
/*
Determine if line (thisOrigin + l * normal) contains lastDifferentOrigin.
Done by calculating the distance of lastDifferentOrigin from line (thisOrigin + l *normal)
E.g. http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
squared distance = | (pointAlongNormal - thisOrign) x (thisOrigin - lastDifferentOrigin) | ^ 2
/
|pointAlongNormal - thisOrigin| ^ 2
( x meaning the cross product )
MITK_DEBUG << "Tilt check: right vector (" << right[0] << "," << right[1] << "," << right[2] << "), "
"up vector (" << up[0] << "," << up[1] << "," << up[2] << ")";
*/
Vector3D normal = itk::CrossProduct(right, up);
Point3D pointAlongNormal = thisOrigin + normal;
double numerator = itk::CrossProduct( pointAlongNormal - thisOrigin , thisOrigin - lastDifferentOrigin ).GetSquaredNorm();
double denominator = (pointAlongNormal - thisOrigin).GetSquaredNorm();
double distance = sqrt(numerator / denominator);
if (distance > 0.001) // mitk::eps is too small; 1/1000 of a mm should be enough to detect tilt
{
MITK_DEBUG << " Series might contain a tilted geometry";
MITK_DEBUG << " Distance of expected slice origin from actual slice origin: " << distance;
MITK_DEBUG << " ==> Sort away " << *fileIter << " for later analysis";
/* Pessimistic approach: split block right here
result.first.assign( files.begin(), fileIter );
result.second.insert( result.second.end(), fileIter, files.end() );
return result; // stop processing with first split
*/
/* optimistic approach: save file for later, check all further files */
result.second.push_back(*fileIter);
fileFitsIntoPattern = false;
}
else
{
result.first.push_back(*fileIter); // this file is good for current block
fileFitsIntoPattern = true;
}
}
else if (fromFirstToSecondOriginInitialized) // we already know the offset between slices
{
Point3D assumedOrigin = lastDifferentOrigin + fromFirstToSecondOrigin;
Vector3D originError = assumedOrigin - thisOrigin;
double norm = originError.GetNorm();
double toleratedError(0.005); // max. 1/10mm error when measurement crosses 20 slices in z direction
if (norm > toleratedError)
{
MITK_DEBUG << " File does not fit into the inter-slice distance pattern (diff = "
<< norm << ", allowed "
<< toleratedError << ").";
MITK_DEBUG << " Expected position (" << assumedOrigin[0] << ","
<< assumedOrigin[1] << ","
<< assumedOrigin[2] << "), got position ("
<< thisOrigin[0] << ","
<< thisOrigin[1] << ","
<< thisOrigin[2] << ")";
MITK_DEBUG << " ==> Sort away " << *fileIter << " for later analysis";
// At this point we know we deviated from the expectation of ITK's ImageSeriesReader
// We split the input file list at this point, i.e. all files up to this one (excluding it)
// are returned as group 1, the remaining files (including the faulty one) are group 2
/*
Pessimistic approach: split right here:
result.first.assign( files.begin(), fileIter );
result.second.insert( result.second.end(), fileIter, files.end() );
return result; // stop processing with first split
*/
/* Optimistic approach: check if any of the remaining slices fits in */
result.second.push_back( *fileIter ); // sort away for further analysis
fileFitsIntoPattern = false;
}
else
{
result.first.push_back(*fileIter); // this file is good for current block
fileFitsIntoPattern = true;
}
}
else // this should be the very first slice
{
result.first.push_back(*fileIter); // this file is good for current block
fileFitsIntoPattern = true;
}
}
// recored current origin for reference in later iterations
if ( !lastOriginInitialized || ( fileFitsIntoPattern && (thisOrigin != lastOrigin) ) )
{
lastDifferentOrigin = thisOrigin;
}
lastOrigin = thisOrigin;
lastOriginInitialized = true;
}
return result;
}
DicomSeriesReader::UidFileNamesMap
DicomSeriesReader::GetSeries(const StringContainer& files, const StringContainer &restrictions)
{
return GetSeries(files, true, restrictions);
}
DicomSeriesReader::UidFileNamesMap
DicomSeriesReader::GetSeries(const StringContainer& files, bool sortTo3DPlust, const StringContainer& /*restrictions*/)
{
/**
assumption about this method:
returns a map of uid-like-key --> list(filename)
each entry should contain filenames that have images of same
- series instance uid (automatically done by GDCMSeriesFileNames
- 0020,0037 image orientation (patient)
- 0028,0030 pixel spacing (x,y)
- 0018,0050 slice thickness
*/
UidFileNamesMap groupsOfSimilarImages; // preliminary result, refined into the final result mapOf3DPlusTBlocks
// use GDCM directly, itk::GDCMSeriesFileNames does not work with GDCM 2
// PART I: scan files for sorting relevant DICOM tags,
// separate images that differ in any of those
// attributes (they cannot possibly form a 3D block)
// scan for relevant tags in dicom files
gdcm::Scanner scanner;
const gdcm::Tag tagSeriesInstanceUID(0x0020,0x000e); // Series Instance UID
scanner.AddTag( tagSeriesInstanceUID );
const gdcm::Tag tagImageOrientation(0x0020, 0x0037); // image orientation
scanner.AddTag( tagImageOrientation );
const gdcm::Tag tagPixelSpacing(0x0028, 0x0030); // pixel spacing
scanner.AddTag( tagPixelSpacing );
const gdcm::Tag tagSliceThickness(0x0018, 0x0050); // slice thickness
scanner.AddTag( tagSliceThickness );
const gdcm::Tag tagNumberOfRows(0x0028, 0x0010); // number rows
scanner.AddTag( tagNumberOfRows );
const gdcm::Tag tagNumberOfColumns(0x0028, 0x0011); // number cols
scanner.AddTag( tagNumberOfColumns );
// additional tags read in this scan to allow later analysis
// THESE tag are not used for initial separating of files
const gdcm::Tag tagImagePositionPatient(0x0020,0x0032); // Image Position (Patient)
scanner.AddTag( tagImagePositionPatient );
// TODO add further restrictions from arguments
// let GDCM scan files
if ( !scanner.Scan( files ) )
{
MITK_ERROR << "gdcm::Scanner failed when scanning " << files.size() << " input files.";
return groupsOfSimilarImages;
}
// assign files IDs that will separate them for loading into image blocks
for (gdcm::Scanner::ConstIterator fileIter = scanner.Begin();
fileIter != scanner.End();
++fileIter)
{
//MITK_DEBUG << "Scan file " << fileIter->first << std::endl;
if ( std::string(fileIter->first).empty() ) continue; // TODO understand why Scanner has empty string entries
// we const_cast here, because I could not use a map.at() function in CreateMoreUniqueSeriesIdentifier.
// doing the same thing with find would make the code less readable. Since we forget the Scanner results
// anyway after this function, we can simply tolerate empty map entries introduced by bad operator[] access
std::string moreUniqueSeriesId = CreateMoreUniqueSeriesIdentifier( const_cast<gdcm::Scanner::TagToValue&>(fileIter->second) );
groupsOfSimilarImages [ moreUniqueSeriesId ].push_back( fileIter->first );
}
// PART III: sort slices spatially
for ( UidFileNamesMap::const_iterator groupIter = groupsOfSimilarImages.begin(); groupIter != groupsOfSimilarImages.end(); ++groupIter )
{
try
{
groupsOfSimilarImages[ groupIter->first ] = SortSeriesSlices( groupIter->second ); // sort each slice group spatially
} catch(...)
{
MITK_ERROR << "Catched something.";
}
}
// PART II: analyze pre-sorted images for valid blocks (i.e. blocks of equal z-spacing),
// separate into multiple blocks if necessary.
//
// Analysis performs the following steps:
// * imitate itk::ImageSeriesReader: use the distance between the first two images as z-spacing
// * check what images actually fulfill ITK's z-spacing assumption
// * separate all images that fail the test into new blocks, re-iterate analysis for these blocks
UidFileNamesMap mapOf3DPlusTBlocks; // final result of this function
for ( UidFileNamesMap::const_iterator groupIter = groupsOfSimilarImages.begin(); groupIter != groupsOfSimilarImages.end(); ++groupIter )
{
UidFileNamesMap mapOf3DBlocks; // intermediate result for only this group(!)
StringContainer filesStillToAnalyze = groupIter->second;
std::string groupUID = groupIter->first;
unsigned int subgroup(0);
MITK_DEBUG << "Analyze group " << groupUID;
while (!filesStillToAnalyze.empty()) // repeat until all files are grouped somehow
{
TwoStringContainers analysisResult = AnalyzeFileForITKImageSeriesReaderSpacingAssumption( filesStillToAnalyze, scanner.GetMappings() );
// enhance the UID for additional groups
std::stringstream newGroupUID;
newGroupUID << groupUID << '.' << subgroup;
mapOf3DBlocks[ newGroupUID.str() ] = analysisResult.first;
MITK_DEBUG << "Result: sorted 3D group " << newGroupUID.str() << " with " << mapOf3DBlocks[ newGroupUID.str() ].size() << " files";
++subgroup;
filesStillToAnalyze = analysisResult.second; // remember what needs further analysis
}
// end of grouping, now post-process groups
// PART IV: attempt to group blocks to 3D+t blocks if requested
// inspect entries of mapOf3DBlocks
// - if number of files is identical to previous entry, collect for 3D+t block
// - as soon as number of files changes from previous entry, record collected blocks as 3D+t block, start a new one, continue
// decide whether or not to group 3D blocks into 3D+t blocks where possible
if ( !sortTo3DPlust )
{
// copy 3D blocks to output
// TODO avoid collisions (or prove impossibility)
mapOf3DPlusTBlocks.insert( mapOf3DBlocks.begin(), mapOf3DBlocks.end() );
}
else
{
// sort 3D+t (as described in "PART IV")
MITK_DEBUG << "================================================================================";
MITK_DEBUG << "3D+t analysis:";
unsigned int numberOfFilesInPreviousBlock(0);
std::string previousBlockKey;
for ( UidFileNamesMap::const_iterator block3DIter = mapOf3DBlocks.begin();
block3DIter != mapOf3DBlocks.end();
++block3DIter )
{
unsigned int numberOfFilesInThisBlock = block3DIter->second.size();
std::string thisBlockKey = block3DIter->first;
if (numberOfFilesInPreviousBlock == 0)
{
numberOfFilesInPreviousBlock = numberOfFilesInThisBlock;
mapOf3DPlusTBlocks[thisBlockKey].insert( mapOf3DPlusTBlocks[thisBlockKey].end(),
block3DIter->second.begin(),
block3DIter->second.end() );
MITK_DEBUG << " 3D+t group " << thisBlockKey << " started";
previousBlockKey = thisBlockKey;
}
else
{
bool identicalOrigins;
try {
// check whether this and the previous block share a comon origin
// TODO should be safe, but a little try/catch or other error handling wouldn't hurt
const char
*origin_value = scanner.GetValue( mapOf3DBlocks[thisBlockKey].front().c_str(), tagImagePositionPatient ),
*previous_origin_value = scanner.GetValue( mapOf3DBlocks[previousBlockKey].front().c_str(), tagImagePositionPatient ),
*destination_value = scanner.GetValue( mapOf3DBlocks[thisBlockKey].back().c_str(), tagImagePositionPatient ),
*previous_destination_value = scanner.GetValue( mapOf3DBlocks[previousBlockKey].back().c_str(), tagImagePositionPatient );
if (!origin_value || !previous_origin_value || !destination_value || !previous_destination_value)
{
identicalOrigins = false;
}
else
{
std::string thisOriginString = origin_value;
std::string previousOriginString = previous_origin_value;
// also compare last origin, because this might differ if z-spacing is different
std::string thisDestinationString = destination_value;
std::string previousDestinationString = previous_destination_value;
identicalOrigins = ( (thisOriginString == previousOriginString) && (thisDestinationString == previousDestinationString) );
}
} catch(...)
{
identicalOrigins = false;
}
if (identicalOrigins && (numberOfFilesInPreviousBlock == numberOfFilesInThisBlock))
{
// group with previous block
mapOf3DPlusTBlocks[previousBlockKey].insert( mapOf3DPlusTBlocks[previousBlockKey].end(),
block3DIter->second.begin(),
block3DIter->second.end() );
MITK_DEBUG << " --> group enhanced with another timestep";
}
else
{
// start a new block
mapOf3DPlusTBlocks[thisBlockKey].insert( mapOf3DPlusTBlocks[thisBlockKey].end(),
block3DIter->second.begin(),
block3DIter->second.end() );
MITK_DEBUG << " ==> group closed with " << mapOf3DPlusTBlocks[previousBlockKey].size() / numberOfFilesInPreviousBlock << " time steps";
previousBlockKey = thisBlockKey;
MITK_DEBUG << " 3D+t group " << thisBlockKey << " started";
}
}
numberOfFilesInPreviousBlock = numberOfFilesInThisBlock;
}
}
}
MITK_DEBUG << "================================================================================";
MITK_DEBUG << "Summary: ";
for ( UidFileNamesMap::const_iterator groupIter = mapOf3DPlusTBlocks.begin(); groupIter != mapOf3DPlusTBlocks.end(); ++groupIter )
{
MITK_DEBUG << " Image volume " << groupIter->first << " with " << groupIter->second.size() << " files";
}
MITK_DEBUG << "Done. ";
MITK_DEBUG << "================================================================================";
return mapOf3DPlusTBlocks;
}
DicomSeriesReader::UidFileNamesMap
DicomSeriesReader::GetSeries(const std::string &dir, const StringContainer &restrictions)
{
gdcm::Directory directoryLister;
directoryLister.Load( dir.c_str(), false ); // non-recursive
return GetSeries(directoryLister.GetFilenames(), restrictions);
}
std::string
DicomSeriesReader::CreateSeriesIdentifierPart( gdcm::Scanner::TagToValue& tagValueMap, const gdcm::Tag& tag )
{
std::string result;
try
{
result = IDifyTagValue( tagValueMap[ tag ] ? tagValueMap[ tag ] : std::string("") );
}
catch (std::exception& e)
{
MITK_WARN << "Could not access tag " << tag << ": " << e.what();
}
return result;
}
std::string
DicomSeriesReader::CreateMoreUniqueSeriesIdentifier( gdcm::Scanner::TagToValue& tagValueMap )
{
const gdcm::Tag tagSeriesInstanceUID(0x0020,0x000e); // Series Instance UID
const gdcm::Tag tagImageOrientation(0x0020, 0x0037); // image orientation
const gdcm::Tag tagPixelSpacing(0x0028, 0x0030); // pixel spacing
const gdcm::Tag tagSliceThickness(0x0018, 0x0050); // slice thickness
const gdcm::Tag tagNumberOfRows(0x0028, 0x0010); // number rows
const gdcm::Tag tagNumberOfColumns(0x0028, 0x0011); // number cols
std::string constructedID;
try
{
constructedID = tagValueMap[ tagSeriesInstanceUID ];
}
catch (std::exception& e)
{
MITK_ERROR << "CreateMoreUniqueSeriesIdentifier() could not access series instance UID. Something is seriously wrong with this image.";
MITK_ERROR << "Error from exception: " << e.what();
}
constructedID += CreateSeriesIdentifierPart( tagValueMap, tagNumberOfRows );
constructedID += CreateSeriesIdentifierPart( tagValueMap, tagNumberOfColumns );
constructedID += CreateSeriesIdentifierPart( tagValueMap, tagPixelSpacing );
constructedID += CreateSeriesIdentifierPart( tagValueMap, tagSliceThickness );
constructedID += CreateSeriesIdentifierPart( tagValueMap, tagImageOrientation );
constructedID.resize( constructedID.length() - 1 ); // cut of trailing '.'
return constructedID;
}
std::string
DicomSeriesReader::IDifyTagValue(const std::string& value)
{
std::string IDifiedValue( value );
if (value.empty()) throw std::logic_error("IDifyTagValue() illegaly called with empty tag value");
// Eliminate non-alnum characters, including whitespace...
// that may have been introduced by concats.
for(std::size_t i=0; i<IDifiedValue.size(); i++)
{
while(i<IDifiedValue.size()
&& !( IDifiedValue[i] == '.'
|| (IDifiedValue[i] >= 'a' && IDifiedValue[i] <= 'z')
|| (IDifiedValue[i] >= '0' && IDifiedValue[i] <= '9')
|| (IDifiedValue[i] >= 'A' && IDifiedValue[i] <= 'Z')))
{
IDifiedValue.erase(i, 1);
}
}
IDifiedValue += ".";
return IDifiedValue;
}
DicomSeriesReader::StringContainer
DicomSeriesReader::GetSeries(const std::string &dir, const std::string &series_uid, const StringContainer &restrictions)
{
UidFileNamesMap allSeries = GetSeries(dir, restrictions);
StringContainer resultingFileList;
for ( UidFileNamesMap::const_iterator idIter = allSeries.begin();
idIter != allSeries.end();
++idIter )
{
if ( idIter->first.find( series_uid ) == 0 ) // this ID starts with given series_uid
{
resultingFileList.insert( resultingFileList.end(), idIter->second.begin(), idIter->second.end() ); // append
}
}
return resultingFileList;
}
DicomSeriesReader::StringContainer
DicomSeriesReader::SortSeriesSlices(const StringContainer &unsortedFilenames)
{
gdcm::Sorter sorter;
sorter.SetSortFunction(DicomSeriesReader::GdcmSortFunction);
try
{
sorter.Sort(unsortedFilenames);
return sorter.GetFilenames();
}
catch(std::logic_error&)
{
MITK_WARN << "Sorting error. Leaving series unsorted.";
return unsortedFilenames;
}
}
bool
DicomSeriesReader::GdcmSortFunction(const gdcm::DataSet &ds1, const gdcm::DataSet &ds2)
{
// make sure we habe Image Position and Orientation
if ( ! (
ds1.FindDataElement(gdcm::Tag(0x0020,0x0032)) &&
ds1.FindDataElement(gdcm::Tag(0x0020,0x0037)) &&
ds2.FindDataElement(gdcm::Tag(0x0020,0x0032)) &&
ds2.FindDataElement(gdcm::Tag(0x0020,0x0037))
)
)
{
MITK_WARN << "Dicom images are missing attributes for a meaningful sorting.";
throw std::logic_error("Dicom images are missing attributes for a meaningful sorting.");
}
gdcm::Attribute<0x0020,0x0032> image_pos1; // Image Position (Patient)
gdcm::Attribute<0x0020,0x0037> image_orientation1; // Image Orientation (Patient)
image_pos1.Set(ds1);
image_orientation1.Set(ds1);
gdcm::Attribute<0x0020,0x0032> image_pos2;
gdcm::Attribute<0x0020,0x0037> image_orientation2;
image_pos2.Set(ds2);
image_orientation2.Set(ds2);
if (image_orientation1 != image_orientation2)
{
MITK_ERROR << "Dicom images have different orientations.";
throw std::logic_error("Dicom images have different orientations. Call GetSeries() first to separate images.");
}
double normal[3];
normal[0] = image_orientation1[1] * image_orientation1[5] - image_orientation1[2] * image_orientation1[4];
normal[1] = image_orientation1[2] * image_orientation1[3] - image_orientation1[0] * image_orientation1[5];
normal[2] = image_orientation1[0] * image_orientation1[4] - image_orientation1[1] * image_orientation1[3];
double
dist1 = 0.0,
dist2 = 0.0;
for (unsigned char i = 0u; i < 3u; ++i)
{
dist1 += normal[i] * image_pos1[i];
dist2 += normal[i] * image_pos2[i];
}
if ( fabs(dist1 - dist2) < mitk::eps)
{
gdcm::Attribute<0x0008,0x0032> acq_time1; // Acquisition time (may be missing, so we check existence first)
gdcm::Attribute<0x0008,0x0032> acq_time2;
gdcm::Attribute<0x0020,0x0012> acq_number1; // Acquisition number (may also be missing, so we check existence first)
gdcm::Attribute<0x0020,0x0012> acq_number2;
if (ds1.FindDataElement(gdcm::Tag(0x0008,0x0032)) && ds2.FindDataElement(gdcm::Tag(0x0008,0x0032)))
{
acq_time1.Set(ds1);
acq_time2.Set(ds2);
return acq_time1 < acq_time2;
}
else if (ds1.FindDataElement(gdcm::Tag(0x0020,0x0012)) && ds2.FindDataElement(gdcm::Tag(0x0020,0x0012)))
{
acq_number1.Set(ds1);
acq_number2.Set(ds2);
return acq_number1 < acq_number2;
}
else
{
return true;
}
}
else
{
// default: compare position
return dist1 < dist2;
}
}
std::string DicomSeriesReader::GetConfigurationString()
{
std::stringstream configuration;
configuration << "MITK_USE_GDCMIO: ";
configuration << "true";
configuration << "\n";
configuration << "GDCM_VERSION: ";
#ifdef GDCM_MAJOR_VERSION
configuration << GDCM_VERSION;
#endif
//configuration << "\n";
return configuration.str();
}
void DicomSeriesReader::CopyMetaDataToImageProperties(StringContainer filenames, const gdcm::Scanner::MappingType &tagValueMappings_, DcmIoType *io, Image *image)
{
std::list<StringContainer> imageBlock;
imageBlock.push_back(filenames);
CopyMetaDataToImageProperties(imageBlock, tagValueMappings_, io, image);
}
void DicomSeriesReader::CopyMetaDataToImageProperties( std::list<StringContainer> imageBlock, const gdcm::Scanner::MappingType& tagValueMappings_, DcmIoType* io, Image* image)
{
if (!io || !image) return;
StringLookupTable filesForSlices;
StringLookupTable sliceLocationForSlices;
StringLookupTable instanceNumberForSlices;
StringLookupTable SOPInstanceNumberForSlices;
gdcm::Scanner::MappingType& tagValueMappings = const_cast<gdcm::Scanner::MappingType&>(tagValueMappings_);
//DICOM tags which should be added to the image properties
const gdcm::Tag tagSliceLocation(0x0020, 0x1041); // slice location
const gdcm::Tag tagInstanceNumber(0x0020, 0x0013); // (image) instance number
const gdcm::Tag tagSOPInstanceNumber(0x0008, 0x0018); // SOP instance number
unsigned int timeStep(0);
std::string propertyKeySliceLocation = "dicom.image.0020.1041";
std::string propertyKeyInstanceNumber = "dicom.image.0020.0013";
std::string propertyKeySOPInstanceNumber = "dicom.image.0008.0018";
// tags for each image
for ( std::list<StringContainer>::iterator i = imageBlock.begin(); i != imageBlock.end(); i++, timeStep++ )
{
const StringContainer& files = (*i);
unsigned int slice(0);
for ( StringContainer::const_iterator fIter = files.begin();
fIter != files.end();
++fIter, ++slice )
{
filesForSlices.SetTableValue( slice, *fIter );
gdcm::Scanner::TagToValue tagValueMapForFile = tagValueMappings[fIter->c_str()];
if(tagValueMapForFile.find(tagSliceLocation) != tagValueMapForFile.end())
sliceLocationForSlices.SetTableValue(slice, tagValueMapForFile[tagSliceLocation]);
if(tagValueMapForFile.find(tagInstanceNumber) != tagValueMapForFile.end())
instanceNumberForSlices.SetTableValue(slice, tagValueMapForFile[tagInstanceNumber]);
if(tagValueMapForFile.find(tagSOPInstanceNumber) != tagValueMapForFile.end())
SOPInstanceNumberForSlices.SetTableValue(slice, tagValueMapForFile[tagSOPInstanceNumber]);
}
image->SetProperty( "files", StringLookupTableProperty::New( filesForSlices ) );
//If more than one time step add postfix ".t" + timestep
if(timeStep != 0)
{
propertyKeySliceLocation.append(".t" + timeStep);
propertyKeyInstanceNumber.append(".t" + timeStep);
propertyKeySOPInstanceNumber.append(".t" + timeStep);
}
image->SetProperty( propertyKeySliceLocation.c_str(), StringLookupTableProperty::New( sliceLocationForSlices ) );
image->SetProperty( propertyKeyInstanceNumber.c_str(), StringLookupTableProperty::New( instanceNumberForSlices ) );
image->SetProperty( propertyKeySOPInstanceNumber.c_str(), StringLookupTableProperty::New( SOPInstanceNumberForSlices ) );
}
// Copy tags for series, study, patient level (leave interpretation to application).
// These properties will be copied to the DataNode by DicomSeriesReader.
// tags for the series (we just use the one that ITK copied to its dictionary (proably that of the last slice)
const itk::MetaDataDictionary& dict = io->GetMetaDataDictionary();
const TagToPropertyMapType& propertyLookup = DicomSeriesReader::GetDICOMTagsToMITKPropertyMap();
itk::MetaDataDictionary::ConstIterator dictIter = dict.Begin();
while ( dictIter != dict.End() )
{
MITK_DEBUG << "Key " << dictIter->first;
std::string value;
if ( itk::ExposeMetaData<std::string>( dict, dictIter->first, value ) )
{
MITK_DEBUG << "Value " << value;
TagToPropertyMapType::const_iterator valuePosition = propertyLookup.find( dictIter->first );
if ( valuePosition != propertyLookup.end() )
{
std::string propertyKey = valuePosition->second;
MITK_DEBUG << "--> " << propertyKey;
image->SetProperty( propertyKey.c_str(), StringProperty::New(value) );
}
}
else
{
MITK_WARN << "Tag " << dictIter->first << " not read as string as expected. Ignoring..." ;
}
++dictIter;
}
}
} // end namespace mitk
#include <mitkDicomSeriesReader.txx>
diff --git a/Core/Code/IO/mitkDicomSeriesReader.h b/Core/Code/IO/mitkDicomSeriesReader.h
index c859e3d172..2e14dc9a14 100644
--- a/Core/Code/IO/mitkDicomSeriesReader.h
+++ b/Core/Code/IO/mitkDicomSeriesReader.h
@@ -1,471 +1,471 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+The Medical Imaging Interaction Toolkit (MITK)
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
+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 mitkDicomSeriesReader_h
#define mitkDicomSeriesReader_h
#include "mitkDataNode.h"
#include "mitkConfig.h"
#include <itkGDCMImageIO.h>
#include <itkImageSeriesReader.h>
#include <itkCommand.h>
#ifdef NOMINMAX
# define DEF_NOMINMAX
# undef NOMINMAX
#endif
#include <gdcmConfigure.h>
#ifdef DEF_NOMINMAX
# ifndef NOMINMAX
# define NOMINMAX
# endif
# undef DEF_NOMINMAX
#endif
#include <gdcmDataSet.h>
#include <gdcmRAWCodec.h>
#include <gdcmSorter.h>
#include <gdcmScanner.h>
#include <gdcmPixmapReader.h>
#include <gdcmStringFilter.h>
namespace mitk
{
/**
\brief Loading DICOM images as MITK images.
- \ref DicomSeriesReader_purpose
- \ref DicomSeriesReader_limitations
- \ref DicomSeriesReader_usage
- \ref DicomSeriesReader_sorting
- \ref DicomSeriesReader_sorting1
- \ref DicomSeriesReader_sorting2
- \ref DicomSeriesReader_sorting3
- \ref DicomSeriesReader_sorting4
- \ref DicomSeriesReader_tests
\section DicomSeriesReader_purpose Purpose
DicomSeriesReader serves as a central class for loading DICOM images as mitk::Image.
As the term "DICOM image" covers a huge variety of possible modalities and
implementations, and since MITK assumes that 3D images are made up of continuous blocks
of slices without any gaps or changes in orientation, the loading mechanism must
implement a number of decisions and compromises.
<b>The main intention of this implementation is not efficiency but correcness of generated slice positions!</b>
\section DicomSeriesReader_limitations Assumptions and limitations
The class is working only with GDCM 2.0.14 (or possibly newer). This version is the
default of an MITK super-build. Support for other versions or ITK's DicomIO was dropped
because of the associated complexity of DicomSeriesReader.
\b Assumptions
- expected to work for SOP Classes CT Image Storage and MR Image Storage (NOT for the "Enhanced" variants containing multi-frame images)
- special treatment for a certain type of Philips 3D ultrasound (recogized by tag 3001,0010 set to "Philips3D")
- loader will always attempt to read multiple single slices as a single 3D image volume (i.e. mitk::Image)
- slices will be grouped by basic properties such as orientation, rows, columns, spacing and grouped into as large blocks as possible
\b Options
- images that cover the same piece of space (i.e. position, orientation, and dimensions are equal)
can be interpreted as time-steps of the same image, i.e. a series will be loaded as 3D+t
\b Limitations
- the 3D+t assumption only works if all time-steps have an equal number of slices and if all
have the Acquisition Time attribute set to meaningful values
- Images from tilted CT gantries CAN ONLY be loaded as a series of single-slice images, since
mitk::Image or the accompanying mapper are not (yet?) capable of representing such geometries
- Secondary Capture images are expected to have the (0018,2010) tag describing the pixel spacing.
If only the (0028,0030) tag is set, the spacing will be misinterpreted as (1,1)
\section DicomSeriesReader_usage Usage
The starting point for an application is a set of DICOM files that should be loaded.
For convenience, DicomSeriesReader can also parse a whole directory for DICOM files,
but an application should better know exactly what to load.
Loading is then done in two steps:
1. <b>Group the files into spatial blocks</b> by calling GetSeries().
This method will sort all passed files into meaningful blocks that
could fit into an mitk::Image. Sorting for 3D+t loading is optional but default.
The \b return value of this function is a list of identifiers similar to
DICOM UIDs, each associated to a sorted list of file names.
2. <b>Load a sorted set of files</b> by calling LoadDicomSeries().
This method expects go receive the sorting output of GetSeries().
The method will then invoke ITK methods to actually load the
files into memory and put them into mitk::Images. Again, loading
as 3D+t is optional.
Example:
\code
// only a directory is known at this point: /home/who/dicom
DicomSeriesReader::UidFileNamesMap allImageBlocks = DicomSeriesReader::GetSeries("/home/who/dicom/");
// file now divided into groups of identical image size, orientation, spacing, etc.
// each of these lists should be loadable as an mitk::Image.
DicomSeriesReader::StringContainer seriesToLoad = allImageBlocks[...]; // decide what to load
// final step: load into DataNode (can result in 3D+t image)
DataNode::Pointer node = DicomSeriesReader::LoadDicomSeries( oneBlockSorted );
Image::Pointer image = dynamic_cast<mitk::Image*>( node->GetData() );
\endcode
\section DicomSeriesReader_sorting Logic for sorting 2D slices from DICOM images into 3D+t blocks for mitk::Image
The general sorting mechanism (implemented in GetSeries) groups and sorts a set of DICOM files, each assumed to contain a single CT/MR slice.
In the following we refer to those file groups as "blocks", since this is what they are meant to become when loaded into an mitk::Image.
\subsection DicomSeriesReader_sorting1 Step 1: Avoiding pure non-sense
A first pass separates slices that cannot possibly be loaded together because of restrictions of mitk::Image.
After this steps, each block contains only slices that match in all of the following DICOM tags:
- (0020,0037) Image Orientation
- (0028,0030) Pixel Spacing
- (0018,0050) Slice Thickness
- (0028,0010) Number Of Rows
- (0028,0011) Number Of Columns
- (0020,000e) Series Instance UID : could be argued about, might be dropped in the future (optionally)
\subsection DicomSeriesReader_sorting2 Step 2: Sort slices spatially
Before slices are further analyzed, they are sorted spatially. As implemented by GdcmSortFunction(),
slices are sorted by
1. distance from origin (calculated using (0020,0032) Image Position Patient and (0020,0037) Image Orientation)
2. when distance is equal, (0008,0032) Acquisition Time is used as a backup criterion (necessary for meaningful 3D+t sorting)
\subsection DicomSeriesReader_sorting3 Step 3: Ensure equal z spacing
Since inter-slice distance is not recorded in DICOM tags, we must ensure that blocks are made up of
slices that have equal distances between neighboring slices. This is especially necessary because itk::ImageSeriesReader
is later used for the actual loading, and this class expects (and does nocht verify) equal inter-slice distance.
To achieve such grouping, the inter-slice distance is calculated from the first two different slice positions of a block.
Following slices are added to a block as long as they can be added by adding the calculated inter-slice distance to the
last slice of the block. Slices that do not fit into the expected distance pattern, are set aside for further analysis.
This grouping is done until each file has been assigned to a group.
Slices that share a position in space are also sorted into separate blocks during this step.
So the result of this step is a set of blocks that contain only slices with equal z spacing
and uniqe slices at each position.
\subsection DicomSeriesReader_sorting4 Step 4 (optional): group 3D blocks as 3D+t when possible
This last step depends on an option of GetSeries(). When requested, image blocks from the previous step are merged again
whenever two blocks occupy the same portion of space (i.e. same origin, number of slices and z-spacing).
\section DicomSeriesReader_tests Tests regarding DICOM loading
A number of tests have been implemented to check our assumptions regarding DICOM loading. Please see \ref DICOMTesting
*/
class MITK_CORE_EXPORT DicomSeriesReader
{
public:
/**
\brief Lists of filenames.
*/
typedef std::vector<std::string> StringContainer;
/**
\brief For grouped lists of filenames, assigned an ID each.
*/
typedef std::map<std::string, StringContainer> UidFileNamesMap;
/**
\brief Interface for the progress callback.
*/
typedef void (*UpdateCallBackMethod)(float);
/**
\brief Provide combination of preprocessor defines that was active during compilation.
Since this class is a combination of several possible implementations, separated only
by ifdef's, calling instances might want to know which flags were active at compile time.
*/
static std::string GetConfigurationString();
/**
\brief Checks if a specific file contains DICOM data.
*/
static
bool
IsDicom(const std::string &filename);
/**
\brief see other GetSeries().
Find all series (and sub-series -- see details) in a particular directory.
*/
static UidFileNamesMap GetSeries(const std::string &dir,
const StringContainer &restrictions = StringContainer());
/**
\brief see other GetSeries().
\warning Untested, could or could not work.
This differs only by having an additional restriction to a single known DICOM series.
Internally, it uses the other GetSeries() method.
*/
static StringContainer GetSeries(const std::string &dir,
const std::string &series_uid,
const StringContainer &restrictions = StringContainer());
/**
\brief PREFERRED version of this method - scan and sort DICOM files.
Parse a list of files for images of DICOM series.
For each series, an enumeration of the files contained in it is created.
\return The resulting maps UID-like keys (based on Series Instance UID and slice properties) to sorted lists of file names.
SeriesInstanceUID will be enhanced to be unique for each set of file names
that is later loadable as a single mitk::Image. This implies that
Image orientation, slice thickness, pixel spacing, rows, and columns
must be the same for each file (i.e. the image slice contained in the file).
If this separation logic requires that a SeriesInstanceUID must be made more specialized,
it will follow the same logic as itk::GDCMSeriesFileNames to enhance the UID with
more digits and dots.
Optionally, more tags can be used to separate files into different logical series by setting
the restrictions parameter.
\warning Adding restrictions is not yet implemented!
*/
static
UidFileNamesMap
GetSeries(const StringContainer& files, bool sortTo3DPlust, const StringContainer &restrictions = StringContainer());
/**
\brief See other GetSeries().
Use GetSeries(const StringContainer& files, bool sortTo3DPlust, const StringContainer &restrictions) instead.
*/
static
UidFileNamesMap
GetSeries(const StringContainer& files, const StringContainer &restrictions = StringContainer());
/**
Loads a DICOM series composed by the file names enumerated in the file names container.
If a callback method is supplied, it will be called after every progress update with a progress value in [0,1].
\param filenames The filenames to load.
\param sort Whether files should be sorted spatially (true) or not (false - maybe useful if presorted)
\param load4D Whether to load the files as 3D+t (if possible)
*/
static DataNode::Pointer LoadDicomSeries(const StringContainer &filenames,
bool sort = true,
bool load4D = true,
UpdateCallBackMethod callback = 0);
/**
\brief See LoadDicomSeries! Just a slightly different interface.
*/
static bool LoadDicomSeries(const StringContainer &filenames,
DataNode &node,
bool sort = true,
bool load4D = true,
UpdateCallBackMethod callback = 0);
protected:
/**
\brief for internal sorting.
*/
typedef std::pair<StringContainer, StringContainer> TwoStringContainers;
/**
\brief Maps DICOM tags to MITK properties.
*/
typedef std::map<std::string, std::string> TagToPropertyMapType;
/**
\brief Ensure an equal z-spacing for a group of files.
Internally used by GetSeries. Returns two lists: the first one contins slices of equal inter-slice spacing.
The second list contains remaining files, which need to be run through AnalyzeFileForITKImageSeriesReaderSpacingAssumption again.
Relevant code that is matched here is in
itkImageSeriesReader.txx (ImageSeriesReader<TOutputImage>::GenerateOutputInformation(void)), lines 176 to 245 (as of ITK 3.20)
*/
static
TwoStringContainers
AnalyzeFileForITKImageSeriesReaderSpacingAssumption(const StringContainer& files, const gdcm::Scanner::MappingType& tagValueMappings_);
/**
\brief Sort a set of file names in an order that is meaningful for loading them into an mitk::Image.
\warning This method assumes that input files are similar in basic properties such as
slice thicknes, image orientation, pixel spacing, rows, columns.
It should always be ok to put the result of a call to GetSeries(..) into this method.
Sorting order is determined by
1. image position along its normal (distance from world origin)
2. acquisition time
If P<n> denotes a position and T<n> denotes a time step, this method will order slices from three timesteps like this:
\verbatim
P1T1 P1T2 P1T3 P2T1 P2T2 P2T3 P3T1 P3T2 P3T3
\endverbatim
*/
static StringContainer SortSeriesSlices(const StringContainer &unsortedFilenames);
public:
/**
\brief Checks if a specific file is a Philips3D ultrasound DICOM file.
*/
static bool IsPhilips3DDicom(const std::string &filename);
protected:
/**
\brief Read a Philips3D ultrasound DICOM file and put into an mitk::Image.
*/
static bool ReadPhilips3DDicom(const std::string &filename, mitk::Image::Pointer output_image);
/**
\brief Construct a UID that takes into account sorting criteria from GetSeries().
*/
static std::string CreateMoreUniqueSeriesIdentifier( gdcm::Scanner::TagToValue& tagValueMap );
/**
\brief Helper for CreateMoreUniqueSeriesIdentifier
*/
static std::string CreateSeriesIdentifierPart( gdcm::Scanner::TagToValue& tagValueMap, const gdcm::Tag& tag );
/**
\brief Helper for CreateMoreUniqueSeriesIdentifier
*/
static std::string IDifyTagValue(const std::string& value);
typedef itk::GDCMImageIO DcmIoType;
/**
\brief Progress callback for DicomSeriesReader.
*/
class CallbackCommand : public itk::Command
{
public:
CallbackCommand(UpdateCallBackMethod callback)
: m_Callback(callback)
{
}
void Execute(const itk::Object *caller, const itk::EventObject&)
{
(*this->m_Callback)(static_cast<const itk::ProcessObject*>(caller)->GetProgress());
}
void Execute(itk::Object *caller, const itk::EventObject&)
{
(*this->m_Callback)(static_cast<itk::ProcessObject*>(caller)->GetProgress());
}
protected:
UpdateCallBackMethod m_Callback;
};
/**
\brief Scan for slice image information
*/
static void ScanForSliceInformation( const StringContainer &filenames, gdcm::Scanner& scanner );
/**
\brief Performs actual loading of a series and creates an image having the specified pixel type.
*/
template <typename PixelType>
static
void
LoadDicom(const StringContainer &filenames, DataNode &node, bool sort, bool check_4d, UpdateCallBackMethod callback);
/**
\brief Feed files into itk::ImageSeriesReader and retrieve a 3D MITK image.
\param command can be used for progress reporting
*/
template <typename PixelType>
static
Image::Pointer
LoadDICOMByITK( const StringContainer&, CallbackCommand* command = NULL);
/**
\brief Sort files into time step blocks of a 3D+t image.
Called by LoadDicom. Expects to be fed a single list of filenames that have been sorted by
GetSeries previously (one map entry). This method will check how many timestep can be filled
with given files.
Assumption is that the number of time steps is determined by how often the first position in
space repeats. I.e. if the first three files in the input parameter all describe the same
location in space, we'll construct three lists of files. and sort the remaining files into them.
\todo We can probably remove this method if we somehow transfer 3D+t information from GetSeries to LoadDicomSeries.
*/
static
std::list<StringContainer>
SortIntoBlocksFor3DplusT( const StringContainer& presortedFilenames, const gdcm::Scanner::MappingType& tagValueMappings_, bool sort, bool& canLoadAs4D);
/**
\brief Defines spatial sorting for sorting by GDCM 2.
Sorts by image position along image normal (distance from world origin).
In cases of conflict, acquisition time is used as a secondary sort criterium.
*/
static
bool
GdcmSortFunction(const gdcm::DataSet &ds1, const gdcm::DataSet &ds2);
/**
\brief Copy information about files and DICOM tags from ITK's MetaDataDictionary
and from the list of input files to the PropertyList of mitk::Image.
\todo Tag copy must follow; image level will cause some additional files parsing, probably.
*/
static void CopyMetaDataToImageProperties( StringContainer filenames, const gdcm::Scanner::MappingType& tagValueMappings_, DcmIoType* io, Image* image);
static void CopyMetaDataToImageProperties( std::list<StringContainer> imageBlock, const gdcm::Scanner::MappingType& tagValueMappings_, DcmIoType* io, Image* image);
/**
\brief Map between DICOM tags and MITK properties.
Uses as a positive list for copying specified DICOM tags (from ITK's ImageIO)
to MITK properties. ITK provides MetaDataDictionary entries of form
"gggg|eeee" (g = group, e = element), e.g. "0028,0109" (Largest Pixel in Series),
which we want to sort as dicom.series.largest_pixel_in_series".
*/
static const TagToPropertyMapType& GetDICOMTagsToMITKPropertyMap();
};
}
#endif /* MITKDICOMSERIESREADER_H_ */
diff --git a/Core/Code/IO/mitkDicomSeriesReader.txx b/Core/Code/IO/mitkDicomSeriesReader.txx
index 4ef94371de..a67ba660fc 100644
--- a/Core/Code/IO/mitkDicomSeriesReader.txx
+++ b/Core/Code/IO/mitkDicomSeriesReader.txx
@@ -1,318 +1,317 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKDICOMSERIESREADER_TXX_
#define MITKDICOMSERIESREADER_TXX_
#include <mitkDicomSeriesReader.h>
#include <itkImageSeriesReader.h>
#include <mitkProperties.h>
namespace mitk
{
template <typename PixelType>
void DicomSeriesReader::LoadDicom(const StringContainer &filenames, DataNode &node, bool sort, bool load4D, UpdateCallBackMethod callback)
{
const char* previousCLocale = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
std::locale previousCppLocale( std::cin.getloc() );
std::locale l( "C" );
std::cin.imbue(l);
try
{
mitk::Image::Pointer image = mitk::Image::New();
CallbackCommand *command = callback ? new CallbackCommand(callback) : 0;
bool initialize_node = false;
/* special case for Philips 3D+t ultrasound images */
if ( DicomSeriesReader::IsPhilips3DDicom(filenames.front().c_str()) )
{
ReadPhilips3DDicom(filenames.front().c_str(), image);
initialize_node = true;
}
else
{
/* default case: assume "normal" image blocks, possibly 3D+t */
bool canLoadAs4D(true);
gdcm::Scanner scanner;
ScanForSliceInformation(filenames, scanner);
std::list<StringContainer> imageBlocks = SortIntoBlocksFor3DplusT( filenames, scanner.GetMappings(), sort, canLoadAs4D );
unsigned int volume_count = imageBlocks.size();
if (volume_count == 1 || !canLoadAs4D || !load4D)
{
image = LoadDICOMByITK<PixelType>( imageBlocks.front() , command ); // load first 3D block
initialize_node = true;
}
else if (volume_count > 1)
{
// It is 3D+t! Read it and store into mitk image
typedef itk::Image<PixelType, 4> ImageType;
typedef itk::ImageSeriesReader<ImageType> ReaderType;
DcmIoType::Pointer io = DcmIoType::New();
typename ReaderType::Pointer reader = ReaderType::New();
reader->SetImageIO(io);
reader->ReverseOrderOff();
if (command)
{
reader->AddObserver(itk::ProgressEvent(), command);
}
unsigned int act_volume = 1u;
reader->SetFileNames(imageBlocks.front());
reader->Update();
image->InitializeByItk(reader->GetOutput(), 1, volume_count);
image->SetImportVolume(reader->GetOutput()->GetBufferPointer(), 0u);
gdcm::Scanner scanner;
ScanForSliceInformation(filenames, scanner);
DicomSeriesReader::CopyMetaDataToImageProperties( imageBlocks, scanner.GetMappings(), io, image);
MITK_DEBUG << "Volume dimension: [" << image->GetDimension(0) << ", "
<< image->GetDimension(1) << ", "
<< image->GetDimension(2) << ", "
<< image->GetDimension(3) << "]";
#if (GDCM_MAJOR_VERSION == 2) && (GDCM_MINOR_VERSION < 1) && (GDCM_BUILD_VERSION < 15)
// workaround for a GDCM 2 bug until version 2.0.15:
// GDCM read spacing vector wrongly. Instead of "row spacing, column spacing", it misinterprets the DICOM tag as "column spacing, row spacing".
// this is undone here, until we use a GDCM that has this issue fixed.
// From the commit comments, GDCM 2.0.15 fixed the spacing interpretation with bug 2901181
// http://sourceforge.net/tracker/index.php?func=detail&aid=2901181&group_id=137895&atid=739587
Vector3D correctedImageSpacing = image->GetGeometry()->GetSpacing();
std::swap( correctedImageSpacing[0], correctedImageSpacing[1] );
image->GetGeometry()->SetSpacing( correctedImageSpacing );
#endif
MITK_DEBUG << "Volume spacing: [" << image->GetGeometry()->GetSpacing()[0] << ", "
<< image->GetGeometry()->GetSpacing()[1] << ", "
<< image->GetGeometry()->GetSpacing()[2] << "]";
for (std::list<StringContainer>::iterator df_it = ++imageBlocks.begin(); df_it != imageBlocks.end(); ++df_it)
{
reader->SetFileNames(*df_it);
reader->Update();
image->SetImportVolume(reader->GetOutput()->GetBufferPointer(), act_volume++);
}
initialize_node = true;
}
}
if (initialize_node)
{
// forward some image properties to node
node.GetPropertyList()->ConcatenatePropertyList( image->GetPropertyList(), true );
node.SetData( image );
setlocale(LC_NUMERIC, previousCLocale);
std::cin.imbue(previousCppLocale);
}
}
catch (std::exception& e)
{
// reset locale then throw up
setlocale(LC_NUMERIC, previousCLocale);
std::cin.imbue(previousCppLocale);
throw e;
}
}
template <typename PixelType>
Image::Pointer DicomSeriesReader::LoadDICOMByITK( const StringContainer& filenames, CallbackCommand* command )
{
/******** Normal Case, 3D (also for GDCM < 2 usable) ***************/
mitk::Image::Pointer image = mitk::Image::New();
typedef itk::Image<PixelType, 3> ImageType;
typedef itk::ImageSeriesReader<ImageType> ReaderType;
DcmIoType::Pointer io = DcmIoType::New();
typename ReaderType::Pointer reader = ReaderType::New();
reader->SetImageIO(io);
reader->ReverseOrderOff();
if (command)
{
reader->AddObserver(itk::ProgressEvent(), command);
}
reader->SetFileNames(filenames);
reader->Update();
image->InitializeByItk(reader->GetOutput());
image->SetImportVolume(reader->GetOutput()->GetBufferPointer());
gdcm::Scanner scanner;
ScanForSliceInformation(filenames, scanner);
DicomSeriesReader::CopyMetaDataToImageProperties( filenames, scanner.GetMappings(), io, image);
MITK_DEBUG << "Volume dimension: [" << image->GetDimension(0) << ", "
<< image->GetDimension(1) << ", "
<< image->GetDimension(2) << "]";
#if (GDCM_MAJOR_VERSION == 2) && (GDCM_MINOR_VERSION < 1) && (GDCM_BUILD_VERSION < 15)
// workaround for a GDCM 2 bug until version 2.0.15:
// GDCM read spacing vector wrongly. Instead of "row spacing, column spacing", it misinterprets the DICOM tag as "column spacing, row spacing".
// this is undone here, until we use a GDCM that has this issue fixed.
// From the commit comments, GDCM 2.0.15 fixed the spacing interpretation with bug 2901181
// http://sourceforge.net/tracker/index.php?func=detail&aid=2901181&group_id=137895&atid=739587
Vector3D correctedImageSpacing = image->GetGeometry()->GetSpacing();
std::swap( correctedImageSpacing[0], correctedImageSpacing[1] );
image->GetGeometry()->SetSpacing( correctedImageSpacing );
#endif
MITK_DEBUG << "Volume spacing: [" << image->GetGeometry()->GetSpacing()[0] << ", "
<< image->GetGeometry()->GetSpacing()[1] << ", "
<< image->GetGeometry()->GetSpacing()[2] << "]";
return image;
}
void
DicomSeriesReader::ScanForSliceInformation(const StringContainer &filenames, gdcm::Scanner& scanner)
{
const gdcm::Tag ippTag(0x0020,0x0032); //Image position (Patient)
scanner.AddTag(ippTag);
// TODO what if tags don't exist?
const gdcm::Tag tagSliceLocation(0x0020, 0x1041); // slice location
scanner.AddTag( tagSliceLocation );
const gdcm::Tag tagInstanceNumber(0x0020, 0x0013); // (image) instance number
scanner.AddTag( tagInstanceNumber );
const gdcm::Tag tagSOPInstanceNumber(0x0008, 0x0018); // SOP instance number
scanner.AddTag( tagSOPInstanceNumber );
scanner.Scan(filenames); // make available image position for each file
}
std::list<DicomSeriesReader::StringContainer>
DicomSeriesReader::SortIntoBlocksFor3DplusT(
const StringContainer& presortedFilenames,
const gdcm::Scanner::MappingType& tagValueMappings,
bool /*sort*/,
bool& canLoadAs4D )
{
std::list<StringContainer> imageBlocks;
// ignore sort request, because most likely re-sorting is now needed due to changes in GetSeries(bug #8022)
StringContainer sorted_filenames = DicomSeriesReader::SortSeriesSlices(presortedFilenames);
std::string firstPosition;
unsigned int numberOfBlocks(0); // number of 3D image blocks
const gdcm::Tag ippTag(0x0020,0x0032); //Image position (Patient)
// loop files to determine number of image blocks
for (StringContainer::const_iterator fileIter = sorted_filenames.begin();
fileIter != sorted_filenames.end();
++fileIter)
{
gdcm::Scanner::TagToValue tagToValueMap = tagValueMappings.find( fileIter->c_str() )->second;
if(tagToValueMap.find(ippTag) == tagToValueMap.end())
{
continue;
}
std::string position = tagToValueMap.find(ippTag)->second;
MITK_DEBUG << " " << *fileIter << " at " << position;
if (firstPosition.empty())
{
firstPosition = position;
}
if ( position == firstPosition )
{
++numberOfBlocks;
}
else
{
break; // enough information to know the number of image blocks
}
}
MITK_DEBUG << " ==> Assuming " << numberOfBlocks << " time steps";
if (numberOfBlocks == 0) return imageBlocks; // only possible if called with no files
// loop files to sort them into image blocks
unsigned int numberOfExpectedSlices(0);
for (unsigned int block = 0; block < numberOfBlocks; ++block)
{
StringContainer filesOfCurrentBlock;
for ( StringContainer::const_iterator fileIter = sorted_filenames.begin() + block;
fileIter != sorted_filenames.end();
//fileIter += numberOfBlocks) // TODO shouldn't this work? give invalid iterators on first attempts
)
{
filesOfCurrentBlock.push_back( *fileIter );
for (unsigned int b = 0; b < numberOfBlocks; ++b)
{
if (fileIter != sorted_filenames.end())
++fileIter;
}
}
imageBlocks.push_back(filesOfCurrentBlock);
if (block == 0)
{
numberOfExpectedSlices = filesOfCurrentBlock.size();
}
else
{
if (filesOfCurrentBlock.size() != numberOfExpectedSlices)
{
MITK_WARN << "DicomSeriesReader expected " << numberOfBlocks
<< " image blocks of "
<< numberOfExpectedSlices
<< " images each. Block "
<< block
<< " got "
<< filesOfCurrentBlock.size()
<< " instead. Cannot load this as 3D+t"; // TODO implement recovery (load as many slices 3D+t as much as possible)
canLoadAs4D = false;
}
}
}
return imageBlocks;
}
}
#endif
diff --git a/Core/Code/IO/mitkFileReader.cpp b/Core/Code/IO/mitkFileReader.cpp
index 626df24e41..2b38ee1094 100644
--- a/Core/Code/IO/mitkFileReader.cpp
+++ b/Core/Code/IO/mitkFileReader.cpp
@@ -1,48 +1,47 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkFileReader.h"
mitk::FileReader::FileReader() :
m_CanReadFromMemory (false),
m_ReadFromMemory (false)
{
}
mitk::FileReader::~FileReader()
{
}
bool mitk::FileReader::CanReadFromMemory( )
{
return m_CanReadFromMemory;
}
void mitk::FileReader::SetReadFromMemory( bool read )
{
m_ReadFromMemory = read;
}
bool mitk::FileReader::GetReadFromMemory( )
{
return m_ReadFromMemory;
}
void mitk::FileReader::SetMemoryBuffer(const char* dataArray, unsigned int size)
{
m_MemoryBuffer = dataArray;
m_MemorySize = size;
}
diff --git a/Core/Code/IO/mitkFileReader.h b/Core/Code/IO/mitkFileReader.h
index f6574d6c2b..f1ac328f93 100644
--- a/Core/Code/IO/mitkFileReader.h
+++ b/Core/Code/IO/mitkFileReader.h
@@ -1,107 +1,106 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 FILEREADER_H_HEADER_INCLUDED_C1E7E521
#define FILEREADER_H_HEADER_INCLUDED_C1E7E521
#include <MitkExports.h>
namespace mitk {
//##Documentation
//## @brief Interface class of readers that read from files
//## @ingroup Process
class MITK_CORE_EXPORT FileReader
{
public:
//##Documentation
//## @brief Get the specified the file to load.
//##
//## Either the FileName or FilePrefix plus FilePattern are used to read.
virtual const char* GetFileName() const = 0;
//##Documentation
//## @brief Specify the file to load.
//##
//## Either the FileName or FilePrefix plus FilePattern are used to read.
virtual void SetFileName(const char* aFileName) = 0;
//##Documentation
//## @brief Get the specified file prefix for the file(s) to load.
//##
//## You should specify either a FileName or FilePrefix. Use FilePrefix if
//## the data is stored in multiple files.
virtual const char* GetFilePrefix() const = 0;
//##Documentation
//## @brief Specify file prefix for the file(s) to load.
//##
//## You should specify either a FileName or FilePrefix. Use FilePrefix if
//## the data is stored in multiple files.
virtual void SetFilePrefix(const char* aFilePrefix) = 0;
//##Documentation
//## @brief Get the specified file pattern for the file(s) to load. The
//## sprintf format used to build filename from FilePrefix and number.
//##
//## You should specify either a FileName or FilePrefix. Use FilePrefix if
//## the data is stored in multiple files.
virtual const char* GetFilePattern() const = 0;
/**
@brief Specified file pattern for the file(s) to load. The sprintf
format used to build filename from FilePrefix and number.
You should specify either a FileName or FilePrefix. Use FilePrefix if
the data is stored in multiple files. */
virtual void SetFilePattern(const char* aFilePattern) = 0;
/**
@brief Specifies, whether the file reader also can
read a file from a memory buffer */
virtual bool CanReadFromMemory( );
/**
@brief Set/Get functions to advise the file reader to
use a memory array for reading a file*/
virtual void SetReadFromMemory( bool read );
virtual bool GetReadFromMemory( );
/**
@brief To be used along with a call of SetReadFromMemory(true). This sets
the memory buffer and the size from which the reader will read.*/
virtual void SetMemoryBuffer(const char* dataArray, unsigned int size);
protected:
FileReader();
virtual ~FileReader();
bool m_CanReadFromMemory;
bool m_ReadFromMemory;
const char* m_MemoryBuffer;
unsigned int m_MemorySize;
public:
protected:
};
} // namespace mitk
#endif /* FILEREADER_H_HEADER_INCLUDED_C1E7E521 */
diff --git a/Core/Code/IO/mitkFileSeriesReader.cpp b/Core/Code/IO/mitkFileSeriesReader.cpp
index b15277543f..f07a98df2a 100644
--- a/Core/Code/IO/mitkFileSeriesReader.cpp
+++ b/Core/Code/IO/mitkFileSeriesReader.cpp
@@ -1,257 +1,256 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkFileSeriesReader.h"
#include <itkImageFileReader.h>
#include <itksys/SystemTools.hxx>
#include <itksys/Directory.hxx>
#include <map>
bool mitk::FileSeriesReader::GenerateFileList()
{
typedef std::vector<std::string> StringContainer;
typedef std::map<unsigned int, std::string> SortedStringContainer;
if ( m_FileName == "" )
{
throw itk::ImageFileReaderException( __FILE__, __LINE__, "FileName must be non-empty" );
}
//MITK_INFO << "FileName: "<< m_FileName <<", FilePrefix: "<< m_FilePrefix << ", FilePattern: "<< m_FilePattern << std::endl;
// determine begin and end idexes of the last digit sequence in the
// filename from the sample file name
// Therefore, walk backwards from the end of the filename until
// a number is found. The string in front of the number is the prefix,
// the string after the number is the extension.
std::string basename, path;
path = itksys::SystemTools::GetFilenamePath( m_FileName );
basename = itksys::SystemTools::GetFilenameName( m_FileName );
unsigned int digitBegin = 0;
unsigned int digitEnd = 0;
bool digitFound = false;
for ( unsigned int i = basename.length() - 1; ; --i )
{
char character = basename[ i ];
if ( character >= '0' && character <= '9' )
{
if (!digitFound)
{
digitEnd = i;
digitBegin = i;
digitFound = true;
}
else
digitBegin = i;
}
else
{
//end of digit series found, jump out of loop!
if (digitFound)
break;
}
if ( i == 0 )
break;
}
//
// if there is no digit in the filename, then we have a problem
// no matching filenames can be identified!
//
if ( !digitFound )
{
itkWarningMacro("Filename contains no digit!");
return false;
}
//
// determine prefix and extension start and length
//
unsigned int prefixBegin = 0;
unsigned int prefixLength = digitBegin;
unsigned int extensionBegin = digitEnd + 1;
unsigned int extensionLength = (digitEnd == basename.length() -1 ? 0 : basename.length() - 1 - digitEnd);
unsigned int numberLength = digitEnd - digitBegin + 1;
//
// extract prefix and extension
//
std::string prefix = "";
if (prefixLength != 0)
prefix = basename.substr( prefixBegin, prefixLength );
std::string extension = "";
if (extensionLength != 0)
extension = basename.substr( extensionBegin, extensionLength );
//
// print debug information
//
/*
MITK_INFO << "digitBegin : " << digitBegin << std::endl;
MITK_INFO << "digitEnd : " << digitEnd << std::endl;
MITK_INFO << "number of digits: " << numberLength << std::endl;
MITK_INFO << "prefixBegin : " << prefixBegin << std::endl;
MITK_INFO << "prefixLength : " << prefixLength << std::endl;
MITK_INFO << "prefix : " << prefix << std::endl;
MITK_INFO << "extensionBegin : " << extensionBegin << std::endl;
MITK_INFO << "extensionLength : " << extensionLength << std::endl;
MITK_INFO << "extension : " << extension << std::endl;
*/
if( (prefixLength + extensionLength + numberLength) != basename.length() )
{
throw itk::ImageFileReaderException( __FILE__, __LINE__, "prefixLength + extensionLength + numberLength != basenameLength" );
}
//
// Load Directory
//
std::string directory = itksys::SystemTools::GetFilenamePath( m_FileName );
itksys::Directory itkDir;
if ( !itkDir.Load ( directory.c_str() ) )
{
itkWarningMacro ( << "Directory " << directory << " cannot be read!" );
return false;
}
//
// Get a list of all files in the directory
//
StringContainer unmatchedFiles;
//unsigned long i;
for ( unsigned long i = 0; i < itkDir.GetNumberOfFiles(); i++ )
{
// Only read files
std::string filename = directory + "/" + itkDir.GetFile( i );
if ( itksys::SystemTools::FileIsDirectory( filename.c_str() ) )
continue;
// store the filenames without path
unmatchedFiles.push_back( itkDir.GetFile( i ) );
}
//
// Match the file list against the file prefix and extension,
// the result should be only the files that should be read
//
StringContainer matchedFiles;
for ( StringContainer::iterator it = unmatchedFiles.begin() ; it != unmatchedFiles.end() ; ++it )
{
bool prefixMatch = false;
bool extensionMatch = false;
// check if the file prefix matches the current file
if ( prefixLength != 0 )
prefixMatch = ( it->find(prefix) == prefixBegin ); // check if prefix is found
else
prefixMatch = ( ( (*it)[0] >='0' ) && ( (*it)[0] <='9' ) ); //check if filename begins with digit
// check if the file extension matches the current file
if ( extensionLength != 0 )
extensionMatch = ( it->find(extension) == it->length() - extensionLength ); // check if prefix is found
else
extensionMatch = ( ( (*it)[it->length()-1] >='0' ) && ( (*it)[it->length()-1] <='9' ) ); //check if filename ends with digit
if ( prefixMatch && extensionMatch )
{
matchedFiles.push_back( *it );
}
}
if ( matchedFiles.size() == 0 )
{
itkWarningMacro( << "Sorry, none of the files matched the prefix!" );
return false;
}
//
// parse the file names from back to front for digits
// and convert them to a number. Store the filename and number
// in a SortedStringContainer
//
SortedStringContainer sortedFiles;
for ( StringContainer::iterator it = matchedFiles.begin() ; it != matchedFiles.end() ; ++it )
{
// parse the filename starting from pos digitBegin until we reach a non-digit
// or the end of filename
std::string number = "";
std::string currentFilename(*it);
for ( unsigned int i = digitBegin ; i < currentFilename.length() ; ++i)
{
char character = currentFilename[ i ];
//do we have a digit?
if ( character >= '0' && character <= '9' )
number += character;
else
break; //end of digit series found, jump out of loop!
}
if ( number.length() == 0 )
{
// The file is not numbered, this is an error!
// Nevertheless, we try the next files.
itkWarningMacro( << "The filename " << *it << "does not contain a valid digit sequence but matches prefix and extension. Skipping file!" );
}
else
{
if ( ( number.length() + prefix.length() + extension.length() ) != it->length() )
{
itkWarningMacro("The file "<< *it <<" matches prefix and extension, but the string in beteen is not a single digit-sequence. Skipping file!");
}
else
{
// convert the number string into an integer and
// insert the filname (including directory) into the SortedStringContainer
unsigned int num = atoi( number.c_str() );
sortedFiles.insert( std::make_pair( num, directory + "/" + *it ) );
}
}
}
if ( sortedFiles.size() == 0 )
{
itkWarningMacro( << "Sorry, no numbered files found, I can't load anything..." );
return false;
}
//
// Convert the sorted string container in a plain sorted vector of strings;
//
m_MatchedFileNames.clear();
m_MatchedFileNames.resize( sortedFiles.size() );
unsigned long index = 0;
for ( SortedStringContainer::iterator it = sortedFiles.begin() ; it != sortedFiles.end() ; ++it, ++index )
{
m_MatchedFileNames[ index ] = it->second ;
MITK_INFO << "Added " << it->second << " to the set of matched files!" << std::endl;
}
return true;
}
mitk::FileSeriesReader::MatchedFileNames mitk::FileSeriesReader::GetMatchedFileNames( )
{
return m_MatchedFileNames;
}
mitk::FileSeriesReader::FileSeriesReader()
: m_FileName( "" ), m_FilePrefix( "" ), m_FilePattern( "" )
{}
mitk::FileSeriesReader::~FileSeriesReader()
{
}
diff --git a/Core/Code/IO/mitkFileSeriesReader.h b/Core/Code/IO/mitkFileSeriesReader.h
index 8b941aaccb..1157604f3b 100644
--- a/Core/Code/IO/mitkFileSeriesReader.h
+++ b/Core/Code/IO/mitkFileSeriesReader.h
@@ -1,66 +1,65 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __MITK_FILE_SERIES_READER__H_
#define __MITK_FILE_SERIES_READER__H_
#include <MitkExports.h>
#include <mitkCommon.h>
#include <mitkFileReader.h>
#include <vector>
#include <string>
namespace mitk
{
/**
* Provides a function which generates a list of files from
* a given prefix and pattern.
* Subclasses may use this function to load a series of files.
*/
class MITK_CORE_EXPORT FileSeriesReader : public FileReader
{
public:
mitkClassMacro( FileSeriesReader, FileReader );
typedef std::vector< std::string > MatchedFileNames;
virtual MatchedFileNames GetMatchedFileNames( );
protected:
FileSeriesReader();
virtual ~FileSeriesReader();
virtual bool GenerateFileList();
std::string m_FileName;
std::string m_FilePrefix;
std::string m_FilePattern;
MatchedFileNames m_MatchedFileNames;
};
}
#endif
diff --git a/Core/Code/IO/mitkFileWriter.cpp b/Core/Code/IO/mitkFileWriter.cpp
index a1f4d6bd5e..7dfc8416b8 100644
--- a/Core/Code/IO/mitkFileWriter.cpp
+++ b/Core/Code/IO/mitkFileWriter.cpp
@@ -1,98 +1,97 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkFileWriter.h"
bool mitk::FileWriter::CanWriteDataType( DataNode* )
{
//TODO #345 check for writing permission
return false;
}
std::string mitk::FileWriter::GetWritenMIMEType()
{
return "";
}
void mitk::FileWriter::SetInput( DataNode* )
{
}
std::string mitk::FileWriter::GetFileExtension()
{
return "";
}
std::string mitk::FileWriter::GetPossibleFileExtensionsAsString()
{
std::vector<std::string> possibleFileExtensions = this->GetPossibleFileExtensions();
std::stringstream stream;
for (unsigned int i=0; i<possibleFileExtensions.size()-1; i++)
{
stream<<"*"<<possibleFileExtensions.at(i)<<" ";
}
stream<<"*"<<possibleFileExtensions.at(possibleFileExtensions.size()-1);
return stream.str();
}
bool mitk::FileWriter::IsExtensionValid(std::string extension)
{
std::vector<std::string> possibleFileExtensions = this->GetPossibleFileExtensions();
for (unsigned int i=0; i<possibleFileExtensions.size(); i++)
{
if (strcmp(extension.c_str(),possibleFileExtensions.at(i).c_str())==0)
return true;
}
return false;
}
mitk::FileWriter::FileWriter() :
m_CanWriteToMemory(false),
m_WriteToMemory(false)
{
}
mitk::FileWriter::~FileWriter()
{
}
bool mitk::FileWriter::CanWriteToMemory( )
{
return m_CanWriteToMemory;
}
void mitk::FileWriter::SetWriteToMemory( bool write )
{
m_WriteToMemory = write;
}
bool mitk::FileWriter::GetWriteToMemory( )
{
return m_WriteToMemory;
}
const char* mitk::FileWriter::GetMemoryPointer()
{
return (const char*) m_MemoryBuffer;
}
unsigned int mitk::FileWriter::GetMemorySize()
{
return m_MemoryBufferSize;
}
void mitk::FileWriter::ReleaseMemory()
{
// do nothing here
}
diff --git a/Core/Code/IO/mitkFileWriter.h b/Core/Code/IO/mitkFileWriter.h
index ae305d0e17..26f15e726e 100644
--- a/Core/Code/IO/mitkFileWriter.h
+++ b/Core/Code/IO/mitkFileWriter.h
@@ -1,166 +1,165 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 FILEWRITER_H_HEADER_INCLUDED
#define FILEWRITER_H_HEADER_INCLUDED
#include <MitkExports.h>
#include <itkProcessObject.h>
#include <mitkDataNode.h>
namespace mitk {
//##Documentation
//## @brief Interface class of writers that write data to files
//## @ingroup Process
class MITK_CORE_EXPORT FileWriter : public itk::ProcessObject
{
public:
mitkClassMacro(FileWriter,itk::ProcessObject);
//##Documentation
//## @brief Get the specified the file to write
//##
//## Either the FileName or FilePrefix plus FilePattern are used to write.
virtual const char* GetFileName() const = 0;
//##Documentation
//## @brief Specify the file to write.
//##
//## Either the FileName or FilePrefix plus FilePattern are used to write.
virtual void SetFileName(const char* aFileName) = 0;
//##Documentation
//## @brief Get the specified file prefix for the file(s) to write.
//##
//## You should specify either a FileName or FilePrefix. Use FilePrefix if
//## the data is stored in multiple files.
virtual const char* GetFilePrefix() const = 0;
//##Documentation
//## @brief Specify file prefix for the file(s) to write.
//##
//## You should specify either a FileName or FilePrefix. Use FilePrefix if
//## the data is stored in multiple files.
virtual void SetFilePrefix(const char* aFilePrefix) = 0;
//##Documentation
//## @brief Get the specified file pattern for the file(s) to write. The
//## sprintf format used to build filename from FilePrefix and number.
//##
//## You should specify either a FileName or FilePrefix. Use FilePrefix if
//## the data is stored in multiple files.
virtual const char* GetFilePattern() const = 0;
//##Documentation
//## @brief Specified file pattern for the file(s) to write. The sprintf
//## format used to build filename from FilePrefix and number.
//##
//## You should specify either a FileName or FilePrefix. Use FilePrefix if
//## the data is stored in multiple files.
virtual void SetFilePattern(const char* aFilePattern) = 0;
//##Documentation
//## @brief Return the extension to be added to the filename.
virtual std::string GetFileExtension();
//##Documentation
//## @brief Checks if given extension is valid for file writer
bool IsExtensionValid(std::string extension);
//##Documentation
//## @brief Return the possible file extensions for the data type associated with the writer
virtual std::vector<std::string> GetPossibleFileExtensions() = 0;
//##Documentation
//## @brief possible file extensions for the data type associated with the writer as string
virtual std::string GetPossibleFileExtensionsAsString();
//##Documentation
//## @brief Check if the Writer can write this type of data of the
//## DataTreenode.
virtual bool CanWriteDataType( DataNode* );
//##Documentation
//## @brief Return the MimeType of the saved File.
virtual std::string GetWritenMIMEType();
//##Documentation
//## @brief Set the DataTreenode as Input. Important: The Writer
//## always have a SetInput-Function.
virtual void SetInput( DataNode* );
virtual void Write() = 0;
/**
@brief Specifies, whether the file writer also can
write a file to a memory buffer */
virtual bool CanWriteToMemory( );
/**
@brief Set/Get functions to advise the file writer to
use tis internal memory array as file writing destination*/
virtual void SetWriteToMemory( bool write );
virtual bool GetWriteToMemory( );
/**
@brief To be used along with a call of SetWriteToMemory(true). This returns
the memory buffer where the file was written.*/
virtual const char* GetMemoryPointer();
/**
@brief To be used along with a call of SetWriteToMemory(true). This returns
the size of the memory buffer where the file was written.*/
virtual unsigned int GetMemorySize();
/**
@brief CAUTION: It's up to the user to call this function to release the
memory buffer after use in case the file writer has written to its memory array.*/
virtual void ReleaseMemory();
protected:
FileWriter();
virtual ~FileWriter();
bool m_CanWriteToMemory;
bool m_WriteToMemory;
char * m_MemoryBuffer;
unsigned int m_MemoryBufferSize;
};
#define mitkWriterMacro \
virtual void Write() \
{ \
if ( this->GetInput() == NULL ) \
{ \
itkExceptionMacro(<<"Write:Please specify an input!"); \
return; \
} \
/* Fill in image information.*/ \
this->UpdateOutputInformation(); \
(*(this->GetInputs().begin()))->SetRequestedRegionToLargestPossibleRegion();\
this->PropagateRequestedRegion(NULL); \
this->UpdateOutputData(NULL); \
} \
\
virtual void Update() \
{ \
Write(); \
}
} // namespace mitk
#endif /* FILEWRITER_H_HEADER_INCLUDED */
diff --git a/Core/Code/IO/mitkFileWriterWithInformation.h b/Core/Code/IO/mitkFileWriterWithInformation.h
index 9cfd05c8d9..2bd74ad220 100644
--- a/Core/Code/IO/mitkFileWriterWithInformation.h
+++ b/Core/Code/IO/mitkFileWriterWithInformation.h
@@ -1,42 +1,41 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 FILEWRITERWITHINFORMATION_H_INCLUDED
#define FILEWRITERWITHINFORMATION_H_INCLUDED
#include "mitkFileWriter.h"
#include "mitkBaseData.h"
namespace mitk {
/**
* \brief Interface for FileWriters with extra information.
* Should be merged into FileWriter.
*/
class MITK_CORE_EXPORT FileWriterWithInformation : public FileWriter {
public:
mitkClassMacro(FileWriterWithInformation,FileWriter);
virtual const char *GetDefaultFilename() = 0;
virtual const char *GetFileDialogPattern() = 0;
virtual const char *GetDefaultExtension() = 0;
virtual bool CanWriteBaseDataType(BaseData::Pointer data) = 0;
virtual void DoWrite(BaseData::Pointer data) = 0;
};
}
#endif
diff --git a/Core/Code/IO/mitkIOAdapter.h b/Core/Code/IO/mitkIOAdapter.h
index d06a7fc499..abfc104139 100644
--- a/Core/Code/IO/mitkIOAdapter.h
+++ b/Core/Code/IO/mitkIOAdapter.h
@@ -1,94 +1,93 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkIOAdapter_h
#define __mitkIOAdapter_h
#include "mitkBaseProcess.h"
#include "itkObject.h"
namespace mitk
{
//##Documentation
//## @brief IOAdapterBase class is an abstract adapter class for IO process objects.
//##
//## @ingroup IO
class MITK_CORE_EXPORT IOAdapterBase: public itk::Object
{
public:
/** Standard typedefs. */
typedef IOAdapterBase Self;
typedef itk::Object Superclass;
typedef itk::SmartPointer<Self>Pointer;
typedef itk::SmartPointer<const Self>ConstPointer;
/// Create an object and return a pointer to it as a mitk::BaseProcess.
virtual itk::SmartPointer<BaseProcess> CreateIOProcessObject(const std::string filename, const std::string filePrefix, const std::string filePattern) = 0;
virtual bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern) = 0;
protected:
IOAdapterBase() {}
~IOAdapterBase() {}
private:
IOAdapterBase(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
//##Documentation
//## @brief IOAdapter class is an adapter class for instantiation of IO process objects.
//## Additional this interface defines the function CanReadFile().
//## This interface allows the target (object) the access to the adaptee (IO process object).
//## @ingroup IO
template <class T>
class IOAdapter : public IOAdapterBase
{
public:
/** Standard class typedefs. */
typedef IOAdapter Self;
typedef itk::SmartPointer<Self> Pointer;
/** Methods from mitk::BaseProcess. */
itkFactorylessNewMacro(Self);
mitk::BaseProcess::Pointer CreateIOProcessObject(const std::string filename, const std::string filePrefix, const std::string filePattern)
{
typename T::Pointer ioProcessObject = T::New();
ioProcessObject->SetFileName(filename.c_str());
ioProcessObject->SetFilePrefix(filePrefix.c_str());
ioProcessObject->SetFilePattern(filePattern.c_str());
return ioProcessObject.GetPointer();
}
virtual bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern)
{
return T::CanReadFile(filename, filePrefix, filePattern);
}
protected:
IOAdapter() {}
~IOAdapter() {}
private:
IOAdapter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkIOUtil.cpp b/Core/Code/IO/mitkIOUtil.cpp
index e9cc3ff452..77e54ca469 100644
--- a/Core/Code/IO/mitkIOUtil.cpp
+++ b/Core/Code/IO/mitkIOUtil.cpp
@@ -1,87 +1,86 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkIOUtil.h"
#include <mitkGetModuleContext.h>
#include <mitkModuleContext.h>
#include <mitkStandaloneDataStorage.h>
#include <mitkIDataNodeReader.h>
#include <mitkProgressBar.h>
namespace mitk {
int IOUtil::LoadFiles(const std::vector<std::string> &fileNames, DataStorage &ds)
{
// Get the set of registered mitk::IDataNodeReader services
ModuleContext* context = GetModuleContext();
const std::list<ServiceReference> refs = context->GetServiceReferences<IDataNodeReader>();
std::vector<IDataNodeReader*> services;
services.reserve(refs.size());
for (std::list<ServiceReference>::const_iterator i = refs.begin();
i != refs.end(); ++i)
{
IDataNodeReader* s = context->GetService<IDataNodeReader>(*i);
if (s != 0)
{
services.push_back(s);
}
}
mitk::ProgressBar::GetInstance()->AddStepsToDo(2*fileNames.size());
// Iterate over all file names and use the IDataNodeReader services
// to load them.
int nodesRead = 0;
for (std::vector<std::string>::const_iterator i = fileNames.begin();
i != fileNames.end(); ++i)
{
for (std::vector<IDataNodeReader*>::const_iterator readerIt = services.begin();
readerIt != services.end(); ++readerIt)
{
try
{
int n = (*readerIt)->Read(*i, ds);
nodesRead += n;
if (n > 0) break;
}
catch (const std::exception& e)
{
MITK_WARN << e.what();
}
}
mitk::ProgressBar::GetInstance()->Progress(2);
}
for (std::list<ServiceReference>::const_iterator i = refs.begin();
i != refs.end(); ++i)
{
context->UngetService(*i);
}
return nodesRead;
}
DataStorage::Pointer IOUtil::LoadFiles(const std::vector<std::string>& fileNames)
{
mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New();
LoadFiles(fileNames, *ds);
return ds.GetPointer();
}
}
diff --git a/Core/Code/IO/mitkIOUtil.h b/Core/Code/IO/mitkIOUtil.h
index c9f087ac09..8451e6675c 100644
--- a/Core/Code/IO/mitkIOUtil.h
+++ b/Core/Code/IO/mitkIOUtil.h
@@ -1,68 +1,67 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKIOUTIL_H
#define MITKIOUTIL_H
#include <MitkExports.h>
#include <mitkDataStorage.h>
namespace mitk {
/**
* \ingroup IO
*
* \brief A utility class to load data from the local file system into a mitk::DataStorage.
*
* This class queries the MITK Micro Services registry for registered mitk::IDataNodeReader service
* instances. The service instance with the highest ranking will be asked first to load the
* given file. On error (exception thrown) or if no mitk::DataNode was constructed, the next
* service instance is used.
*
* \see mitk::IDataNodeReader
*/
class MITK_CORE_EXPORT IOUtil
{
public:
/**
* Load a files in <code>fileNames</code> and add the constructed mitk::DataNode instances
* to the mitk::DataStorage <code>storage</code>
*
* \param fileNames A list (vector) of absolute file name paths.
* \param storage The data storage to which the constructed data nodes are added.
* \return The number of added mitk::DataNode instances.
*/
static int LoadFiles(const std::vector<std::string>&fileNames, DataStorage& storage);
/**
* This method will create a new mitk::DataStorage instance and pass it to
* LoadFiles(std::vector<std::string>,DataStorage).
*
* \param fileNames A list (vector) of absolute file name paths.
* \return The new mitk::DataStorage containing the constructed data nodes.
*
* \see LoadFiles(std::vector<std::string>,DataStorage)
*/
static DataStorage::Pointer LoadFiles(const std::vector<std::string>& fileNames);
};
}
#endif // MITKIOUTIL_H
diff --git a/Core/Code/IO/mitkImageGenerator.cpp b/Core/Code/IO/mitkImageGenerator.cpp
index ae33022a75..970cfe5a27 100644
--- a/Core/Code/IO/mitkImageGenerator.cpp
+++ b/Core/Code/IO/mitkImageGenerator.cpp
@@ -1,10 +1,15 @@
-/*=========================================================================
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+/*===================================================================
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
+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.
+
+===================================================================*/
diff --git a/Core/Code/IO/mitkImageGenerator.h b/Core/Code/IO/mitkImageGenerator.h
index 516e2d963b..16b4e0e0b4 100644
--- a/Core/Code/IO/mitkImageGenerator.h
+++ b/Core/Code/IO/mitkImageGenerator.h
@@ -1,110 +1,115 @@
-/*=========================================================================
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+/*===================================================================
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
+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 ImageGenerator_H_HEADER_INCLUDED
#define ImageGenerator_H_HEADER_INCLUDED
#include <MitkExports.h>
#include <mitkImage.h>
#include <itkMersenneTwisterRandomVariateGenerator.h>
namespace mitk {
//##Documentation
//## @brief generator for random MITK images
//## This is a helper class to generate MITK images filled with random values.
//## The parameters dimX, dimY, dimZ, and dimT are used to set the dimensions of the MITK image.
//## Default parameters are dimT = 1 and dimZ = 1 which is a 2D image (or a 4D image with just 1 slice and 1 time step).
//## The parameters randomMax and randomMin are boundary values for the random generator.
//## In other words: the generator will generate values between randomMin and randomMax.
//## @ingroup IO
class MITK_CORE_EXPORT ImageGenerator
{
public:
template <typename TPixelType>
static mitk::Image::Pointer GenerateRandomImage(unsigned int dimX,
unsigned int dimY,
unsigned int dimZ = 1,
unsigned int dimT = 1,
const double randomMax = 1000.0f, const double randMin = 0.0f)
{
//set the data type according to the template
mitk::PixelType type = MakeScalarPixelType<TPixelType>();
//type.Initialize(typeid(TPixelType));
//initialize the MITK image with given dimenion and data type
mitk::Image::Pointer output = mitk::Image::New();
unsigned int* dimensions = new unsigned int[4];
unsigned int numberOfDimensions = 0;
unsigned int bufferSize = 0;
//check which dimension is needed
if(dimT <= 1)
{
if(dimZ <= 1)
{ //2D
numberOfDimensions = 2;
dimensions[0] = dimX;
dimensions[1] = dimY;
bufferSize = dimX*dimY;
}
else
{ //3D
numberOfDimensions = 3;
dimensions[0] = dimX;
dimensions[1] = dimY;
dimensions[2] = dimZ;
bufferSize = dimX*dimY*dimZ;
}
}
else
{ //4D
numberOfDimensions = 4;
dimensions[0] = dimX;
dimensions[1] = dimY;
dimensions[2] = dimZ;
dimensions[3] = dimT;
bufferSize = dimX*dimY*dimZ*dimT;
}
output->Initialize(type, numberOfDimensions, dimensions);
//get a pointer to the image buffer to write into
TPixelType* imageBuffer = (TPixelType*)output->GetData();
//initialize the random generator
itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randomGenerator = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
randomGenerator->Initialize();
//fill the buffer for each pixel/voxel
for(unsigned int i = 0; i < bufferSize; i++)
{
if(type == typeid(int)) //call integer function
{
imageBuffer[i] = (TPixelType)randomGenerator->GetIntegerVariate((int)randomMax);
//TODO random generator does not support integer values in a given range (e.g. from 5-10)
//range is always [0, (int)randomMax]
}else if((type == typeid(double)) || (type == typeid(float))) //call integer function
{
imageBuffer[i] = (TPixelType)randomGenerator->GetUniformVariate(randMin,randomMax);
}else if(type == typeid(unsigned char))
{
//use the integer randomGenerator with mod 256 to generate unsigned char values
imageBuffer[i] = (unsigned char) ((int)randomGenerator->GetIntegerVariate((int)randomMax)) % 256;
}else{
MITK_ERROR << "Datatype not supported yet.";
//TODO call different methods for other datatypes
}
}
return output;
}
};
} // namespace mitk
#endif /* ImageGenerator_H_HEADER_INCLUDED */
diff --git a/Core/Code/IO/mitkImageWriter.cpp b/Core/Code/IO/mitkImageWriter.cpp
index 522f5da51a..9bb017268a 100644
--- a/Core/Code/IO/mitkImageWriter.cpp
+++ b/Core/Code/IO/mitkImageWriter.cpp
@@ -1,335 +1,334 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageWriter.h"
#include "mitkItkPictureWrite.h"
#include "mitkImage.h"
#include "mitkImageTimeSelector.h"
#include "mitkImageAccessByItk.h"
#include <itkImageIOBase.h>
#include <itkImageIOFactory.h>
mitk::ImageWriter::ImageWriter()
{
this->SetNumberOfRequiredInputs( 1 );
m_MimeType = "";
SetDefaultExtension();
}
mitk::ImageWriter::~ImageWriter()
{
}
void mitk::ImageWriter::SetDefaultExtension()
{
m_Extension = ".mhd";
}
#include <vtkConfigure.h>
#include <vtkImageData.h>
#include <vtkXMLImageDataWriter.h>
static void writeVti(const char * filename, mitk::Image* image, int t=0)
{
vtkXMLImageDataWriter * vtkwriter = vtkXMLImageDataWriter::New();
vtkwriter->SetFileName( filename );
vtkwriter->SetInput(image->GetVtkImageData(t));
vtkwriter->Write();
vtkwriter->Delete();
}
void mitk::ImageWriter::WriteByITK(mitk::Image* image, const std::string& fileName)
{
// Pictures and picture series like .png are written via a different mechanism then volume images.
// So, they are still multiplexed and thus not support vector images.
if (fileName.find(".png") != std::string::npos || fileName.find(".tif") != std::string::npos || fileName.find(".jpg") != std::string::npos)
{
AccessByItk_1( image, _mitkItkPictureWrite, fileName );
return;
}
// Implementation of writer using itkImageIO directly. This skips the use
// of templated itkImageFileWriter, which saves the multiplexing on MITK side.
unsigned int dimension = image->GetDimension();
unsigned int* dimensions = image->GetDimensions();
mitk::PixelType pixelType = image->GetPixelType();
mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
mitk::Point3D origin = image->GetGeometry()->GetOrigin();
itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fileName.c_str(),
itk::ImageIOFactory::WriteMode );
if(imageIO.IsNull())
{
itkExceptionMacro(<< "Error: Could not create itkImageIO via factory for file " << fileName);
}
// Set the necessary information for imageIO
imageIO->SetNumberOfDimensions(dimension);
imageIO->SetPixelTypeInfo( pixelType.GetTypeId() );
if(pixelType.GetNumberOfComponents() > 1)
imageIO->SetNumberOfComponents(pixelType.GetNumberOfComponents());
itk::ImageIORegion ioRegion( dimension );
for(unsigned int i=0; i<dimension; i++)
{
imageIO->SetDimensions(i,dimensions[i]);
imageIO->SetSpacing(i,spacing[i]);
imageIO->SetOrigin(i,origin[i]);
mitk::Vector3D direction;
direction.Set_vnl_vector(image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i));
vnl_vector< double > axisDirection(dimension);
for(unsigned int j=0; j<dimension; j++)
{
axisDirection[j] = direction[j]/spacing[i];
}
imageIO->SetDirection( i, axisDirection );
ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i) );
ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i) );
}
//use compression if available
imageIO->UseCompressionOn();
imageIO->SetIORegion(ioRegion);
imageIO->SetFileName(fileName);
const void * data = image->GetData();
imageIO->Write(data);
}
void mitk::ImageWriter::GenerateData()
{
const std::string& locale = "C";
const std::string& currLocale = setlocale( LC_ALL, NULL );
if ( locale.compare(currLocale)!=0 )
{
try
{
setlocale(LC_ALL, locale.c_str());
}
catch(...)
{
MITK_INFO << "Could not set locale " << locale;
}
}
if ( m_FileName == "" )
{
itkWarningMacro( << "Sorry, filename has not been set!" );
return ;
}
FILE* tempFile = fopen(m_FileName.c_str(),"w");
if (tempFile==NULL)
{
itkExceptionMacro(<<"File location not writeable");
return;
}
fclose(tempFile);
remove(m_FileName.c_str());
mitk::Image::Pointer input = const_cast<mitk::Image*>(this->GetInput());
bool vti = (m_Extension.find(".vti") != std::string::npos);
// If the extension is NOT .pic and NOT .nrrd and NOT .nii and NOT .nii.gz the following block is entered
if ( m_Extension.find(".pic") == std::string::npos
&& m_Extension.find(".nrrd") == std::string::npos
&& m_Extension.find(".nii") == std::string::npos
&& m_Extension.find(".nii.gz") == std::string::npos
)
{
if(input->GetDimension() > 3)
{
int t, timesteps;
timesteps = input->GetDimension(3);
ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
timeSelector->SetInput(input);
mitk::Image::Pointer image = timeSelector->GetOutput();
for(t = 0; t < timesteps; ++t)
{
::itk::OStringStream filename;
timeSelector->SetTimeNr(t);
timeSelector->Update();
if(input->GetTimeSlicedGeometry()->IsValidTime(t))
{
const mitk::TimeBounds& timebounds = input->GetTimeSlicedGeometry()->GetGeometry3D(t)->GetTimeBounds();
filename << m_FileName.c_str() << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << m_Extension;
}
else
{
itkWarningMacro(<<"Error on write: TimeSlicedGeometry invalid of image " << filename << ".");
filename << m_FileName.c_str() << "_T" << t << m_Extension;
}
if ( vti )
{
writeVti(filename.str().c_str(), input, t);
}
else
{
WriteByITK(image, filename.str());
}
}
}
else if ( vti )
{
::itk::OStringStream filename;
filename << m_FileName.c_str() << m_Extension;
writeVti(filename.str().c_str(), input);
}
else
{
::itk::OStringStream filename;
filename << m_FileName.c_str() << m_Extension;
WriteByITK(input, filename.str());
}
}
else
{
// use the PicFileWriter for the .pic data type
if( m_Extension.find(".pic") != std::string::npos )
{
/* PicFileWriter::Pointer picWriter = PicFileWriter::New();
size_t found;
found = m_FileName.find( m_Extension ); // !!! HAS to be at the very end of the filename (not somewhere in the middle)
if( m_FileName.length() > 3 && found != m_FileName.length() - 4 )
{
//if Extension not in Filename
::itk::OStringStream filename;
filename << m_FileName.c_str() << m_Extension;
picWriter->SetFileName( filename.str().c_str() );
}
else
{
picWriter->SetFileName( m_FileName.c_str() );
}
picWriter->SetInputImage( input );
picWriter->Write();
*/ }
// use the ITK .nrrd Image writer
if( m_Extension.find(".nrrd") != std::string::npos
|| m_Extension.find(".nii") != std::string::npos
|| m_Extension.find(".nii.gz") != std::string::npos
)
{
::itk::OStringStream filename;
filename << this->m_FileName.c_str() << this->m_Extension;
WriteByITK(input, filename.str());
}
}
m_MimeType = "application/MITK.Pic";
try
{
setlocale(LC_ALL, currLocale.c_str());
}
catch(...)
{
MITK_INFO << "Could not reset locale " << currLocale;
}
}
bool mitk::ImageWriter::CanWriteDataType( DataNode* input )
{
if ( input )
{
mitk::BaseData* data = input->GetData();
if ( data )
{
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>( data );
if( image.IsNotNull() )
{
//"SetDefaultExtension()" set m_Extension to ".mhd" ?????
m_Extension = ".pic";
return true;
}
}
}
return false;
}
void mitk::ImageWriter::SetInput( DataNode* input )
{
if( input && CanWriteDataType( input ) )
this->ProcessObject::SetNthInput( 0, dynamic_cast<mitk::Image*>( input->GetData() ) );
}
std::string mitk::ImageWriter::GetWritenMIMEType()
{
return m_MimeType;
}
std::vector<std::string> mitk::ImageWriter::GetPossibleFileExtensions()
{
std::vector<std::string> possibleFileExtensions;
possibleFileExtensions.push_back(".pic");
possibleFileExtensions.push_back(".bmp");
possibleFileExtensions.push_back(".dcm");
possibleFileExtensions.push_back(".DCM");
possibleFileExtensions.push_back(".dicom");
possibleFileExtensions.push_back(".DICOM");
possibleFileExtensions.push_back(".gipl");
possibleFileExtensions.push_back(".gipl.gz");
possibleFileExtensions.push_back(".mha");
possibleFileExtensions.push_back(".nii");
possibleFileExtensions.push_back(".nrrd");
possibleFileExtensions.push_back(".nhdr");
possibleFileExtensions.push_back(".png");
possibleFileExtensions.push_back(".PNG");
possibleFileExtensions.push_back(".spr");
possibleFileExtensions.push_back(".mhd");
possibleFileExtensions.push_back(".vtk");
possibleFileExtensions.push_back(".vti");
possibleFileExtensions.push_back(".hdr");
possibleFileExtensions.push_back(".png");
possibleFileExtensions.push_back(".tif");
possibleFileExtensions.push_back(".jpg");
return possibleFileExtensions;
}
std::string mitk::ImageWriter::GetFileExtension()
{
return m_Extension;
}
void mitk::ImageWriter::SetInput( mitk::Image* image )
{
this->ProcessObject::SetNthInput( 0, image );
}
const mitk::Image* mitk::ImageWriter::GetInput()
{
if ( this->GetNumberOfInputs() < 1 )
{
return NULL;
}
else
{
return static_cast< const mitk::Image * >( this->ProcessObject::GetInput( 0 ) );
}
}
diff --git a/Core/Code/IO/mitkImageWriter.h b/Core/Code/IO/mitkImageWriter.h
index 89d691c9ee..bd892f33b6 100644
--- a/Core/Code/IO/mitkImageWriter.h
+++ b/Core/Code/IO/mitkImageWriter.h
@@ -1,159 +1,158 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_IMAGE_WRITER__H_
#define _MITK_IMAGE_WRITER__H_
#include <mitkFileWriter.h>
namespace mitk
{
class Image;
/**
* @brief Writer for mitk::Image
*
* Uses the given extension (SetExtension) to decide the format to write
* (.mhd is default, .pic, .tif, .png, .jpg supported yet).
* @ingroup IO
*/
class MITK_CORE_EXPORT ImageWriter : public mitk::FileWriter
{
public:
mitkClassMacro( ImageWriter, mitk::FileWriter );
itkNewMacro( Self );
mitkWriterMacro;
/**
* Sets the filename of the file to write.
* @param _arg the name of the file to write.
*/
itkSetStringMacro( FileName );
/**
* @returns the name of the file to be written to disk.
*/
itkGetStringMacro( FileName );
/**
* \brief Explicitly set the extension to be added to the filename.
* @param _arg to be added to the filename, including a "."
* (e.g., ".mhd").
*/
itkSetStringMacro( Extension );
/**
* \brief Get the extension to be added to the filename.
* @returns the extension to be added to the filename (e.g.,
* ".mhd").
*/
itkGetStringMacro( Extension );
/**
* \brief Set the extension to be added to the filename to the default
*/
void SetDefaultExtension();
/**
* @warning multiple write not (yet) supported
*/
itkSetStringMacro( FilePrefix );
/**
* @warning multiple write not (yet) supported
*/
itkGetStringMacro( FilePrefix );
/**
* @warning multiple write not (yet) supported
*/
itkSetStringMacro( FilePattern );
/**
* @warning multiple write not (yet) supported
*/
itkGetStringMacro( FilePattern );
/**
* Sets the 0'th input object for the filter.
* @param input the first input for the filter.
*/
void SetInput( mitk::Image* input );
//##Documentation
//## @brief Return the possible file extensions for the data type associated with the writer
virtual std::vector<std::string> GetPossibleFileExtensions();
/**
* @brief Return the extension to be added to the filename.
*/
virtual std::string GetFileExtension();
/**
* @brief Check if the Writer can write the Content of the
*/
virtual bool CanWriteDataType( DataNode* );
/**
* @brief Return the MimeType of the saved File.
*/
virtual std::string GetWritenMIMEType();
/**
* @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function.
*/
virtual void SetInput( DataNode* );
/**
* @returns the 0'th input object of the filter.
*/
const mitk::Image* GetInput();
protected:
/**
* Constructor.
*/
ImageWriter();
/**
* Virtual destructor.
*/
virtual ~ImageWriter();
virtual void GenerateData();
virtual void WriteByITK(mitk::Image* image, const std::string& fileName);
std::string m_FileName;
std::string m_FilePrefix;
std::string m_FilePattern;
std::string m_Extension;
std::string m_MimeType;
};
}
#endif //_MITK_IMAGE_WRITER__H_
diff --git a/Core/Code/IO/mitkImageWriterFactory.cpp b/Core/Code/IO/mitkImageWriterFactory.cpp
index b1ff0e915f..a09f2d2fce 100644
--- a/Core/Code/IO/mitkImageWriterFactory.cpp
+++ b/Core/Code/IO/mitkImageWriterFactory.cpp
@@ -1,77 +1,76 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageWriterFactory.h"
#include "itkCreateObjectFunction.h"
#include "itkVersion.h"
#include "mitkImageWriter.h"
namespace mitk
{
template <class T>
class CreateImageWriter : public itk::CreateObjectFunctionBase
{
public:
/** Standard class typedefs. */
typedef CreateImageWriter Self;
typedef itk::SmartPointer<Self> Pointer;
/** Methods from itk:LightObject. */
itkFactorylessNewMacro(Self);
LightObject::Pointer CreateObject() { typename T::Pointer p = T::New();
p->Register();
return p.GetPointer();
}
protected:
CreateImageWriter() {}
~CreateImageWriter() {}
private:
CreateImageWriter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
ImageWriterFactory::ImageWriterFactory()
{
this->RegisterOverride("IOWriter",
"ImageWriter",
"Image Writer",
1,
mitk::CreateImageWriter<mitk::ImageWriter>::New());
}
ImageWriterFactory::~ImageWriterFactory()
{
}
const char* ImageWriterFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* ImageWriterFactory::GetDescription() const
{
return "ImageWriterFactory";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkImageWriterFactory.h b/Core/Code/IO/mitkImageWriterFactory.h
index 7a751ba0e9..b84e64fc85 100644
--- a/Core/Code/IO/mitkImageWriterFactory.h
+++ b/Core/Code/IO/mitkImageWriterFactory.h
@@ -1,64 +1,63 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 IMAGEWRITERFACTORY_H_HEADER_INCLUDED
#define IMAGEWRITERFACTORY_H_HEADER_INCLUDED
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
class MITK_CORE_EXPORT ImageWriterFactory : public itk::ObjectFactoryBase
{
public:
mitkClassMacro( mitk::ImageWriterFactory, itk::ObjectFactoryBase )
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
static bool IsRegistered = false;
if ( !IsRegistered )
{
ImageWriterFactory::Pointer imageWriterFactory = ImageWriterFactory::New();
ObjectFactoryBase::RegisterFactory( imageWriterFactory );
IsRegistered = true;
}
}
protected:
ImageWriterFactory();
~ImageWriterFactory();
private:
ImageWriterFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkItkImageFileIOFactory.cpp b/Core/Code/IO/mitkItkImageFileIOFactory.cpp
index 233650e9d7..fe25ac07ce 100644
--- a/Core/Code/IO/mitkItkImageFileIOFactory.cpp
+++ b/Core/Code/IO/mitkItkImageFileIOFactory.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkItkImageFileIOFactory.h"
#include "mitkIOAdapter.h"
#include "mitkItkImageFileReader.h"
#include "itkVersion.h"
namespace mitk
{
ItkImageFileIOFactory::ItkImageFileIOFactory()
{
this->RegisterOverride("mitkIOAdapter",
"mitkItkImageFileReader",
"itk Image IO",
1,
itk::CreateObjectFunction<IOAdapter<ItkImageFileReader> >::New());
}
ItkImageFileIOFactory::~ItkImageFileIOFactory()
{
}
const char* ItkImageFileIOFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* ItkImageFileIOFactory::GetDescription() const
{
return "ItkImageFile IO Factory, allows the loading of images supported by ITK";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkItkImageFileIOFactory.h b/Core/Code/IO/mitkItkImageFileIOFactory.h
index da58ae88e3..cd725f7709 100644
--- a/Core/Code/IO/mitkItkImageFileIOFactory.h
+++ b/Core/Code/IO/mitkItkImageFileIOFactory.h
@@ -1,72 +1,71 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkItkImageFileIOFactory_h
#define __mitkItkImageFileIOFactory_h
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
//##Documentation
//## @brief Create instances of ItkImageFileReader objects using an object factory.
//##
//## @ingroup IO
class MITK_CORE_EXPORT ItkImageFileIOFactory : public itk::ObjectFactoryBase
{
public:
/** Standard class typedefs. */
typedef ItkImageFileIOFactory Self;
typedef itk::ObjectFactoryBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
static ItkImageFileIOFactory* FactoryNew() { return new ItkImageFileIOFactory;}
/** Run-time type information (and related methods). */
itkTypeMacro(ItkImageFileIOFactory, ObjectFactoryBase);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
ItkImageFileIOFactory::Pointer ItkImageFileIOFactory = ItkImageFileIOFactory::New();
ObjectFactoryBase::RegisterFactory(ItkImageFileIOFactory);
}
protected:
ItkImageFileIOFactory();
~ItkImageFileIOFactory();
private:
ItkImageFileIOFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkItkImageFileReader.cpp b/Core/Code/IO/mitkItkImageFileReader.cpp
index 050c3ac206..5c980b56e2 100644
--- a/Core/Code/IO/mitkItkImageFileReader.cpp
+++ b/Core/Code/IO/mitkItkImageFileReader.cpp
@@ -1,213 +1,212 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkItkImageFileReader.h"
#include "mitkConfig.h"
#include <itkImageFileReader.h>
#include <itksys/SystemTools.hxx>
#include <itksys/Directory.hxx>
#include <itkImage.h>
//#include <itkImageSeriesReader.h>
#include <itkImageFileReader.h>
#include <itkImageIOFactory.h>
#include <itkImageIORegion.h>
//#include <itkImageSeriesReader.h>
//#include <itkDICOMImageIO2.h>
//#include <itkDICOMSeriesFileNames.h>
//#include <itkGDCMImageIO.h>
//#include <itkGDCMSeriesFileNames.h>
//#include <itkNumericSeriesFileNames.h>
void mitk::ItkImageFileReader::GenerateData()
{
const std::string& locale = "C";
const std::string& currLocale = setlocale( LC_ALL, NULL );
if ( locale.compare(currLocale)!=0 )
{
try
{
setlocale(LC_ALL, locale.c_str());
}
catch(...)
{
MITK_INFO << "Could not set locale " << locale;
}
}
mitk::Image::Pointer image = this->GetOutput();
const unsigned int MINDIM = 2;
const unsigned int MAXDIM = 4;
MITK_INFO << "loading " << m_FileName << " via itk::ImageIOFactory... " << std::endl;
// Check to see if we can read the file given the name or prefix
if ( m_FileName == "" )
{
itkWarningMacro( << "File Type not supported!" );
return ;
}
itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( m_FileName.c_str(), itk::ImageIOFactory::ReadMode );
if ( imageIO.IsNull() )
{
itkWarningMacro( << "File Type not supported!" );
return ;
}
// Got to allocate space for the image. Determine the characteristics of
// the image.
imageIO->SetFileName( m_FileName.c_str() );
imageIO->ReadImageInformation();
unsigned int ndim = imageIO->GetNumberOfDimensions();
if ( ndim < MINDIM || ndim > MAXDIM )
{
itkWarningMacro( << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim << " dimensions! Reading as 4D." );
ndim = MAXDIM;
}
itk::ImageIORegion ioRegion( ndim );
itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize();
itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex();
unsigned int dimensions[ MAXDIM ];
dimensions[ 0 ] = 0;
dimensions[ 1 ] = 0;
dimensions[ 2 ] = 0;
dimensions[ 3 ] = 0;
float spacing[ MAXDIM ];
spacing[ 0 ] = 1.0f;
spacing[ 1 ] = 1.0f;
spacing[ 2 ] = 1.0f;
spacing[ 3 ] = 1.0f;
Point3D origin;
origin.Fill(0);
unsigned int i;
for ( i = 0; i < ndim ; ++i )
{
ioStart[ i ] = 0;
ioSize[ i ] = imageIO->GetDimensions( i );
if(i<MAXDIM)
{
dimensions[ i ] = imageIO->GetDimensions( i );
spacing[ i ] = imageIO->GetSpacing( i );
if(spacing[ i ] <= 0)
spacing[ i ] = 1.0f;
}
if(i<3)
{
origin[ i ] = imageIO->GetOrigin( i );
}
}
ioRegion.SetSize( ioSize );
ioRegion.SetIndex( ioStart );
MITK_INFO << "ioRegion: " << ioRegion << std::endl;
imageIO->SetIORegion( ioRegion );
void* buffer = new unsigned char[imageIO->GetImageSizeInBytes()];
imageIO->Read( buffer );
//mitk::Image::Pointer image = mitk::Image::New();
if((ndim==4) && (dimensions[3]<=1))
ndim = 3;
if((ndim==3) && (dimensions[2]<=1))
ndim = 2;
mitk::PixelType pixelType = mitk::PixelType(imageIO->GetComponentTypeInfo(), imageIO->GetComponentTypeInfo(),
imageIO->GetComponentSize(), imageIO->GetNumberOfComponents(),
imageIO->GetComponentTypeAsString( imageIO->GetComponentType() ).c_str(),
imageIO->GetPixelTypeAsString( imageIO->GetPixelType() ).c_str() );
image->Initialize( pixelType, ndim, dimensions );
image->SetImportChannel( buffer, 0, Image::ManageMemory );
// access direction of itk::Image and include spacing
mitk::Matrix3D matrix;
matrix.SetIdentity();
unsigned int j, itkDimMax3 = (ndim >= 3? 3 : ndim);
for ( i=0; i < itkDimMax3; ++i)
for( j=0; j < itkDimMax3; ++j )
matrix[i][j] = imageIO->GetDirection(j)[i];
// re-initialize PlaneGeometry with origin and direction
PlaneGeometry* planeGeometry = static_cast<PlaneGeometry*>(image->GetSlicedGeometry(0)->GetGeometry2D(0));
planeGeometry->SetOrigin(origin);
planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix);
// re-initialize SlicedGeometry3D
SlicedGeometry3D* slicedGeometry = image->GetSlicedGeometry(0);
slicedGeometry->InitializeEvenlySpaced(planeGeometry, image->GetDimension(2));
slicedGeometry->SetSpacing(spacing);
// re-initialize TimeSlicedGeometry
image->GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, image->GetDimension(3));
buffer = NULL;
MITK_INFO << "number of image components: "<< image->GetPixelType().GetNumberOfComponents() << std::endl;
// mitk::DataNode::Pointer node = this->GetOutput();
// node->SetData( image );
// add level-window property
//if ( image->GetPixelType().GetNumberOfComponents() == 1 )
//{
// SetDefaultImageProperties( node );
//}
MITK_INFO << "...finished!" << std::endl;
try
{
setlocale(LC_ALL, currLocale.c_str());
}
catch(...)
{
MITK_INFO << "Could not reset locale " << currLocale;
}
}
bool mitk::ItkImageFileReader::CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern)
{
// First check the extension
if( filename == "" )
return false;
// check if image is serie
if( filePattern != "" && filePrefix != "" )
return false;
itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( filename.c_str(), itk::ImageIOFactory::ReadMode );
if ( imageIO.IsNull() )
return false;
return true;
}
mitk::ItkImageFileReader::ItkImageFileReader()
: m_FileName(""), m_FilePrefix(""), m_FilePattern("")
{
}
mitk::ItkImageFileReader::~ItkImageFileReader()
{
}
diff --git a/Core/Code/IO/mitkItkImageFileReader.h b/Core/Code/IO/mitkItkImageFileReader.h
index 81a44176b0..51ee473a34 100644
--- a/Core/Code/IO/mitkItkImageFileReader.h
+++ b/Core/Code/IO/mitkItkImageFileReader.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 ItkImageFileReader_H_HEADER_INCLUDED
#define ItkImageFileReader_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkFileReader.h"
#include "mitkImageSource.h"
namespace mitk {
//##Documentation
//## @brief Reader to read file formats supported by itk
//## @ingroup IO
class MITK_CORE_EXPORT ItkImageFileReader : public ImageSource, public FileReader
{
public:
mitkClassMacro(ItkImageFileReader, FileReader);
/** Method for creation through the object factory. */
itkNewMacro(Self);
itkSetStringMacro(FileName);
itkGetStringMacro(FileName);
itkSetStringMacro(FilePrefix);
itkGetStringMacro(FilePrefix);
itkSetStringMacro(FilePattern);
itkGetStringMacro(FilePattern);
static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
protected:
virtual void GenerateData();
ItkImageFileReader();
~ItkImageFileReader();
std::string m_FileName;
std::string m_FilePrefix;
std::string m_FilePattern;
};
} // namespace mitk
#endif /* ItkImageFileReader_H_HEADER_INCLUDED */
diff --git a/Core/Code/IO/mitkItkPictureWrite.cpp b/Core/Code/IO/mitkItkPictureWrite.cpp
index b77bfd0d8a..5a986176a0 100644
--- a/Core/Code/IO/mitkItkPictureWrite.cpp
+++ b/Core/Code/IO/mitkItkPictureWrite.cpp
@@ -1,141 +1,140 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkItkPictureWrite.h"
#include <mitkInstantiateAccessFunctions.h>
#include <itkNumericSeriesFileNames.h>
#include <itkImageSeriesWriter.h>
#include <itkRescaleIntensityImageFilter.h>
template < typename TPixel, unsigned int VImageDimension >
void _mitkItkPictureWrite(itk::Image< TPixel, VImageDimension >* itkImage, const std::string& fileName)
{
typedef itk::Image< TPixel, VImageDimension > TImageType;
typedef itk::Image<unsigned char,3> OutputImage3DType;
typedef itk::Image<unsigned char,2> OutputImage2DType;
typename itk::RescaleIntensityImageFilter<TImageType, OutputImage3DType>::Pointer rescaler = itk::RescaleIntensityImageFilter<TImageType, OutputImage3DType>::New();
rescaler->SetInput(itkImage);
rescaler->SetOutputMinimum(0);
rescaler->SetOutputMaximum(255);
itk::ImageSeriesWriter<OutputImage3DType, OutputImage2DType>::Pointer writer = itk::ImageSeriesWriter<OutputImage3DType, OutputImage2DType >::New();
// Fix initialize the numberOfSlices to one as default
// test if image has dimension >2 to set the number of slices according to the value of GetSize()[2]
int numberOfSlices = 1;
if( VImageDimension > 2 )
{
itk::NumericSeriesFileNames::Pointer numericFileNameWriter = itk::NumericSeriesFileNames::New();
numberOfSlices = itkImage->GetLargestPossibleRegion().GetSize()[2];
std::string finalFileName = fileName;
std::string::size_type pos = fileName.find_last_of(".",fileName.length()-1);
if(pos==std::string::npos)
finalFileName.append(".%d.png");
else
finalFileName.insert(pos,".%d");
numericFileNameWriter->SetEndIndex(numberOfSlices);
numericFileNameWriter->SetSeriesFormat(finalFileName.c_str());
numericFileNameWriter->Modified();
writer->SetFileNames(numericFileNameWriter->GetFileNames());
}
// if the given image is an 2D-png image, do not use the numericFileNameWriter
// to generate the name, since it alters the fileName given as parameter
else
{
writer->SetFileName(fileName);
}
writer->SetInput( rescaler->GetOutput() );
writer->Update();
}
#define InstantiateAccessFunction__mitkItkPictureWrite(pixelType, dim) \
template MITK_CORE_EXPORT void _mitkItkPictureWrite(itk::Image<pixelType,dim>*, const std::string&);
InstantiateAccessFunction(_mitkItkPictureWrite)
// typedef itk::Image<itk::RGBPixel<unsigned char>, 2> itkImageRGBUC2;
// template <> void _mitkItkImageWrite<itk::RGBPixel<unsigned char>, 2>(itkImageRGBUC2* itkImage, const std::string& fileName)
// {
// typedef itkImageRGBUC2 TImageType;
//
// itk::ImageFileWriter<TImageType>::Pointer writer = itk::ImageFileWriter<TImageType>::New();
// writer->SetInput( itkImage );
// writer->SetFileName( fileName.c_str() );
// writer->Update();
// };
//
// typedef itk::Image<itk::RGBPixel<unsigned char>, 3> itkImageRGBUC3;
// template <> void _mitkItkImageWrite<itk::RGBPixel<unsigned char>, 3>(itkImageRGBUC3* itkImage, const std::string& fileName)
// {
// typedef itkImageRGBUC3 TImageType;
//
// itk::ImageFileWriter<TImageType>::Pointer writer = itk::ImageFileWriter<TImageType>::New();
// writer->SetInput( itkImage );
// writer->SetFileName( fileName.c_str() );
// writer->Update();
// };
//
// typedef itk::Image<itk::DiffusionTensor3D<float>, 3> itkImageDTIF3;
// template <> void _mitkItkImageWrite<itk::DiffusionTensor3D<float>, 3>(itkImageDTIF3* itkImage, const std::string& fileName)
// {
// typedef itkImageDTIF3 TImageType;
//
// itk::ImageFileWriter<TImageType>::Pointer writer = itk::ImageFileWriter<TImageType>::New();
// writer->SetInput( itkImage );
// writer->SetFileName( fileName.c_str() );
// writer->Update();
// };
//
// typedef itk::Image<itk::DiffusionTensor3D<double>, 3> itkImageDTID3;
// template <> void _mitkItkImageWrite<itk::DiffusionTensor3D<double>, 3>(itkImageDTID3* itkImage, const std::string& fileName)
// {
// typedef itkImageDTID3 TImageType;
//
// itk::ImageFileWriter<TImageType>::Pointer writer = itk::ImageFileWriter<TImageType>::New();
// writer->SetInput( itkImage );
// writer->SetFileName( fileName.c_str() );
// writer->Update();
// };
//
// typedef itk::Image<itk::DiffusionTensor3D<float>, 2> itkImageDTIF2;
// template <> void _mitkItkImageWrite<itk::DiffusionTensor3D<float>, 2>(itkImageDTIF2* itkImage, const std::string& fileName)
// {
// typedef itkImageDTIF2 TImageType;
//
// itk::ImageFileWriter<TImageType>::Pointer writer = itk::ImageFileWriter<TImageType>::New();
// writer->SetInput( itkImage );
// writer->SetFileName( fileName.c_str() );
// writer->Update();
// };
//
// typedef itk::Image<itk::DiffusionTensor3D<double>, 2> itkImageDTID2;
// template <> void _mitkItkImageWrite<itk::DiffusionTensor3D<double>, 2>(itkImageDTID2* itkImage, const std::string& fileName)
// {
// typedef itkImageDTID2 TImageType;
//
// itk::ImageFileWriter<TImageType>::Pointer writer = itk::ImageFileWriter<TImageType>::New();
// writer->SetInput( itkImage );
// writer->SetFileName( fileName.c_str() );
// writer->Update();
// };
diff --git a/Core/Code/IO/mitkItkPictureWrite.h b/Core/Code/IO/mitkItkPictureWrite.h
index db20eb2c80..3d18a3a8ea 100644
--- a/Core/Code/IO/mitkItkPictureWrite.h
+++ b/Core/Code/IO/mitkItkPictureWrite.h
@@ -1,27 +1,26 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKITKPICTUREWRITE_H
#define MITKITKPICTUREWRITE_H
#include <itkImage.h>
template < typename TPixel, unsigned int VImageDimension >
void _mitkItkPictureWrite(itk::Image< TPixel, VImageDimension >* itkImage, const std::string& fileName);
#endif /* MITKITKPICTUREWRITE_H */
diff --git a/Core/Code/IO/mitkLog.cpp b/Core/Code/IO/mitkLog.cpp
index 6a3bd4d0cd..0d9c1c9bfb 100644
--- a/Core/Code/IO/mitkLog.cpp
+++ b/Core/Code/IO/mitkLog.cpp
@@ -1,146 +1,145 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:56:03 +0200 (Tue, 12 May 2009) $
-Version: $Revision: 17179 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLog.h"
#include "mitkLogMacros.h"
#include "itkSimpleFastMutexLock.h"
#include <itkOutputWindow.h>
#include <iostream>
#include <fstream>
static itk::SimpleFastMutexLock logMutex;
static mitk::LoggingBackend *mitkLogBackend = 0;
static std::ofstream *logFile = 0;
static std::stringstream *outputWindow = 0;
static bool logOutputWindow = false;
void mitk::LoggingBackend::EnableAdditionalConsoleWindow(bool enable)
{
logOutputWindow = enable;
}
void mitk::LoggingBackend::ProcessMessage(const mbilog::LogMessage& l )
{
logMutex.Lock();
#ifdef _WIN32
FormatSmart( l, (int)GetCurrentThreadId() );
#else
FormatSmart( l );
#endif
if(logFile)
{
#ifdef _WIN32
FormatFull( *logFile, l, (int)GetCurrentThreadId() );
#else
FormatFull( *logFile, l );
#endif
}
if(logOutputWindow)
{
if(outputWindow == NULL)
{ outputWindow = new std::stringstream();}
outputWindow->str("");
outputWindow->clear();
#ifdef _WIN32
FormatFull( *outputWindow, l, (int)GetCurrentThreadId() );
#else
FormatFull( *outputWindow, l );
#endif
itk::OutputWindow::GetInstance()->DisplayText(outputWindow->str().c_str());
}
logMutex.Unlock();
}
void mitk::LoggingBackend::Register()
{
if(mitkLogBackend)
return;
mitkLogBackend = new mitk::LoggingBackend();
mbilog::RegisterBackend( mitkLogBackend );
}
void mitk::LoggingBackend::Unregister()
{
if(mitkLogBackend)
{
SetLogFile(0);
mbilog::UnregisterBackend( mitkLogBackend );
delete mitkLogBackend;
mitkLogBackend=0;
}
}
void mitk::LoggingBackend::SetLogFile(const char *file)
{
logMutex.Lock();
if(logFile)
{
MITK_INFO << "closing logfile";
logFile->close();
delete logFile;
logFile = 0;
}
if(file)
{
logFile = new std::ofstream( file, std::ios_base::out | std::ios_base::app );
/*
if(*logFile)
{
std::cout << "opening logfile '" << file << "' for writing failed";
MITK_INFO << "logging to '" << file << "'";
}
else
{
std::cerr << "opening logfile '" << file << "' for writing failed";
MITK_ERROR << "opening logfile '" << file << "' for writing failed";
delete logFile;
logFile = 0;
}
*/
}
logMutex.Unlock();
}
void mitk::LoggingBackend::CatchLogFileCommandLineParameter(int &argc,char **argv)
{
int r;
for(r=1;r<argc;r++)
{
if(std::string(argv[r])=="--logfile")
{
if(r+1>=argc)
{
--argc;
MITK_ERROR << "--logfile parameter found, but no file given";
return;
}
mitk::LoggingBackend::SetLogFile(argv[r+1]);
for(r+=2;r<argc;r++)
argv[r-2]=argv[r];
argc-=2;
return;
}
}
}
diff --git a/Core/Code/IO/mitkLog.h b/Core/Code/IO/mitkLog.h
index 030389769e..7157b13b37 100644
--- a/Core/Code/IO/mitkLog.h
+++ b/Core/Code/IO/mitkLog.h
@@ -1,64 +1,63 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:56:03 +0200 (Tue, 12 May 2009) $
-Version: $Revision: 17179 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_LOG_H
#define _MITK_LOG_H
#include <MitkExports.h>
#include <mbilog.h>
namespace mitk
{
/*!
\brief mbilog backend implementation for mitk
*/
class MITK_CORE_EXPORT LoggingBackend : public mbilog::TextBackendBase
{
public:
/** \brief overloaded method for receiving log message from mbilog
*/
void ProcessMessage(const mbilog::LogMessage& );
/** \brief registers MITK logging backend at mbilog
*/
static void Register();
/** \brief Unregisters MITK logging backend at mbilog
*/
static void Unregister();
/** \brief Sets extra log file path (additionally to the console log)
*/
static void SetLogFile(const char *file);
/** \brief Enables an additional logging output window by means of itk::outputwindow
* This might be relevant for showing log output in applications with no default output console
*/
static void EnableAdditionalConsoleWindow(bool enable);
/** \brief Automatically extracts and removes the "--logfile <file>" parameters from the standard C main(argc,argv) parameter list and calls SetLogFile if needed
*/
static void CatchLogFileCommandLineParameter(int &argc,char **argv);
};
}
#endif
diff --git a/Core/Code/IO/mitkLogMacros.h b/Core/Code/IO/mitkLogMacros.h
index 0e94a8971c..fb145d3523 100644
--- a/Core/Code/IO/mitkLogMacros.h
+++ b/Core/Code/IO/mitkLogMacros.h
@@ -1,29 +1,28 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
-Version: $Revision: 18127 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __MITK_LOG_H__
#define __MITK_LOG_H__
#include <mbilog.h>
#define MITK_INFO MBI_INFO
#define MITK_WARN MBI_WARN
#define MITK_ERROR MBI_ERROR
#define MITK_FATAL MBI_FATAL
#define MITK_DEBUG MBI_DEBUG
#endif /*__MITK_LOG_H__*/
diff --git a/Core/Code/IO/mitkLookupTableProperty.cpp b/Core/Code/IO/mitkLookupTableProperty.cpp
index d6e4c640d5..4f1eba1686 100755
--- a/Core/Code/IO/mitkLookupTableProperty.cpp
+++ b/Core/Code/IO/mitkLookupTableProperty.cpp
@@ -1,69 +1,68 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkLookupTableProperty.h"
mitk::LookupTableProperty::LookupTableProperty()
{
}
mitk::LookupTableProperty::LookupTableProperty(const mitk::LookupTable::Pointer lut)
{
this->SetLookupTable(lut);
}
bool mitk::LookupTableProperty::IsEqual(const BaseProperty& property) const
{
return *(this->m_LookupTable) == *(static_cast<const Self&>(property).m_LookupTable);
}
bool mitk::LookupTableProperty::Assign(const BaseProperty& property)
{
this->m_LookupTable = static_cast<const Self&>(property).m_LookupTable;
return true;
}
std::string mitk::LookupTableProperty::GetValueAsString() const
{
std::stringstream ss;
ss << m_LookupTable;
return ss.str();
}
mitk::LookupTableProperty::ValueType mitk::LookupTableProperty::GetValue() const
{
return m_LookupTable;
}
void mitk::LookupTableProperty::SetLookupTable(const mitk::LookupTable::Pointer aLookupTable)
{
// MITK_INFO << "setting LUT property ... " << std::endl;
if((m_LookupTable != aLookupTable) || (*m_LookupTable != *aLookupTable))
{
m_LookupTable = aLookupTable;
Modified();
}
// MITK_INFO << "setting LUT property OK! " << std::endl;
}
void mitk::LookupTableProperty::SetValue(const ValueType & value)
{
SetLookupTable(value);
}
diff --git a/Core/Code/IO/mitkLookupTableProperty.h b/Core/Code/IO/mitkLookupTableProperty.h
index e843c4437f..f1c4fd65a7 100755
--- a/Core/Code/IO/mitkLookupTableProperty.h
+++ b/Core/Code/IO/mitkLookupTableProperty.h
@@ -1,85 +1,84 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKLookupTablePROPERTY_H_HEADER_INCLUDED_C10EEAA8
#define MITKLookupTablePROPERTY_H_HEADER_INCLUDED_C10EEAA8
#include <MitkExports.h>
#include "mitkBaseProperty.h"
#include "mitkLookupTable.h"
namespace mitk {
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4522)
#endif
//##Documentation
//## @brief Property for LookupTable data
//##
//## @ingroup DataManagement
class MITK_CORE_EXPORT LookupTableProperty : public BaseProperty
{
protected:
LookupTable::Pointer m_LookupTable;
LookupTableProperty();
LookupTableProperty(const mitk::LookupTable::Pointer lut);
public:
typedef LookupTable::Pointer ValueType;
mitkClassMacro(LookupTableProperty, BaseProperty);
itkNewMacro(LookupTableProperty);
mitkNewMacro1Param(LookupTableProperty, const mitk::LookupTable::Pointer);
itkGetObjectMacro(LookupTable, LookupTable );
ValueType GetValue() const;
void SetLookupTable(const mitk::LookupTable::Pointer aLookupTable);
void SetValue(const ValueType&);
virtual std::string GetValueAsString() const;
using BaseProperty::operator=;
private:
// purposely not implemented
LookupTableProperty(const LookupTableProperty&);
LookupTableProperty& operator=(const LookupTableProperty&);
virtual bool IsEqual(const BaseProperty& property) const;
virtual bool Assign(const BaseProperty& property);
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace mitk
#endif /* MITKLookupTablePROPERTY_H_HEADER_INCLUDED_C10EEAA8 */
diff --git a/Core/Code/IO/mitkOperation.cpp b/Core/Code/IO/mitkOperation.cpp
index baab9b35f9..c23562ba9d 100644
--- a/Core/Code/IO/mitkOperation.cpp
+++ b/Core/Code/IO/mitkOperation.cpp
@@ -1,33 +1,32 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkOperation.h"
mitk::Operation::Operation(mitk::OperationType operationType)
: m_OperationType(operationType)
{
}
mitk::Operation::~Operation()
{
}
mitk::OperationType mitk::Operation::GetOperationType()
{
return m_OperationType;
}
diff --git a/Core/Code/IO/mitkOperation.h b/Core/Code/IO/mitkOperation.h
index 5a4492aa2f..135dffa0c9 100644
--- a/Core/Code/IO/mitkOperation.h
+++ b/Core/Code/IO/mitkOperation.h
@@ -1,68 +1,67 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 OPERATION_H_HEADER_INCLUDED_C16E7D9E
#define OPERATION_H_HEADER_INCLUDED_C16E7D9E
#include <MitkExports.h>
#include <itkEventObject.h>
namespace mitk {
typedef int OperationType ;
//##Documentation
//## @brief Base class of all Operation-classes
//##
//## @ingroup Undo
class MITK_CORE_EXPORT Operation
{
public:
//##Documentation
//## Constructor
Operation(OperationType operationType);
virtual ~Operation();
OperationType GetOperationType();
protected:
OperationType m_OperationType;
};
class MITK_CORE_EXPORT OperationEndEvent : public itk::EndEvent
{
public:
typedef OperationEndEvent Self;
typedef itk::EndEvent Superclass;
OperationEndEvent(Operation* operation = NULL) :
m_Operation(operation) {}
virtual ~OperationEndEvent() {}
virtual const char * GetEventName() const { return "OperationEndEvent"; }
virtual bool CheckEvent(const ::itk::EventObject* e) const
{ return dynamic_cast<const Self*>(e); }
virtual ::itk::EventObject* MakeObject() const
{ return new Self(m_Operation); }
Operation* GetOperation() const { return m_Operation; }
private:
Operation* m_Operation;
OperationEndEvent(const Self&);
void operator=(const Self&);
};
}//namespace mitk
#endif /* OPERATION_H_HEADER_INCLUDED_C16E7D9E */
diff --git a/Core/Code/IO/mitkOperationActor.h b/Core/Code/IO/mitkOperationActor.h
index c84e8be301..1317b143fd 100644
--- a/Core/Code/IO/mitkOperationActor.h
+++ b/Core/Code/IO/mitkOperationActor.h
@@ -1,52 +1,51 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 OPERATIONACTOR_H_HEADER_INCLUDED_C16E28BD
#define OPERATIONACTOR_H_HEADER_INCLUDED_C16E28BD
#include <MitkExports.h>
namespace mitk
{
class Operation;
class OperationEvent;
/** Macro for checking the type of an operation*/
#define mitkCheckOperationTypeMacro(OperationType, operation, newOperationName) \
mitk::OperationType *newOperationName= dynamic_cast<mitk::OperationType *>(operation);\
if (newOperationName == NULL)\
{\
itkWarningMacro("Recieved wrong type of operation!");\
return;\
}\
//##Documentation
//## @brief abstract class, that can be used by Undo to undo an operation.
//##
//## @ingroup Undo
class MITK_CORE_EXPORT OperationActor
{
public:
virtual ~OperationActor() {};
virtual void ExecuteOperation(Operation* operation) = 0;
};
}
#endif /* OPERATIONACTOR_H_HEADER_INCLUDED_C16E28BD */
diff --git a/Core/Code/IO/mitkPixelType.cpp b/Core/Code/IO/mitkPixelType.cpp
index 045109debd..997c705431 100644
--- a/Core/Code/IO/mitkPixelType.cpp
+++ b/Core/Code/IO/mitkPixelType.cpp
@@ -1,150 +1,149 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPixelType.h"
#include <mitkLogMacros.h>
#include <itkVector.h>
#include <itkRGBPixel.h>
#include <itkRGBAPixel.h>
#include <itkCovariantVector.h>
#include "itkDiffusionTensor3D.h"
#define HUNDRED_VECS(HUN) \
TEN_VECS(HUN) \
TEN_VECS(HUN+10) \
TEN_VECS(HUN+20) \
TEN_VECS(HUN+30) \
TEN_VECS(HUN+40) \
TEN_VECS(HUN+50) \
TEN_VECS(HUN+60) \
TEN_VECS(HUN+70) \
TEN_VECS(HUN+80) \
TEN_VECS(HUN+90) \
#define TEN_VECS(TEN) \
if(false){} \
N_VEC(TEN+ 1) \
N_VEC(TEN+ 2) \
N_VEC(TEN+ 3) \
N_VEC(TEN+ 4) \
N_VEC(TEN+ 5) \
N_VEC(TEN+ 6) \
N_VEC(TEN+ 7) \
N_VEC(TEN+ 8) \
N_VEC(TEN+ 9) \
N_VEC(TEN+10) \
#define N_VEC(N_DIRS) \
_N_VEC(N_DIRS,double) \
_N_VEC(N_DIRS,float) \
_N_VEC(N_DIRS,short) \
#define _N_VEC(N_DIRS,PIXTYPE) \
else if ( *m_TypeId == typeid( itk::Vector<PIXTYPE,N_DIRS> )) \
{ \
found = true; \
m_TypeId = & typeid( PIXTYPE ); \
m_NumberOfComponents *= N_DIRS; \
m_Type = mitkIpPicFloat; \
m_Bpe = sizeof(PIXTYPE) * 8 * m_NumberOfComponents; \
m_ItkTypeId = &typeid( itk::Vector<PIXTYPE,N_DIRS> ); \
} \
mitk::PixelType::PixelType( const mitk::PixelType& other )
: m_ComponentType( other.m_ComponentType ),
m_PixelType( other.m_PixelType),
m_ComponentTypeName( other.m_ComponentTypeName ),
m_PixelTypeName( other.m_PixelTypeName ),
m_NumberOfComponents( other.m_NumberOfComponents ),
m_BytesPerComponent( other.m_BytesPerComponent )
{
}
bool mitk::PixelType::operator==(const mitk::PixelType& rhs) const
{
MITK_DEBUG << "operator==" << std::endl;
MITK_DEBUG << "m_NumberOfComponents = " << m_NumberOfComponents << " " << rhs.m_NumberOfComponents << std::endl;
MITK_DEBUG << "m_BytesPerComponent = " << m_BytesPerComponent << " " << rhs.m_BytesPerComponent << std::endl;
return ( this->m_PixelType == rhs.m_PixelType
&& this->m_ComponentType == rhs.m_ComponentType
&& this->m_NumberOfComponents == rhs.m_NumberOfComponents
&& this->m_BytesPerComponent == rhs.m_BytesPerComponent
);
}
bool mitk::PixelType::operator ==(const std::type_info& typeId) const
{
if( m_NumberOfComponents ==1 )
return (m_ComponentType == typeId);
else
return (m_PixelType == typeId);
}
bool mitk::PixelType::operator!=(const mitk::PixelType& rhs) const
{
return !(this->operator==(rhs));
}
bool mitk::PixelType::operator!=(const std::type_info& typeId) const
{
return !(this->operator==(typeId));
}
#define SET_ITK_TYPE_ID(anItkIoPixelType_test, numberOfComponents_test, ITK_TYPE) \
if ( (itk::ImageIOBase::anItkIoPixelType_test == anItkIoPixelType ) && \
(numberOfComponents_test == m_NumberOfComponents) \
) \
{ * \
m_ItkTypeId = &typeid(ITK_TYPE); \
}
#define SET_TYPE(TYPE, IPPIC_TYPE) \
if ( *m_TypeId == typeid( TYPE ) ) \
{ \
m_Type = IPPIC_TYPE; \
m_Bpe = sizeof(TYPE) * 8 * m_NumberOfComponents; \
\
typedef itk::Vector<TYPE, 3> Vector3Type; \
typedef itk::CovariantVector<TYPE, 3> CovariantVector3Type; \
typedef itk::Point<TYPE, 3> Point3Type; \
typedef itk::Vector<TYPE, 2> Vector2Type; \
typedef itk::CovariantVector<TYPE, 2> CovariantVector2Type; \
typedef itk::Point<TYPE, 2> Point2Type; \
\
SET_ITK_TYPE_ID(UNKNOWNPIXELTYPE, 1, TYPE ) else \
SET_ITK_TYPE_ID(SCALAR, 1, TYPE ) else \
\
SET_ITK_TYPE_ID(VECTOR, 2, Vector2Type ) else \
SET_ITK_TYPE_ID(COVARIANTVECTOR, 2, CovariantVector2Type ) else \
SET_ITK_TYPE_ID(POINT, 2, Point2Type ) else \
\
SET_ITK_TYPE_ID(RGB, 3, itk::RGBPixel<TYPE> ) else \
/*SET_ITK_TYPE_ID(DIFFUSIONTENSOR3D, 6, itk::DiffusionTensor3D<TYPE> ) else */ \
SET_ITK_TYPE_ID(VECTOR, 3, Vector3Type ) else \
SET_ITK_TYPE_ID(COVARIANTVECTOR, 3, CovariantVector3Type ) else \
SET_ITK_TYPE_ID(POINT, 3, Point3Type ) else \
\
SET_ITK_TYPE_ID(RGBA, 4, itk::RGBAPixel<TYPE> ) else \
{ \
} \
} \
else
diff --git a/Core/Code/IO/mitkPixelType.h b/Core/Code/IO/mitkPixelType.h
index f0842e880d..14dffbd58d 100644
--- a/Core/Code/IO/mitkPixelType.h
+++ b/Core/Code/IO/mitkPixelType.h
@@ -1,260 +1,259 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 PIXELTYPE_H_HEADER_INCLUDED_C1EBF565
#define PIXELTYPE_H_HEADER_INCLUDED_C1EBF565
#include <MitkExports.h>
#include "mitkCommon.h"
#include "mitkPixelTypeTraits.h"
#include <typeinfo>
#include <string>
#include <itkImageIOBase.h>
#include <itkImage.h>
namespace mitk {
template< typename ComponentT>
const char* ComponentTypeToString()
{
return typeid(ComponentT).name();
}
template<typename PixelT>
const char* PixelTypeToString()
{
return typeid(PixelT).name();
}
//##Documentation
//## @brief Class for defining the data type of pixels
//##
//## To obtain additional type information not provided by this class
//## itk::ImageIOBase can be used by passing the return value of
//## PixelType::GetItkTypeId() to itk::ImageIOBase::SetPixelTypeInfo
//## and using the itk::ImageIOBase methods GetComponentType,
//## GetComponentTypeAsString, GetPixelType, GetPixelTypeAsString.
//## @ingroup Data
class MITK_CORE_EXPORT PixelType
{
public:
itkTypeMacro(PixelType, None);
typedef itk::ImageIOBase::IOPixelType ItkIOPixelType;
PixelType(const mitk::PixelType & aPixelType);
/** \brief Get the \a type_info of the scalar (!) type. Each element
* may contain m_NumberOfComponents (more than one) of these scalars.
*
*/
inline const std::type_info& GetTypeId() const
{
return m_ComponentType;
}
/** \brief Get the \a type_info of the whole pixel type.
*
* If you want the type information for the component of a compound type use the
* GetTypeId() method
*/
inline const std::type_info& GetPixelTypeId() const
{
return m_PixelType;
}
/** \brief Returns a string containing the ItkTypeName,
*
* The string provides the same information as GetPixelTypeId.name()
*/
std::string GetItkTypeAsString() const
{
return m_PixelTypeName;
}
/** \brief Returns a string containing the type name of the component,
*
* The string provides the same information as GetTypeId.name()
*/
std::string GetComponentTypeAsString() const
{
return m_ComponentTypeName;
}
/** \brief Get size of the PixelType in bytes
*
* A RGBA PixelType of floats will return 4 * sizeof(float)
*/
size_t GetSize() const
{
return (m_NumberOfComponents * m_BytesPerComponent);
}
/** \brief Get the number of bits per element (of an
* element)
*
* A vector of double with three components will return
* 8*sizeof(double)*3.
* \sa GetBitsPerComponent
* \sa GetItkTypeId
* \sa GetTypeId
*/
size_t GetBpe() const
{
return this->GetSize() * 8;
}
/** \brief Get the number of components of which each element consists
*
* Each pixel can consist of multiple components, e.g. RGB.
*/
inline size_t GetNumberOfComponents() const
{
return m_NumberOfComponents;
}
/** \brief Get the number of bits per components
* \sa GetBitsPerComponent
*/
inline size_t GetBitsPerComponent() const
{
return m_BytesPerComponent * 8;
}
bool operator==(const PixelType& rhs) const;
bool operator!=(const PixelType& rhs) const;
bool operator==(const std::type_info& typeId) const;
bool operator!=(const std::type_info& typeId) const;
~PixelType() {}
private:
friend class ItkImageFileReader;
friend class NrrdTbssImageReader;
friend class NrrdTbssRoiImageReader;
template< typename ComponentT, typename PixelT, std::size_t numberOfComponents >
friend PixelType MakePixelType();
template< typename ItkImageType >
friend PixelType MakePixelType();
PixelType( const std::type_info& componentType,
const std::type_info& pixelType,
std::size_t bytesPerComponent,
std::size_t numberOfComponents,
const char* componentTypeName = 0,
const char* pixelTypeName = 0 )
: m_ComponentType( componentType ),
m_PixelType( pixelType ),
m_NumberOfComponents( numberOfComponents ),
m_BytesPerComponent( bytesPerComponent )
{
if(componentTypeName) m_ComponentTypeName = componentTypeName;
else m_ComponentTypeName = componentType.name();
if(pixelTypeName) m_PixelTypeName = pixelTypeName;
else m_PixelTypeName = pixelType.name();
}
// default constructor is disabled on purpose
PixelType(void);
// assignment operator declared private on purpose
PixelType& operator=(const PixelType& other);
/** \brief the \a type_info of the scalar (!) component type. Each element
may contain m_NumberOfComponents (more than one) of these scalars.
*/
const std::type_info& m_ComponentType;
const std::type_info& m_PixelType;
std::string m_ComponentTypeName;
std::string m_PixelTypeName;
std::size_t m_NumberOfComponents;
std::size_t m_BytesPerComponent;
};
/** \brief A template method for creating a pixel type.
*/
template< typename ComponentT, typename PixelT, std::size_t numOfComponents >
PixelType MakePixelType()
{
typedef itk::Image< PixelT, numOfComponents> ItkImageType;
return PixelType( typeid(ComponentT), typeid(ItkImageType),
sizeof(ComponentT), numOfComponents,
ComponentTypeToString<ComponentT>(),
PixelTypeToString<ItkImageType>()
);
}
/** \brief A template method for creating a pixel type from an ItkImageType
*
* For fixed size vector images ( i.e. images of type itk::FixedArray<3,float> ) also the number of components
* is propagated to the constructor
*/
template< typename ItkImageType >
PixelType MakePixelType()
{
// define new type, since the ::PixelType is used to distinguish between simple and compound types
typedef typename ItkImageType::PixelType ImportPixelType;
// get the component type ( is either directly ImportPixelType or ImportPixelType::ValueType for compound types )
typedef typename GetComponentType<ImportPixelType>::ComponentType ComponentT;
// The PixelType is the same as the ComponentT for simple types
typedef typename ItkImageType::PixelType PixelT;
// Get the length of compound type ( initialized to 1 for simple types and variable-length vector images)
size_t numComp = ComponentsTrait<
(isPrimitiveType<PixelT>::value || isVectorImage<PixelT, ComponentT>::value), ItkImageType >::Size;
// call the constructor
return PixelType(
typeid(ComponentT), typeid(PixelT),
sizeof(ComponentT), numComp,
ComponentTypeToString<ComponentT>(),
PixelTypeToString<PixelT >()
);
}
/** \brief An interface to the MakePixelType method for creating scalar pixel types.
*
* Usage: for example MakeScalarPixelType<short>() for a scalar short image
*/
template< typename T>
PixelType MakeScalarPixelType()
{
return MakePixelType<T,T,1>();
}
} // namespace mitk
#endif /* PIXELTYPE_H_HEADER_INCLUDED_C1EBF565 */
diff --git a/Core/Code/IO/mitkPixelTypeTraits.h b/Core/Code/IO/mitkPixelTypeTraits.h
index 4a083084b4..544da6f42c 100644
--- a/Core/Code/IO/mitkPixelTypeTraits.h
+++ b/Core/Code/IO/mitkPixelTypeTraits.h
@@ -1,128 +1,127 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 PIXELTYPETRAITS_H
#define PIXELTYPETRAITS_H
/** \file mitkPixelTypeTraits.h
*
* The pixel type traits are in general used for compile time resolution of the component type and
* the number of components for compound types like the ones in ItkImageType.
* The default values are used to define the corresponding variable also for scalar types
*/
namespace itk
{
/** Forward declaration of the Variable Length Vector class from ITK */
template < typename TValueType > class VariableLengthVector;
}
/**
\brief This is an implementation of a type trait to provide a compile-time check for PixelType used in
the instantiation of an itk::Image
*/
template< typename T>
struct isPrimitiveType
{
static const bool value = false;
};
/** \def DEFINE_TYPE_PRIMITIVE macro which provides a partial specialization for the \sa isPrimitiveType
object */
#define DEFINE_TYPE_PRIMITIVE(_TYPEIN) \
template<> struct isPrimitiveType<_TYPEIN>{ static const bool value = true; }
/** \brief Partial specialization (unsigned char) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(unsigned char);
/** \brief Partial specialization (char) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(char);
/** \brief Partial specialization (signed char) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(signed char);
/** \brief Partial specialization (unsigned short) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(unsigned short);
/** \brief Partial specialization (short) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(short);
/** \brief Partial specialization (unsigned int) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(unsigned int);
/** \brief Partial specialization (int) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(int);
/** \brief Partial specialization (long int) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(long int);
/** \brief Partial specialization (long unsigned int) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(long unsigned int);
/** \brief Partial specialization (float) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(float);
/** \brief Partial specialization (double) for the isPrimitiveType object */
DEFINE_TYPE_PRIMITIVE(double);
/** \brief Type trait to provide compile-time check for T ?= itk::VectorImage */
template< class T, typename TValueType >
struct isVectorImage
{
static const bool value = false;
};
/** \brief Partial specification for the isVectorImage trait. */
template< typename TValueType >
struct isVectorImage< itk::VariableLengthVector<TValueType>, TValueType>
{
static const bool value = true;
};
/** \brief Compile-time trait for resolving the ValueType from an ItkImageType */
template<bool flag,typename T>
struct PixelTypeTrait
{
typedef T ValueType;
};
/** \brief Partial specialization for the PixelTypeTrait
*
* Specialization for the false value. Used to define the value type for non-primitive pixel types
*/
template<typename T>
struct PixelTypeTrait<false, T>
{
typedef typename T::ValueType ValueType;
};
/** \brief Compile time resolving of the type of a component */
template<typename T>
struct GetComponentType
{
typedef typename PixelTypeTrait<isPrimitiveType<T>::value, T>::ValueType ComponentType;
};
/** \brief Object for compile-time resolving of the number of components for given type.
*
* Default value for the component number is 1
*/
template<bool V, typename T>
struct ComponentsTrait
{
static const size_t Size = 1;
};
/** \brief Partial specialization for the ComponentsTraits in case of compound types */
template<typename T>
struct ComponentsTrait<false, T>
{
static const size_t Size = T::ValueType::Length;
};
#endif // PIXELTYPETRAITS_H
diff --git a/Core/Code/IO/mitkPointSetIOFactory.cpp b/Core/Code/IO/mitkPointSetIOFactory.cpp
index 05b0310ae9..bc08bd1fdf 100644
--- a/Core/Code/IO/mitkPointSetIOFactory.cpp
+++ b/Core/Code/IO/mitkPointSetIOFactory.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetIOFactory.h"
#include "mitkIOAdapter.h"
#include "mitkPointSetReader.h"
#include "itkVersion.h"
namespace mitk
{
PointSetIOFactory::PointSetIOFactory()
{
this->RegisterOverride("mitkIOAdapter",
"mitkPointSetReader",
"mitk PointSet IO",
1,
itk::CreateObjectFunction<IOAdapter<PointSetReader> >::New());
}
PointSetIOFactory::~PointSetIOFactory()
{
}
const char* PointSetIOFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* PointSetIOFactory::GetDescription() const
{
return "PointSet IO Factory, allows the loading of MITK pointsets";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkPointSetIOFactory.h b/Core/Code/IO/mitkPointSetIOFactory.h
index d544b50a67..58a788e77e 100644
--- a/Core/Code/IO/mitkPointSetIOFactory.h
+++ b/Core/Code/IO/mitkPointSetIOFactory.h
@@ -1,72 +1,71 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkPointSetIOFactory_h
#define __mitkPointSetIOFactory_h
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
//##Documentation
//## @brief Create instances of PointSetReader objects using an object factory.
//##
//## @ingroup IO
class MITK_CORE_EXPORT PointSetIOFactory : public itk::ObjectFactoryBase
{
public:
/** Standard class typedefs. */
typedef PointSetIOFactory Self;
typedef itk::ObjectFactoryBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
static PointSetIOFactory* FactoryNew() { return new PointSetIOFactory;}
/** Run-time type information (and related methods). */
itkTypeMacro(PointSetIOFactory, ObjectFactoryBase);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
PointSetIOFactory::Pointer PointSetIOFactory = PointSetIOFactory::New();
ObjectFactoryBase::RegisterFactory(PointSetIOFactory);
}
protected:
PointSetIOFactory();
~PointSetIOFactory();
private:
PointSetIOFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkPointSetReader.cpp b/Core/Code/IO/mitkPointSetReader.cpp
index e5a377ae98..24b359e708 100644
--- a/Core/Code/IO/mitkPointSetReader.cpp
+++ b/Core/Code/IO/mitkPointSetReader.cpp
@@ -1,195 +1,194 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetReader.h"
#include <iostream>
#include <fstream>
#include <locale>
mitk::PointSetReader::PointSetReader()
{
m_Success = false;
}
mitk::PointSetReader::~PointSetReader()
{}
void mitk::PointSetReader::GenerateData()
{
std::locale::global(std::locale("C"));
m_Success = false;
if ( m_FileName == "" )
{
itkWarningMacro( << "Sorry, filename has not been set!" );
return ;
}
if ( ! this->CanReadFile( m_FileName.c_str() ) )
{
itkWarningMacro( << "Sorry, can't read file " << m_FileName << "!" );
return ;
}
try{
TiXmlDocument doc(m_FileName.c_str());
bool loadOkay = doc.LoadFile();
if (loadOkay)
{
TiXmlHandle docHandle( &doc );
unsigned int pointSetCounter(0);
for( TiXmlElement* currentPointSetElement = docHandle.FirstChildElement("point_set_file").FirstChildElement("point_set").ToElement();
currentPointSetElement != NULL; currentPointSetElement = currentPointSetElement->NextSiblingElement())
{
mitk::PointSet::Pointer newPointSet = mitk::PointSet::New();
if(currentPointSetElement->FirstChildElement("time_series") != NULL)
{
for( TiXmlElement* currentTimeSeries = currentPointSetElement->FirstChildElement("time_series")->ToElement();
currentTimeSeries != NULL; currentTimeSeries = currentTimeSeries->NextSiblingElement())
{
unsigned int currentTimeStep(0);
TiXmlElement* currentTimeSeriesID = currentTimeSeries->FirstChildElement("time_series_id");
currentTimeStep = atoi(currentTimeSeriesID->GetText());
newPointSet = this->ReadPoint(newPointSet, currentTimeSeries, currentTimeStep);
}
}
else
{
newPointSet = this->ReadPoint(newPointSet, currentPointSetElement, 0);
}
this->SetNthOutput( pointSetCounter, newPointSet );
pointSetCounter++;
}
}
else
{
MITK_WARN << "XML parser error!";
}
}catch(...)
{
MITK_ERROR << "Cannot read point set.";
m_Success = false;
}
m_Success = true;
}
mitk::PointSet::Pointer mitk::PointSetReader::ReadPoint(mitk::PointSet::Pointer newPointSet,
TiXmlElement* currentTimeSeries, unsigned int currentTimeStep)
{
if(currentTimeSeries->FirstChildElement("point") != NULL)
{
for( TiXmlElement* currentPoint = currentTimeSeries->FirstChildElement("point")->ToElement();
currentPoint != NULL; currentPoint = currentPoint->NextSiblingElement())
{
unsigned int id(0);
mitk::PointSpecificationType spec((mitk::PointSpecificationType) 0);
double x(0.0);
double y(0.0);
double z(0.0);
id = atoi(currentPoint->FirstChildElement("id")->GetText());
if(currentPoint->FirstChildElement("specification") != NULL)
{
spec = (mitk::PointSpecificationType) atoi(currentPoint->FirstChildElement("specification")->GetText());
}
x = atof(currentPoint->FirstChildElement("x")->GetText());
y = atof(currentPoint->FirstChildElement("y")->GetText());
z = atof(currentPoint->FirstChildElement("z")->GetText());
mitk::Point3D point;
mitk::FillVector3D(point, x, y, z);
newPointSet->SetPoint(id, point, spec, currentTimeStep);
}
}
else
{
if(currentTimeStep != newPointSet->GetTimeSteps()+1)
{
newPointSet->Expand(currentTimeStep+1); // expand time step series with empty time step
}
}
return newPointSet;
}
void mitk::PointSetReader::GenerateOutputInformation()
{
}
int mitk::PointSetReader::CanReadFile ( const char *name )
{
std::ifstream in( name );
bool isGood = in.good();
in.close();
return isGood;
}
bool mitk::PointSetReader::CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern)
{
// First check the extension
if( filename == "" )
{
//MITK_INFO<<"No filename specified."<<std::endl;
return false;
}
// check if image is serie
if( filePattern != "" && filePrefix != "" )
return false;
bool extensionFound = false;
std::string::size_type MPSPos = filename.rfind(".mps");
if ((MPSPos != std::string::npos)
&& (MPSPos == filename.length() - 4))
{
extensionFound = true;
}
MPSPos = filename.rfind(".MPS");
if ((MPSPos != std::string::npos)
&& (MPSPos == filename.length() - 4))
{
extensionFound = true;
}
if( !extensionFound )
{
//MITK_INFO<<"The filename extension is not recognized."<<std::endl;
return false;
}
return true;
}
void mitk::PointSetReader::ResizeOutputs( const unsigned int& num )
{
unsigned int prevNum = this->GetNumberOfOutputs();
this->SetNumberOfOutputs( num );
for ( unsigned int i = prevNum; i < num; ++i )
{
this->SetNthOutput( i, this->MakeOutput( i ).GetPointer() );
}
}
bool mitk::PointSetReader::GetSuccess() const
{
return m_Success;
}
diff --git a/Core/Code/IO/mitkPointSetReader.h b/Core/Code/IO/mitkPointSetReader.h
index c1312c70d0..052df205e7 100644
--- a/Core/Code/IO/mitkPointSetReader.h
+++ b/Core/Code/IO/mitkPointSetReader.h
@@ -1,145 +1,144 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_POINT_SET_READER__H_
#define _MITK_POINT_SET_READER__H_
#include <mitkPointSetSource.h>
#include <mitkFileReader.h>
#include <string>
#include <stack>
#include <vtkXMLParser.h>
#include <tinyxml.h>
namespace mitk
{
/**
* @brief reads xml representations of mitk::PointSets from a file
*
* Reader for xml files containing one or multiple xml represenations of
* mitk::PointSets. If multiple mitk::PointSets are stored in one file,
* these are assigned to multiple outputs of the filter. The number of point
* sets which have be read can be retrieven by a call to GetNumberOfOutputs()
* after the pipeline update().
* The reader is able to read the old 3D Pointsets without the "specification" and "timeseries" tags and the new 4D Pointsets.
* @note loading point sets from multiple files according to a given file pattern
* is not yet supported!
* @ingroup PSIO
* @ingroup IO
*/
class MITK_CORE_EXPORT PointSetReader: public PointSetSource, public FileReader
{
public:
mitkClassMacro( PointSetReader, FileReader );
itkNewMacro( Self );
/**
* @brief Sets the filename of the file to be read
* @param _arg the filename of the point set xml-file
*/
itkSetStringMacro( FileName );
/**
* @brief Returns the filename of the point set xml-file.
* @returns the filename of the point set xml-file.
*/
itkGetStringMacro( FileName );
/**
* @warning multiple load not (yet) supported
*/
itkSetStringMacro( FilePrefix );
/**
* @warning multiple load not (yet) supported
*/
itkGetStringMacro( FilePrefix );
/**
* @warning multiple load not (yet) supported
*/
itkSetStringMacro( FilePattern );
/**
* @warning multiple load not (yet) supported
*/
itkGetStringMacro( FilePattern );
static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
/**
* @returns whether the last read attempt was successful or not.
*/
bool GetSuccess() const;
protected:
/**
* Constructor
*/
PointSetReader();
/**
* Virtual destructor
*/
virtual ~PointSetReader();
/**
* Actually reads the point sets from the given file
*/
virtual void GenerateData();
virtual mitk::PointSet::Pointer ReadPoint(mitk::PointSet::Pointer newPointSet,
TiXmlElement* currentTimeSeries, unsigned int currentTimeStep);
/**
* Does nothing in the current implementation
*/
virtual void GenerateOutputInformation();
/**
* Resizes the output-objects according to the given number.
* @param num the new number of output objects.
*/
virtual void ResizeOutputs( const unsigned int& num );
/**
* Checks if the given file has appropriate
* read access.
* @returns true if the file exists and may be read
* or false otherwise.
*/
virtual int CanReadFile (const char *name);
std::string m_FileName;
std::string m_FilePrefix;
std::string m_FilePattern;
bool m_Success;
};
}
#endif
diff --git a/Core/Code/IO/mitkPointSetWriter.cpp b/Core/Code/IO/mitkPointSetWriter.cpp
index 8c28e9cf19..d6f1dd6708 100644
--- a/Core/Code/IO/mitkPointSetWriter.cpp
+++ b/Core/Code/IO/mitkPointSetWriter.cpp
@@ -1,383 +1,382 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetWriter.h"
#include <iostream>
#include <fstream>
#include <locale>
//
// Initialization of the xml tags.
//
const char* mitk::PointSetWriter::XML_POINT_SET_FILE = "point_set_file" ;
const char* mitk::PointSetWriter::XML_FILE_VERSION = "file_version" ;
const char* mitk::PointSetWriter::XML_POINT_SET = "point_set" ;
const char* mitk::PointSetWriter::XML_TIME_SERIES = "time_series";
const char* mitk::PointSetWriter::XML_TIME_SERIES_ID = "time_series_id";
const char* mitk::PointSetWriter::XML_POINT = "point" ;
const char* mitk::PointSetWriter::XML_ID = "id" ;
const char* mitk::PointSetWriter::XML_SPEC = "specification" ;
const char* mitk::PointSetWriter::XML_X = "x" ;
const char* mitk::PointSetWriter::XML_Y = "y" ;
const char* mitk::PointSetWriter::XML_Z = "z" ;
const char* mitk::PointSetWriter::VERSION_STRING = "0.1" ;
mitk::PointSetWriter::PointSetWriter()
: m_FileName(""), m_FilePrefix(""), m_FilePattern("")
{
this->SetNumberOfRequiredInputs( 1 );
this->SetNumberOfOutputs( 1 );
this->SetNthOutput( 0, mitk::PointSet::New().GetPointer() );
m_Indent = 2;
m_IndentDepth = 0;
m_Success = false;
}
mitk::PointSetWriter::~PointSetWriter()
{}
void mitk::PointSetWriter::GenerateData()
{
m_Success = false;
m_IndentDepth = 0;
//
// Opening the file to write to
//
if ( m_FileName == "" )
{
itkWarningMacro( << "Sorry, filename has not been set!" );
return ;
}
std::ofstream out( m_FileName.c_str() );
if ( !out.good() )
{
itkExceptionMacro(<< "File " << m_FileName << " could not be opened!");
itkWarningMacro( << "Sorry, file " << m_FileName << " could not be opened!" );
out.close();
return ;
}
std::locale previousLocale(out.getloc());
std::locale I("C");
out.imbue(I);
//
// Here the actual xml writing begins
//
WriteXMLHeader( out );
WriteStartElement( XML_POINT_SET_FILE, out );
WriteStartElement( XML_FILE_VERSION, out );
WriteCharacterData( VERSION_STRING, out );
WriteEndElement( XML_FILE_VERSION, out, false );
//
// for each input object write its xml representation to
// the stream
//
for ( unsigned int i = 0 ; i < this->GetNumberOfInputs(); ++i )
{
InputType::Pointer pointSet = this->GetInput( i );
assert( pointSet.IsNotNull() );
WriteXML( pointSet.GetPointer(), out );
}
WriteEndElement( XML_POINT_SET_FILE, out );
out.imbue(previousLocale);
if ( !out.good() ) // some error during output
{
out.close();
throw std::ios_base::failure("Some error during point set writing.");
}
out.close();
m_Success = true;
m_MimeType = "application/MITK.PointSet";
}
void mitk::PointSetWriter::WriteXML( mitk::PointSet* pointSet, std::ofstream& out )
{
WriteStartElement( XML_POINT_SET, out );
unsigned int timecount = pointSet->GetTimeSteps();
for(unsigned int i=0; i< timecount; i++)
{
WriteStartElement( XML_TIME_SERIES, out );
WriteStartElement( XML_TIME_SERIES_ID, out );
WriteCharacterData( ConvertToString( i ).c_str() , out );
WriteEndElement( XML_TIME_SERIES_ID, out, false );
mitk::PointSet::PointsContainer* pointsContainer = pointSet->GetPointSet(i)->GetPoints();
mitk::PointSet::PointsContainer::Iterator it;
for ( it = pointsContainer->Begin(); it != pointsContainer->End(); ++it )
{
WriteStartElement( XML_POINT, out );
WriteStartElement( XML_ID, out );
WriteCharacterData( ConvertToString( it->Index() ).c_str() , out );
WriteEndElement( XML_ID, out, false );
mitk::PointSet::PointType point = it->Value();
WriteStartElement( XML_SPEC, out );
WriteCharacterData( ConvertToString( pointSet->GetSpecificationTypeInfo(it->Index(), i) ).c_str() , out );
WriteEndElement( XML_SPEC, out, false );
WriteStartElement( XML_X, out );
WriteCharacterData( ConvertToString( point[ 0 ] ).c_str(), out );
WriteEndElement( XML_X, out, false );
WriteStartElement( XML_Y, out );
WriteCharacterData( ConvertToString( point[ 1 ] ).c_str(), out );
WriteEndElement( XML_Y, out, false );
WriteStartElement( XML_Z, out );
WriteCharacterData( ConvertToString( point[ 2 ] ).c_str(), out );
WriteEndElement( XML_Z, out, false );
WriteEndElement( XML_POINT, out );
}
WriteEndElement( XML_TIME_SERIES, out );
}
WriteEndElement( XML_POINT_SET, out );
}
void mitk::PointSetWriter::ResizeInputs( const unsigned int& num )
{
unsigned int prevNum = this->GetNumberOfInputs();
this->SetNumberOfInputs( num );
for ( unsigned int i = prevNum; i < num; ++i )
{
this->SetNthInput( i, mitk::PointSet::New().GetPointer() );
}
}
void mitk::PointSetWriter::SetInput( InputType* pointSet )
{
this->ProcessObject::SetNthInput( 0, pointSet );
}
void mitk::PointSetWriter::SetInput( const unsigned int& id, InputType* pointSet )
{
if ( id >= this->GetNumberOfInputs() )
this->ResizeInputs( id + 1 );
this->ProcessObject::SetNthInput( id, pointSet );
}
mitk::PointSet* mitk::PointSetWriter::GetInput()
{
if ( this->GetNumberOfInputs() < 1 )
{
return 0;
}
else
{
return dynamic_cast<InputType*> ( this->GetInput( 0 ) );
}
}
mitk::PointSet* mitk::PointSetWriter::GetInput( const unsigned int& num )
{
return dynamic_cast<InputType*> ( this->ProcessObject::GetInput( num ) );
}
template < typename T>
std::string mitk::PointSetWriter::ConvertToString( T value )
{
std::ostringstream o;
std::locale I("C");
o.imbue(I);
if ( o << value )
{
return o.str();
}
else
return "conversion error";
}
void mitk::PointSetWriter::WriteXMLHeader( std::ofstream &file )
{
file << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
}
void mitk::PointSetWriter::WriteStartElement( const char *const tag, std::ofstream &file )
{
file << std::endl;
WriteIndent( file );
file << '<' << tag << '>';
m_IndentDepth++;
}
void mitk::PointSetWriter::WriteEndElement( const char *const tag, std::ofstream &file, const bool& indent )
{
m_IndentDepth--;
if ( indent )
{
file << std::endl;
WriteIndent( file );
}
file << '<' << '/' << tag << '>';
}
void mitk::PointSetWriter::WriteCharacterData( const char *const data, std::ofstream &file )
{
file << data;
}
void mitk::PointSetWriter::WriteStartElement( std::string &tag, std::ofstream &file )
{
WriteStartElement( tag.c_str(), file );
}
void mitk::PointSetWriter::WriteEndElement( std::string &tag, std::ofstream &file, const bool& indent )
{
WriteEndElement( tag.c_str(), file, indent );
}
void mitk::PointSetWriter::WriteCharacterData( std::string &data, std::ofstream &file )
{
WriteCharacterData( data.c_str(), file );
}
void mitk::PointSetWriter::WriteIndent( std::ofstream& file )
{
std::string spaces( m_IndentDepth * m_Indent, ' ' );
file << spaces.c_str();
}
bool mitk::PointSetWriter::GetSuccess() const
{
return m_Success;
}
bool mitk::PointSetWriter::CanWriteDataType( DataNode* input )
{
if ( input )
{
mitk::BaseData* data = input->GetData();
if ( data )
{
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>( data );
if( pointSet.IsNotNull() )
{
//this writer has no "SetDefaultExtension()" - function
m_Extension = ".mps";
return true;
}
}
}
return false;
}
void mitk::PointSetWriter::SetInput( DataNode* input )
{
if( input && CanWriteDataType( input ) )
this->ProcessObject::SetNthInput( 0, dynamic_cast<mitk::PointSet*>( input->GetData() ) );
}
std::string mitk::PointSetWriter::GetWritenMIMEType()
{
return m_MimeType;
}
std::vector<std::string> mitk::PointSetWriter::GetPossibleFileExtensions()
{
std::vector<std::string> possibleFileExtensions;
possibleFileExtensions.push_back(".mps");
return possibleFileExtensions;
}
std::string mitk::PointSetWriter::GetFileExtension()
{
return m_Extension;
}
diff --git a/Core/Code/IO/mitkPointSetWriter.h b/Core/Code/IO/mitkPointSetWriter.h
index be1b02f11f..43f16b297b 100644
--- a/Core/Code/IO/mitkPointSetWriter.h
+++ b/Core/Code/IO/mitkPointSetWriter.h
@@ -1,266 +1,265 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_POINT_SET_WRITER__H_
#define _MITK_POINT_SET_WRITER__H_
#include <itkProcessObject.h>
#include <mitkFileWriter.h>
#include <mitkPointSet.h>
namespace mitk
{
/**
* @brief XML-based writer for mitk::PointSets
*
* XML-based writer for mitk::PointSets. Multiple PointSets can be written in
* a single XML file by simply setting multiple inputs to the filter.
* Writing of multiple XML files according to a given filename pattern is not
* yet supported.
* @ingroup PSIO
* @ingroup Process
*/
class MITK_CORE_EXPORT PointSetWriter : public mitk::FileWriter
{
public:
mitkClassMacro( PointSetWriter, mitk::FileWriter );
mitkWriterMacro;
itkNewMacro( Self );
typedef mitk::PointSet InputType;
typedef InputType::Pointer InputTypePointer;
/**
* Sets the filename of the file to write.
* @param FileName the name of the file to write.
*/
itkSetStringMacro( FileName );
/**
* @returns the name of the file to be written to disk.
*/
itkGetStringMacro( FileName );
/**
* @warning multiple write not (yet) supported
*/
itkSetStringMacro( FilePrefix );
/**
* @warning multiple write not (yet) supported
*/
itkGetStringMacro( FilePrefix );
/**
* @warning multiple write not (yet) supported
*/
itkSetStringMacro( FilePattern );
/**
* @warning multiple write not (yet) supported
*/
itkGetStringMacro( FilePattern );
/**
* Sets the 0'th input object for the filter.
* @param input the first input for the filter.
*/
void SetInput( InputType* input );
/**
* Sets the n'th input object for the filter. If num is
* larger than GetNumberOfInputs() the number of inputs is
* resized appropriately.
* @param input the n'th input for the filter.
*/
void SetInput( const unsigned int& num, InputType* input);
/**
* @returns the 0'th input object of the filter.
*/
PointSet* GetInput();
/**
* @param num the index of the desired output object.
* @returns the n'th input object of the filter.
*/
PointSet* GetInput( const unsigned int& num );
/**
* @brief Return the possible file extensions for the data type associated with the writer
*/
virtual std::vector<std::string> GetPossibleFileExtensions();
/**
* @brief Return the extension to be added to the filename.
*/
virtual std::string GetFileExtension();
/**
* @brief Check if the Writer can write the Content of the
*/
virtual bool CanWriteDataType( DataNode* );
/**
* @brief Return the MimeType of the saved File.
*/
virtual std::string GetWritenMIMEType();
/**
* @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function.
*/
virtual void SetInput( DataNode* );
/**
* @returns whether the last write attempt was successful or not.
*/
bool GetSuccess() const;
protected:
/**
* Constructor.
*/
PointSetWriter();
/**
* Virtual destructor.
*/
virtual ~PointSetWriter();
/**
* Writes the XML file
*/
virtual void GenerateData();
/**
* Resizes the number of inputs of the writer.
* The inputs are initialized by empty PointSets
* @param num the new number of inputs
*/
virtual void ResizeInputs( const unsigned int& num );
/**
* Converts an arbitrary type to a string. The type has to
* support the << operator. This works fine at least for integral
* data types as float, int, long etc.
* @param value the value to convert
* @returns the string representation of value
*/
template < typename T>
std::string ConvertToString( T value );
/**
* Writes an XML representation of the given point set to
* an outstream. The XML-Header an root node is not included!
* @param pointSet the point set to be converted to xml
* @param out the stream to write to.
*/
void WriteXML( mitk::PointSet* pointSet, std::ofstream& out );
/**
* Writes an standard xml header to the given stream.
* @param file the stream in which the header is written.
*/
void WriteXMLHeader( std::ofstream &file );
/** Write a start element tag */
void WriteStartElement( const char *const tag, std::ofstream &file );
/**
* Write an end element tag
* End-Elements following character data should pass indent = false.
*/
void WriteEndElement( const char *const tag, std::ofstream &file, const bool& indent = true );
/** Write character data inside a tag. */
void WriteCharacterData( const char *const data, std::ofstream &file );
/** Write a start element tag */
void WriteStartElement( std::string &tag, std::ofstream &file );
/** Write an end element tag */
void WriteEndElement( std::string &tag, std::ofstream &file, const bool& indent = true );
/** Write character data inside a tag. */
void WriteCharacterData( std::string &data, std::ofstream &file );
/** Writes empty spaces to the stream according to m_IndentDepth and m_Indent */
void WriteIndent( std::ofstream& file );
std::string m_FileName;
std::string m_FilePrefix;
std::string m_FilePattern;
std::string m_Extension;
std::string m_MimeType;
unsigned int m_IndentDepth;
unsigned int m_Indent;
bool m_Success;
public:
static const char* XML_POINT_SET;
static const char* XML_TIME_SERIES;
static const char* XML_TIME_SERIES_ID;
static const char* XML_POINT_SET_FILE;
static const char* XML_FILE_VERSION;
static const char* XML_POINT;
static const char* XML_SPEC;
static const char* XML_ID;
static const char* XML_X;
static const char* XML_Y;
static const char* XML_Z;
static const char* VERSION_STRING;
};
}
#endif
diff --git a/Core/Code/IO/mitkPointSetWriterFactory.cpp b/Core/Code/IO/mitkPointSetWriterFactory.cpp
index bd1f76a7a5..7c2c2c2bdd 100644
--- a/Core/Code/IO/mitkPointSetWriterFactory.cpp
+++ b/Core/Code/IO/mitkPointSetWriterFactory.cpp
@@ -1,76 +1,75 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetWriterFactory.h"
#include "itkCreateObjectFunction.h"
#include "itkVersion.h"
#include "mitkPointSetWriter.h"
namespace mitk
{
template <class T>
class CreatePointSetWriter : public itk::CreateObjectFunctionBase
{
public:
/** Standard class typedefs. */
typedef CreatePointSetWriter Self;
typedef itk::SmartPointer<Self> Pointer;
/** Methods from itk:LightObject. */
itkFactorylessNewMacro(Self);
LightObject::Pointer CreateObject() { typename T::Pointer p = T::New();
p->Register();
return p.GetPointer();
}
protected:
CreatePointSetWriter() {}
~CreatePointSetWriter() {}
private:
CreatePointSetWriter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
PointSetWriterFactory::PointSetWriterFactory()
{
this->RegisterOverride("IOWriter",
"PointSetWriter",
"Point-Set Writer",
1,
mitk::CreatePointSetWriter<mitk::PointSetWriter>::New());
}
PointSetWriterFactory::~PointSetWriterFactory()
{
}
const char* PointSetWriterFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* PointSetWriterFactory::GetDescription() const
{
return "PointSetWriterFactory";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkPointSetWriterFactory.h b/Core/Code/IO/mitkPointSetWriterFactory.h
index 19993552e0..ffd6d1651c 100644
--- a/Core/Code/IO/mitkPointSetWriterFactory.h
+++ b/Core/Code/IO/mitkPointSetWriterFactory.h
@@ -1,64 +1,63 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 POINTSETWRITERFACTORY_H_HEADER_INCLUDED
#define POINTSETWRITERFACTORY_H_HEADER_INCLUDED
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
class MITK_CORE_EXPORT PointSetWriterFactory : public itk::ObjectFactoryBase
{
public:
mitkClassMacro( mitk::PointSetWriterFactory, itk::ObjectFactoryBase )
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
static bool IsRegistered = false;
if ( !IsRegistered )
{
PointSetWriterFactory::Pointer pointSetWriterFactory = PointSetWriterFactory::New();
ObjectFactoryBase::RegisterFactory( pointSetWriterFactory );
IsRegistered = true;
}
}
protected:
PointSetWriterFactory();
~PointSetWriterFactory();
private:
PointSetWriterFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkRawImageFileReader.cpp b/Core/Code/IO/mitkRawImageFileReader.cpp
index 9e7d4b562c..6611eda1ef 100644
--- a/Core/Code/IO/mitkRawImageFileReader.cpp
+++ b/Core/Code/IO/mitkRawImageFileReader.cpp
@@ -1,187 +1,186 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRawImageFileReader.h"
#include "mitkITKImageImport.h"
#include <itkImage.h>
#include <itkRawImageIO.h>
#include <itkImageFileReader.h>
mitk::RawImageFileReader::RawImageFileReader()
: m_FileName(""), m_FilePrefix(""), m_FilePattern("")
{
}
mitk::RawImageFileReader::~RawImageFileReader()
{
}
void mitk::RawImageFileReader::SetDimensions(unsigned int i, unsigned int dim)
{
if ( i > 2 ) return;
this->Modified(); // TODO: this order (first modified, then set the variable) is intended??
m_Dimensions[i] = dim;
}
unsigned int mitk::RawImageFileReader::GetDimensions(unsigned int i) const
{
if ( i > 2 ) return 0;
return m_Dimensions[i];
}
bool mitk::RawImageFileReader::CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern)
{
// First check the extension
if( filename == "" )
return false;
// check if image is serie
if( filePattern != "" && filePrefix != "" )
return false;
return true;
}
void mitk::RawImageFileReader::GenerateData()
{
mitk::Image::Pointer output = this->GetOutput();
if (this->GetOutput()==NULL)
{
MITK_INFO << "Error" << std::endl;
}
// Check to see if we can read the file given the name or prefix
if ( m_FileName == "" )
{
itkWarningMacro( << "File Type not supported!" );
return ;
}
// check file dimensionality and pixel type and perform reading according to it
if (m_Dimensionality == 2)
{
if (m_PixelType == SCHAR) TypedGenerateData<signed char, 2 >();
else if (m_PixelType == UCHAR) TypedGenerateData<unsigned char, 2 >();
else if (m_PixelType == SSHORT) TypedGenerateData<signed short int, 2 >();
else if (m_PixelType == USHORT) TypedGenerateData<unsigned short int, 2 >();
else if (m_PixelType == UINT) TypedGenerateData<unsigned int, 2 >();
else if (m_PixelType == SINT) TypedGenerateData<signed int, 2 >();
else if (m_PixelType == FLOAT) TypedGenerateData<float, 2 >();
else if (m_PixelType == DOUBLE) TypedGenerateData<double, 2 >();
else
{
MITK_INFO << "Error while reading raw file: Dimensionality or pixel type not supported or not properly set" << std::endl;
return;
}
}
else if (m_Dimensionality==3)
{
if (m_PixelType == SCHAR) TypedGenerateData<signed char, 3 >();
else if (m_PixelType == UCHAR) TypedGenerateData<unsigned char, 3 >();
else if (m_PixelType == SSHORT) TypedGenerateData<signed short int, 3 >();
else if (m_PixelType == USHORT) TypedGenerateData<unsigned short int, 3 >();
else if (m_PixelType == UINT) TypedGenerateData<unsigned int, 3 >();
else if (m_PixelType == SINT) TypedGenerateData<signed int, 3 >();
else if (m_PixelType == FLOAT) TypedGenerateData<float, 3 >();
else if (m_PixelType == DOUBLE) TypedGenerateData<double, 3 >();
else
{
MITK_INFO << "Error while reading raw file: Dimensionality or pixel type not supported or not properly set" << std::endl;
return;
}
}
else
{
MITK_INFO << "Error while reading raw file: Dimensionality not supported" << std::endl;
return;
}
MITK_INFO << "...reading raw finished!" << std::endl;
}
template < typename TPixel, unsigned int VImageDimensions >
void mitk::RawImageFileReader::TypedGenerateData()
{
mitk::Image::Pointer output = this->GetOutput();
if (this->GetOutput()==NULL)
{
MITK_INFO << "Error" << std::endl;
}
MITK_INFO << "loading " << m_FileName << " via itk::ImageIOFactory... " << std::endl;
// Check to see if we can read the file given the name or prefix
if ( m_FileName == "" )
{
itkWarningMacro( << "File Type not supported!" );
return ;
}
typedef itk::Image< TPixel, VImageDimensions > ImageType;
typedef itk::ImageFileReader< ImageType > ReaderType;
typedef itk::RawImageIO< TPixel, VImageDimensions > IOType;
typename ReaderType::Pointer reader = ReaderType::New();
typename IOType::Pointer io = IOType::New();
io->SetFileDimensionality(VImageDimensions);
for (unsigned short int dim = 0; dim < VImageDimensions; ++dim)
{
io->SetDimensions(dim, m_Dimensions[dim] );
}
if (m_Endianity == LITTLE)
{
io->SetByteOrderToLittleEndian();
}
else if (m_Endianity == BIG)
{
io->SetByteOrderToBigEndian();
}
else
{
MITK_INFO << "Warning: endianity not properly set. Resulting image might be incorrect";
}
reader->SetImageIO( io );
reader->SetFileName(m_FileName.c_str());
try
{
reader->Update();
}
catch( itk::ExceptionObject & err )
{
MITK_ERROR <<"An error occurred during the raw image reading process: ";
MITK_INFO << err << std::endl;
}
mitk::Image::Pointer image = mitk::Image::New();
mitk::CastToMitkImage(reader->GetOutput(), image);
output->Initialize( image );
output->SetVolume( reader->GetOutput()->GetBufferPointer());
}
diff --git a/Core/Code/IO/mitkRawImageFileReader.h b/Core/Code/IO/mitkRawImageFileReader.h
index 4ca70779f0..835f0512a7 100644
--- a/Core/Code/IO/mitkRawImageFileReader.h
+++ b/Core/Code/IO/mitkRawImageFileReader.h
@@ -1,111 +1,110 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 RawImageFileReader_H_HEADER_INCLUDED
#define RawImageFileReader_H_HEADER_INCLUDED
#include "itkVector.h"
#include <MitkExports.h>
#include "mitkFileReader.h"
#include "mitkImageSource.h"
namespace mitk
{
//##Documentation
//## @brief Reader to read raw image files
/** The user must set the dimensionality, the dimensions and the pixel type. If they are incorrect, the image will not be opened or the visualization will be incorrect. */
//## @ingroup IO
class MITK_CORE_EXPORT RawImageFileReader : public ImageSource, public FileReader
{
public:
mitkClassMacro(RawImageFileReader, FileReader);
/** Method for creation through the object factory. */
itkNewMacro(Self);
itkSetMacro(FileName, std::string);
itkSetStringMacro(FileName);
itkGetMacro(FileName, std::string);
itkGetStringMacro(FileName);
itkSetMacro(FilePrefix, std::string);
itkSetStringMacro(FilePrefix);
itkGetMacro(FilePrefix, std::string);
itkGetStringMacro(FilePrefix);
itkSetMacro(FilePattern, std::string);
itkSetStringMacro(FilePattern);
itkGetMacro(FilePattern, std::string);
itkGetStringMacro(FilePattern);
/** Supported pixel types. */
typedef enum {UCHAR,SCHAR,USHORT,SSHORT, UINT, SINT, FLOAT, DOUBLE} IOPixelType;
itkSetMacro(PixelType, IOPixelType);
/** Endianity of bits. */
typedef enum {LITTLE, BIG} EndianityType;
itkSetMacro(Endianity, EndianityType);
itkSetMacro(Dimensionality, int);
itkGetMacro(Dimensionality, int);
/** Image dimensions must be set one by one, starting from dimension 0. */
void SetDimensions(unsigned int i, unsigned int dim);
unsigned int GetDimensions(unsigned int i) const;
static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
protected:
RawImageFileReader();
~RawImageFileReader();
virtual void GenerateData();
template < typename TPixel, unsigned int VImageDimensions > void TypedGenerateData();
/** Name of file to be read.*/
std::string m_FileName;
/** File prefix. */
std::string m_FilePrefix;
/** File pattern. */
std::string m_FilePattern;
/** Pixel type of image to be read. Must be of type IOPixelType. */
IOPixelType m_PixelType;
/** Dimensionality of file to be read. Can be 2 or 3. */
int m_Dimensionality;
/** Endianity. Must be set to LITTLE or BIG. Default is BIG. */
EndianityType m_Endianity;
/** Vector containing dimensions of image to be read. */
itk::Vector<int, 3> m_Dimensions;
};
} // namespace mitk
#endif /* RawImageFileReader_H_HEADER_INCLUDED */
diff --git a/Core/Code/IO/mitkSTLFileIOFactory.cpp b/Core/Code/IO/mitkSTLFileIOFactory.cpp
index 42cb1dea13..68f44046ae 100644
--- a/Core/Code/IO/mitkSTLFileIOFactory.cpp
+++ b/Core/Code/IO/mitkSTLFileIOFactory.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSTLFileIOFactory.h"
#include "mitkIOAdapter.h"
#include "mitkSTLFileReader.h"
#include "itkVersion.h"
namespace mitk
{
STLFileIOFactory::STLFileIOFactory()
{
this->RegisterOverride("mitkIOAdapter",
"mitkSTLFileReader",
"mitk STL Surface IO",
1,
itk::CreateObjectFunction<IOAdapter<STLFileReader> >::New());
}
STLFileIOFactory::~STLFileIOFactory()
{
}
const char* STLFileIOFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* STLFileIOFactory::GetDescription() const
{
return "STLFile IO Factory, allows the loading of STL files";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkSTLFileIOFactory.h b/Core/Code/IO/mitkSTLFileIOFactory.h
index ef73ed20d4..48c51fe19f 100644
--- a/Core/Code/IO/mitkSTLFileIOFactory.h
+++ b/Core/Code/IO/mitkSTLFileIOFactory.h
@@ -1,72 +1,71 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkSTLFileIOFactory_h
#define __mitkSTLFileIOFactory_h
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
//##Documentation
//## @brief Create instances of STLFileReader objects using an object factory.
//##
//## @ingroup IO
class MITK_CORE_EXPORT STLFileIOFactory : public itk::ObjectFactoryBase
{
public:
/** Standard class typedefs. */
typedef STLFileIOFactory Self;
typedef itk::ObjectFactoryBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
static STLFileIOFactory* FactoryNew() { return new STLFileIOFactory;}
/** Run-time type information (and related methods). */
itkTypeMacro(STLFileIOFactory, ObjectFactoryBase);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
STLFileIOFactory::Pointer STLFileIOFactory = STLFileIOFactory::New();
ObjectFactoryBase::RegisterFactory(STLFileIOFactory);
}
protected:
STLFileIOFactory();
~STLFileIOFactory();
private:
STLFileIOFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkSTLFileReader.cpp b/Core/Code/IO/mitkSTLFileReader.cpp
index dc54f90516..ee2862ed1f 100644
--- a/Core/Code/IO/mitkSTLFileReader.cpp
+++ b/Core/Code/IO/mitkSTLFileReader.cpp
@@ -1,95 +1,94 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSTLFileReader.h"
#include <mitkSurface.h>
#include <vtkSmartPointer.h>
#include <vtkSTLReader.h>
#include <vtkPolyData.h>
#include <vtkPolyDataNormals.h>
#include <vtkCleanPolyData.h>
mitk::STLFileReader::STLFileReader() : mitk::SurfaceSource(), m_FileName("")
{
}
mitk::STLFileReader::~STLFileReader()
{
}
void mitk::STLFileReader::GenerateData()
{
mitk::Surface::Pointer output = this->GetOutput();
if( m_FileName != "")
{
MITK_INFO << "Loading " << m_FileName << " as stl..." << std::endl;
vtkSmartPointer<vtkSTLReader> stlReader = vtkSmartPointer<vtkSTLReader>::New();
stlReader->SetFileName( m_FileName.c_str() );
vtkSmartPointer<vtkPolyDataNormals> normalsGenerator = vtkSmartPointer<vtkPolyDataNormals>::New();
normalsGenerator->SetInput( stlReader->GetOutput() );
vtkSmartPointer<vtkCleanPolyData> cleanPolyDataFilter = vtkSmartPointer<vtkCleanPolyData>::New();
cleanPolyDataFilter->SetInput(normalsGenerator->GetOutput());
cleanPolyDataFilter->PieceInvariantOff();
cleanPolyDataFilter->ConvertLinesToPointsOff();
cleanPolyDataFilter->ConvertPolysToLinesOff();
cleanPolyDataFilter->ConvertStripsToPolysOff();
cleanPolyDataFilter->PointMergingOn();
cleanPolyDataFilter->Update();
if ( ( stlReader->GetOutput() != NULL ) && ( cleanPolyDataFilter->GetOutput() != NULL ) )
{
vtkSmartPointer<vtkPolyData> surfaceWithNormals = cleanPolyDataFilter->GetOutput();
output->SetVtkPolyData( surfaceWithNormals );
}
}
}
bool mitk::STLFileReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
{
// First check the extension
if( filename == "" )
{
//MITK_INFO<<"No filename specified."<<std::endl;
return false;
}
bool extensionFound = false;
std::string::size_type STLPos = filename.rfind(".stl");
if ((STLPos != std::string::npos)
&& (STLPos == filename.length() - 4))
{
extensionFound = true;
}
STLPos = filename.rfind(".STL");
if ((STLPos != std::string::npos)
&& (STLPos == filename.length() - 4))
{
extensionFound = true;
}
if( !extensionFound )
{
//MITK_INFO<<"The filename extension is not recognized."<<std::endl;
return false;
}
return true;
}
diff --git a/Core/Code/IO/mitkSTLFileReader.h b/Core/Code/IO/mitkSTLFileReader.h
index 7bbea7bd47..bba0008e71 100644
--- a/Core/Code/IO/mitkSTLFileReader.h
+++ b/Core/Code/IO/mitkSTLFileReader.h
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 STLFileReader_H_HEADER_INCLUDED
#define STLFileReader_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkSurfaceSource.h"
namespace mitk {
//##Documentation
//## @brief Reader to read files in stl-format
//## @ingroup IO
class MITK_CORE_EXPORT STLFileReader : public SurfaceSource
{
public:
mitkClassMacro(STLFileReader, SurfaceSource);
/** Method for creation through the object factory. */
itkNewMacro(Self);
itkSetStringMacro(FileName);
itkGetStringMacro(FileName);
itkSetStringMacro(FilePrefix);
itkGetStringMacro(FilePrefix);
itkSetStringMacro(FilePattern);
itkGetStringMacro(FilePattern);
static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
protected:
virtual void GenerateData();
STLFileReader();
~STLFileReader();
std::string m_FileName, m_FilePrefix, m_FilePattern;
};
} // namespace mitk
#endif /* STLFileReader_H_HEADER_INCLUDED */
diff --git a/Core/Code/IO/mitkStandardFileLocations.cpp b/Core/Code/IO/mitkStandardFileLocations.cpp
index b49c5ad895..bf16cdd046 100644
--- a/Core/Code/IO/mitkStandardFileLocations.cpp
+++ b/Core/Code/IO/mitkStandardFileLocations.cpp
@@ -1,242 +1,241 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <mitkStandardFileLocations.h>
#include <mitkConfig.h>
#include <itkObject.h>
#include <itkMacro.h>
#include <itksys/SystemTools.hxx>
#include <algorithm>
mitk::StandardFileLocations::StandardFileLocations()
{
}
mitk::StandardFileLocations::~StandardFileLocations()
{
}
mitk::StandardFileLocations* mitk::StandardFileLocations::GetInstance()
{
static StandardFileLocations::Pointer m_Instance = 0;
if(m_Instance.IsNull())
m_Instance = StandardFileLocations::New();
return m_Instance;
}
void mitk::StandardFileLocations::AddDirectoryForSearch(const char * dir, bool insertInFrontOfSearchList)
{
std::string directory = dir;
// Do nothing if directory is already included into search list (TODO more clever: search only once!)
FileSearchVectorType::iterator iter;
if(m_SearchDirectories.size() > 0)
{
iter = std::find(m_SearchDirectories.begin(), m_SearchDirectories.end(),std::string(dir));
if ( iter != m_SearchDirectories.end() )
return;
}
// insert dir into queue
if(insertInFrontOfSearchList)
{
FileSearchVectorType::iterator it = m_SearchDirectories.begin();
m_SearchDirectories.insert(it,std::string(dir));
}
else
m_SearchDirectories.push_back(std::string(dir));
}
void mitk::StandardFileLocations::RemoveDirectoryForSearch(const char * dir)
{
FileSearchVectorType::iterator it;
// background layers
if(m_SearchDirectories.size() > 0)
{
it = std::find(m_SearchDirectories.begin(), m_SearchDirectories.end(),std::string(dir));
if(it != m_SearchDirectories.end())
{
m_SearchDirectories.erase(it);
return;
}
}
}
std::string mitk::StandardFileLocations::SearchDirectoriesForFile(const char * filename)
{
FileSearchVectorType::iterator it;
for(it = m_SearchDirectories.begin(); it != m_SearchDirectories.end(); it++)
{
std::string currDir = (*it);
// Perhaps append "/" before appending filename
if(currDir.find_last_of("\\")+1 != currDir.size() || currDir.find_last_of("/")+1 != currDir.size())
currDir += "/";
// Append filename
currDir += filename;
// Perhaps remove "/" after filename
if(currDir.find_last_of("\\")+1 == currDir.size() || currDir.find_last_of("/")+1 == currDir.size())
currDir.erase(currDir.size()-1,currDir.size());
// convert to OS dependent path schema
currDir = itksys::SystemTools::ConvertToOutputPath(currDir.c_str());
// On windows systems, the ConvertToOutputPath method quotes pathes that contain empty spaces.
// These quotes are not expected by the FileExists method and therefore removed, if existing.
if(currDir.find_last_of("\"")+1 == currDir.size())
currDir.erase(currDir.size()-1,currDir.size());
if(currDir.find_last_of("\"") == 0)
currDir.erase(0,1);
// Return first found path
if(itksys::SystemTools::FileExists(currDir.c_str()))
return currDir;
}
return std::string("");
}
std::string mitk::StandardFileLocations::FindFile(const char* filename, const char* pathInSourceDir)
{
std::string directoryPath;
// 1. look for MITKCONF environment variable
const char* mitkConf = itksys::SystemTools::GetEnv("MITKCONF");
if (mitkConf!=NULL)
AddDirectoryForSearch(mitkConf, false);
// 2. use .mitk-subdirectory in home directory of the user
#if defined(_WIN32) && !defined(__CYGWIN__)
const char* homeDrive = itksys::SystemTools::GetEnv("HOMEDRIVE");
const char* homePath = itksys::SystemTools::GetEnv("HOMEPATH");
if((homeDrive!=NULL) || (homePath!=NULL))
{
directoryPath = homeDrive;
directoryPath += homePath;
directoryPath += "/.mitk/";
AddDirectoryForSearch(directoryPath.c_str(), false);
}
#else
const char* homeDirectory = itksys::SystemTools::GetEnv("HOME");
if(homeDirectory != NULL)
{
directoryPath = homeDirectory;
directoryPath += "/.mitk/";
AddDirectoryForSearch(directoryPath.c_str(), false);
}
#endif // defined(_WIN32) && !defined(__CYGWIN__)
// 3. look in the current working directory
directoryPath = "";
AddDirectoryForSearch(directoryPath.c_str());
directoryPath = itksys::SystemTools::GetCurrentWorkingDirectory();
AddDirectoryForSearch(directoryPath.c_str(), false);
std::string directoryBinPath = directoryPath + "/bin";
AddDirectoryForSearch(directoryBinPath.c_str(), false);
// 4. use a source tree location from compile time
directoryPath = MITK_ROOT;
if (pathInSourceDir)
{
directoryPath += pathInSourceDir;
}
directoryPath += '/';
AddDirectoryForSearch(directoryPath.c_str(), false);
return SearchDirectoriesForFile(filename);
}
std::string mitk::StandardFileLocations::GetOptionDirectory()
{
const char* mitkoptions = itksys::SystemTools::GetEnv("MITKOPTIONS");
std::string optionsDirectory;
if (mitkoptions!=NULL)
{
// 1. look for MITKOPTIONS environment variable
optionsDirectory = mitkoptions;
optionsDirectory += "/";
}
else
{
// 2. use .mitk-subdirectory in home directory of the user
std::string homeDirectory;
#if defined(_WIN32) && !defined(__CYGWIN__)
const char* homeDrive = itksys::SystemTools::GetEnv("HOMEDRIVE");
const char* homePath = itksys::SystemTools::GetEnv("HOMEPATH");
if((homeDrive==NULL) || (homePath==NULL))
{
itkGenericOutputMacro( << "Environment variables HOMEDRIVE and/or HOMEPATH not set" <<
". Using current working directory as home directory: " << itksys::SystemTools::GetCurrentWorkingDirectory());
homeDirectory = itksys::SystemTools::GetCurrentWorkingDirectory();
}
else
{
homeDirectory = homeDrive;
homeDirectory +=homePath;
}
if(itksys::SystemTools::FileExists(homeDirectory.c_str())==false)
{
itkGenericOutputMacro( << "Could not find home directory at " << homeDirectory <<
". Using current working directory as home directory: " << itksys::SystemTools::GetCurrentWorkingDirectory());
homeDirectory = itksys::SystemTools::GetCurrentWorkingDirectory();
}
#else
const char* home = itksys::SystemTools::GetEnv("HOME");
if(home==NULL)
{
itkGenericOutputMacro( << "Environment variable HOME not set" <<
". Using current working directory as home directory: " << itksys::SystemTools::GetCurrentWorkingDirectory());
homeDirectory = itksys::SystemTools::GetCurrentWorkingDirectory();
}
else
homeDirectory = home;
if(itksys::SystemTools::FileExists(homeDirectory.c_str())==false)
{
itkGenericOutputMacro( << "Could not find home directory at " << homeDirectory <<
". Using current working directory as home directory: " << itksys::SystemTools::GetCurrentWorkingDirectory());
homeDirectory = itksys::SystemTools::GetCurrentWorkingDirectory();
}
#endif // defined(_WIN32) && !defined(__CYGWIN__)
optionsDirectory = homeDirectory;
optionsDirectory += "/.mitk";
}
optionsDirectory = itksys::SystemTools::ConvertToOutputPath(optionsDirectory.c_str());
if(itksys::SystemTools::CountChar(optionsDirectory.c_str(),'"') > 0)
{
char * unquoted = itksys::SystemTools::RemoveChars(optionsDirectory.c_str(),"\"");
optionsDirectory = unquoted;
delete [] unquoted;
}
if(itksys::SystemTools::MakeDirectory(optionsDirectory.c_str())==false)
{
itkGenericExceptionMacro( << "Could not create .mitk directory at " << optionsDirectory );
}
return optionsDirectory;
}
diff --git a/Core/Code/IO/mitkStandardFileLocations.h b/Core/Code/IO/mitkStandardFileLocations.h
index a8a9f6694b..3a1ce8850e 100644
--- a/Core/Code/IO/mitkStandardFileLocations.h
+++ b/Core/Code/IO/mitkStandardFileLocations.h
@@ -1,117 +1,116 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITK_STANDARD_FILE_LOCATIONS_H_INCLUDED_SWDG
#define MITK_STANDARD_FILE_LOCATIONS_H_INCLUDED_SWDG
#include <string>
#include <itkObject.h>
#include <itkObjectFactory.h>
#include <MitkExports.h>
namespace mitk
{
/*! \brief Provides a method to look for configuration and option files etc.
Call mitk::StandardFileLocations::FindFile(filename) to look for configuration files.
Call mitk::StandardFileLocations::GetOptionDirectory() to look for/save option files.
*/
class MITK_CORE_EXPORT StandardFileLocations : public itk::Object
{
public:
typedef StandardFileLocations Self;
typedef itk::Command Superclass;
typedef itk::SmartPointer<Self> Pointer;
/*!
\brief Adds a directory into the search queue:
\ Use this function in combination with FindFile(), after adding some
\ directories, they will also be searched for the requested file
\param dir directory you want to be searched in
\param insertInFrontOfSearchList wheather this search request shall be processed first
*/
void AddDirectoryForSearch(const char * dir, bool insertInFrontOfSearchList = true);
/*!
\brief Remove a directory from the search queue:
\ Use this function in combination with FindFile().
\
\param dir directory you want to be searched in
*/
void RemoveDirectoryForSearch(const char * dir);
/*!
\brief looks for a file in several standard locations
\param filename The file you want to fine, without any path
\param pathInSourceDir Where in the source tree hierarchy would that file be?
\return The absolute path to the file including the filename
This method appends several standard locations to the end of the searchqueue (if they not already exist)
and then searches for the file within all directories contained in the search queue:
1. Add the directory specified in the environment variable MITKCONF
2. Add the .mitk directory in the home folder of the user
3. Add the current working directory
4. Add the (current working directory)/bin directory
5. Add the directory specified in pathInSourceDir, that is relative to the source code directory root (which is determined at compile time)
Already added directories in the searchqueue by using AddDirectoryForSearch before calling FindFile are still searched first,
because above mentioned standard locations are always appended at the end of the list.
*/
std::string FindFile(const char* filename, const char* pathInSourceDir = NULL );
/*!
\brief Return directory of/for option files
\return The absolute path to the directory for option files.
This method looks for the directory of/for option files in two ways. The logic is as follows
1. If there is an environment variable MITKOPTIONS, then use that directory.
2. Use .mitk-subdirectory in home directory of the user
The directory will be created if it does not exist.
*/
std::string GetOptionDirectory();
static StandardFileLocations* GetInstance();
protected:
itkNewMacro( Self );
typedef std::vector<std::string> FileSearchVectorType;
FileSearchVectorType m_SearchDirectories;
StandardFileLocations();
virtual ~StandardFileLocations();
std::string SearchDirectoriesForFile(const char * filename);
private:
// Private Copy Constructor
StandardFileLocations( const StandardFileLocations& );
};
} // namespace
#endif
diff --git a/Core/Code/IO/mitkSurfaceVtkWriter.cpp b/Core/Code/IO/mitkSurfaceVtkWriter.cpp
index a274b78f72..4903183717 100644
--- a/Core/Code/IO/mitkSurfaceVtkWriter.cpp
+++ b/Core/Code/IO/mitkSurfaceVtkWriter.cpp
@@ -1,89 +1,88 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <vtkErrorCode.h>
#include "mitkSurfaceVtkWriter.h"
#include "mitkSurfaceVtkWriter.txx"
namespace mitk {
template<>
void SurfaceVtkWriter<vtkSTLWriter>::SetDefaultExtension()
{
m_Extension = ".stl";
m_WriterWriteHasReturnValue = false;
}
template<>
void SurfaceVtkWriter<vtkPolyDataWriter>::SetDefaultExtension()
{
m_Extension = ".vtk";
m_WriterWriteHasReturnValue = false;
}
template<>
void SurfaceVtkWriter<vtkXMLPolyDataWriter>::SetDefaultExtension()
{
m_Extension = ".vtp";
m_WriterWriteHasReturnValue = true;
}
template<>
void SurfaceVtkWriter<vtkXMLPolyDataWriter>::ExecuteWrite( VtkWriterType* vtkWriter )
{
if ( vtkWriter->Write() == 0 || vtkWriter->GetErrorCode() != 0 )
{
itkExceptionMacro(<<"Error during surface writing: " << vtkErrorCode::GetStringFromErrorCode(vtkWriter->GetErrorCode()) );
}
}
template<>
std::vector<std::string> SurfaceVtkWriter<vtkSTLWriter>::GetPossibleFileExtensions()
{
std::vector<std::string> possibleFileExtensions;
possibleFileExtensions.push_back(".stl");
possibleFileExtensions.push_back(".obj");
return possibleFileExtensions;
}
template<>
std::vector<std::string> SurfaceVtkWriter<vtkPolyDataWriter>::GetPossibleFileExtensions()
{
std::vector<std::string> possibleFileExtensions;
possibleFileExtensions.push_back(".vtk");
possibleFileExtensions.push_back(".obj");
return possibleFileExtensions;
}
template<>
std::vector<std::string> SurfaceVtkWriter<vtkXMLPolyDataWriter>::GetPossibleFileExtensions()
{
std::vector<std::string> possibleFileExtensions;
possibleFileExtensions.push_back(".vtp");
possibleFileExtensions.push_back(".obj");
return possibleFileExtensions;
}
template class SurfaceVtkWriter<vtkSTLWriter>;
template class SurfaceVtkWriter<vtkPolyDataWriter>;
template class SurfaceVtkWriter<vtkXMLPolyDataWriter>;
}
diff --git a/Core/Code/IO/mitkSurfaceVtkWriter.h b/Core/Code/IO/mitkSurfaceVtkWriter.h
index 72b7484194..35e70dc087 100644
--- a/Core/Code/IO/mitkSurfaceVtkWriter.h
+++ b/Core/Code/IO/mitkSurfaceVtkWriter.h
@@ -1,203 +1,202 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_SURFACE_VTK_WRITER__H_
#define _MITK_SURFACE_VTK_WRITER__H_
#include <iomanip>
#include <vtkSTLWriter.h>
#include <vtkPolyDataWriter.h>
#include <vtkXMLPolyDataWriter.h>
#include <itkProcessObject.h>
#include <mitkFileWriter.h>
#include <mitkPointSet.h>
#include <mitkSurface.h>
#include <vtkSmartPointer.h>
class vtkTransformPolyDataFilter;
namespace mitk
{
/**
* @brief VTK-based writer for mitk::Surface
*
* The mitk::Surface is written using the VTK-writer-type provided as the
* template argument. If the mitk::Surface contains multiple points of
* time, multiple files are written. The life-span (time-bounds) of each
* each point of time is included in the filename according to the
* following scheme:
* &lt;filename&gt;_S&lt;timebounds[0]&gt;E&lt;timebounds[1]&gt;_T&lt;framenumber&gt;
* (S=start, E=end, T=time).
* Writing of multiple files according to a given filename pattern is not
* yet supported.
* @ingroup Process
*/
template <class VTKWRITER>
class MITK_CORE_EXPORT SurfaceVtkWriter : public mitk::FileWriter
{
public:
mitkClassMacro( SurfaceVtkWriter, mitk::FileWriter );
itkNewMacro( Self );
mitkWriterMacro;
typedef VTKWRITER VtkWriterType;
/**
* Sets the filename of the file to write.
* @param _arg the name of the file to write.
*/
itkSetStringMacro( FileName );
/**
* @returns the name of the file to be written to disk.
*/
itkGetStringMacro( FileName );
/**
* \brief Explicitly set the extension to be added to the filename.
* @param _arg to be added to the filename, including a "."
* (e.g., ".vtk").
*
* Partial template specialization is used for some vtk-writer types
* to set a default extension.
*/
itkSetStringMacro( Extension );
/**
* \brief Get the extension to be added to the filename.
* @returns the extension to be added to the filename (e.g.,
* ".vtk").
*/
itkGetStringMacro( Extension );
/**
* \brief Set the extension to be added to the filename to the default
*
* Partial template specialization is used for some vtk-writer types
* to define the default extension.
*/
void SetDefaultExtension();
/**
* @warning multiple write not (yet) supported
*/
itkSetStringMacro( FilePrefix );
/**
* @warning multiple write not (yet) supported
*/
itkGetStringMacro( FilePrefix );
/**
* @warning multiple write not (yet) supported
*/
itkSetStringMacro( FilePattern );
/**
* @warning multiple write not (yet) supported
*/
itkGetStringMacro( FilePattern );
/**
* Sets the 0'th input object for the filter.
* @param input the first input for the filter.
*/
void SetInput( mitk::Surface* input );
/**
* @returns the 0'th input object of the filter.
*/
const mitk::Surface* GetInput();
/**
* @brief Return the extension to be added to the filename.
*/
virtual std::string GetFileExtension();
/**
* @brief Check if the Writer can write the Content of the DataTreenode.
*/
virtual bool CanWriteDataType( DataNode* );
/**
* @brief Return the MimeType of the saved File.
*/
virtual std::string GetWritenMIMEType();
/**
* @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function.
*/
virtual void SetInput( DataNode* );
VtkWriterType* GetVtkWriter()
{
return m_VtkWriter;
}
/**
* @brief Return the possible file extensions for the data type associated with the writer
*/
virtual std::vector<std::string> GetPossibleFileExtensions();
protected:
/**
* Constructor.
*/
SurfaceVtkWriter();
/**
* Virtual destructor.
*/
virtual ~SurfaceVtkWriter();
virtual void GenerateData();
void ExecuteWrite( VtkWriterType* vtkWriter );
std::string m_FileName;
std::string m_FilePrefix;
std::string m_FilePattern;
std::string m_Extension;
std::string m_MimeType;
vtkSmartPointer<VtkWriterType> m_VtkWriter;
bool m_WriterWriteHasReturnValue;
};
#ifndef Mitk_EXPORTS
extern template class SurfaceVtkWriter<vtkSTLWriter>;
extern template class SurfaceVtkWriter<vtkPolyDataWriter>;
extern template class SurfaceVtkWriter<vtkXMLPolyDataWriter>;
#endif
}
#endif //_MITK_SURFACE_VTK_WRITER__H_
diff --git a/Core/Code/IO/mitkSurfaceVtkWriter.txx b/Core/Code/IO/mitkSurfaceVtkWriter.txx
index 9f1f549f55..971a762d18 100644
--- a/Core/Code/IO/mitkSurfaceVtkWriter.txx
+++ b/Core/Code/IO/mitkSurfaceVtkWriter.txx
@@ -1,175 +1,174 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurfaceVtkWriter.h"
#include <vtkConfigure.h>
#include <vtkPolyData.h>
#include <vtkLinearTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkErrorCode.h>
#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
template <class VTKWRITER>
mitk::SurfaceVtkWriter<VTKWRITER>::SurfaceVtkWriter()
: m_WriterWriteHasReturnValue( false )
{
this->SetNumberOfRequiredInputs( 1 );
m_VtkWriter = vtkSmartPointer<VtkWriterType>::New();
//enable to write ascii-formatted-file
//m_VtkWriter->SetFileTypeToASCII();
SetDefaultExtension(); // and information about the Writer's Write() method
}
template <class VTKWRITER>
mitk::SurfaceVtkWriter<VTKWRITER>::~SurfaceVtkWriter()
{
}
template <class VTKWRITER>
void mitk::SurfaceVtkWriter<VTKWRITER>::SetDefaultExtension()
{
m_Extension = ".vtk";
}
template<class VTKWRITER>
void mitk::SurfaceVtkWriter<VTKWRITER>::ExecuteWrite( VtkWriterType* vtkWriter )
{
if ( vtkWriter->Write() == 0 || vtkWriter->GetErrorCode() != 0 )
{
itkExceptionMacro(<<"Error during surface writing: " << vtkErrorCode::GetStringFromErrorCode(vtkWriter->GetErrorCode()) );
}
}
template <class VTKWRITER>
void mitk::SurfaceVtkWriter<VTKWRITER>::GenerateData()
{
if ( m_FileName == "" )
{
itkWarningMacro( << "Sorry, filename has not been set!" );
return ;
}
mitk::Surface::Pointer input = const_cast<mitk::Surface*>(this->GetInput());
vtkSmartPointer<vtkTransformPolyDataFilter> transformPolyData = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
vtkPolyData * polyData;
Geometry3D* geometry;
unsigned int t, timesteps = input->GetTimeSlicedGeometry()->GetTimeSteps();
for(t = 0; t < timesteps; ++t)
{
// surfaces do not have to exist in all timeteps; therefor, only write valid surfaces
if( input->GetVtkPolyData(t) == NULL ) continue;
::itk::OStringStream filename;
filename.imbue(::std::locale::classic());
geometry = input->GetGeometry(t);
if ( timesteps > 1 )
{
if(input->GetTimeSlicedGeometry()->IsValidTime(t))
{
const TimeBounds& timebounds = geometry->GetTimeBounds();
filename << m_FileName.c_str() << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << m_Extension;
}
else
{
itkWarningMacro(<<"Error on write: TimeSlicedGeometry invalid of surface " << filename << ".");
filename << m_FileName.c_str() << "_T" << t << m_Extension;
}
m_VtkWriter->SetFileName(filename.str().c_str());
}
else
m_VtkWriter->SetFileName(m_FileName.c_str());
geometry->TransferItkToVtkTransform();
transformPolyData->SetInput(input->GetVtkPolyData(t));
transformPolyData->SetTransform(geometry->GetVtkTransform());
transformPolyData->UpdateWholeExtent();
polyData = transformPolyData->GetOutput();
m_VtkWriter->SetInput(polyData);
ExecuteWrite( m_VtkWriter );
}
m_MimeType = "application/MITK.Surface";
}
template <class VTKWRITER>
void mitk::SurfaceVtkWriter<VTKWRITER>::SetInput( mitk::Surface* surface )
{
this->ProcessObject::SetNthInput( 0, surface );
}
template <class VTKWRITER>
const mitk::Surface* mitk::SurfaceVtkWriter<VTKWRITER>::GetInput()
{
if ( this->GetNumberOfInputs() < 1 )
{
return NULL;
}
else
{
return static_cast< const Surface * >( this->ProcessObject::GetInput( 0 ) );
}
}
template <class VTKWRITER>
bool mitk::SurfaceVtkWriter<VTKWRITER>::CanWriteDataType( DataNode* input )
{
if ( input )
{
BaseData* data = input->GetData();
if ( data )
{
Surface::Pointer surface = dynamic_cast<Surface*>( data );
if( surface.IsNotNull() )
{
SetDefaultExtension();
return true;
}
}
}
return false;
}
template <class VTKWRITER>
void mitk::SurfaceVtkWriter<VTKWRITER>::SetInput( DataNode* input )
{
if( input && CanWriteDataType( input ) )
SetInput( dynamic_cast<Surface*>( input->GetData() ) );
}
template <class VTKWRITER>
std::string mitk::SurfaceVtkWriter<VTKWRITER>::GetWritenMIMEType()
{
return m_MimeType;
}
template <class VTKWRITER>
std::string mitk::SurfaceVtkWriter<VTKWRITER>::GetFileExtension()
{
return m_Extension;
}
diff --git a/Core/Code/IO/mitkSurfaceVtkWriterFactory.cpp b/Core/Code/IO/mitkSurfaceVtkWriterFactory.cpp
index d7e8216e30..165d3f1035 100644
--- a/Core/Code/IO/mitkSurfaceVtkWriterFactory.cpp
+++ b/Core/Code/IO/mitkSurfaceVtkWriterFactory.cpp
@@ -1,77 +1,76 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurfaceVtkWriterFactory.h"
#include "itkCreateObjectFunction.h"
#include "itkVersion.h"
#include <mitkSurfaceVtkWriter.h>
#include <vtkXMLPolyDataWriter.h>
namespace mitk
{
template <class T>
class CreateSurfaceWriter : public itk::CreateObjectFunctionBase
{
public:
/** Standard class typedefs. */
typedef CreateSurfaceWriter Self;
typedef itk::SmartPointer<Self> Pointer;
/** Methods from itk:LightObject. */
itkFactorylessNewMacro(Self);
LightObject::Pointer CreateObject() { typename T::Pointer p = T::New();
p->Register();
return p.GetPointer();
}
protected:
CreateSurfaceWriter() {}
~CreateSurfaceWriter() {}
private:
CreateSurfaceWriter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
SurfaceVtkWriterFactory::SurfaceVtkWriterFactory()
{
this->RegisterOverride("IOWriter",
"SurfaceVtkWriter",
"Surface Vtk Writer",
1,
mitk::CreateSurfaceWriter< mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter> >::New());
}
SurfaceVtkWriterFactory::~SurfaceVtkWriterFactory()
{
}
const char* SurfaceVtkWriterFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* SurfaceVtkWriterFactory::GetDescription() const
{
return "SurfaceVtkWriterFactory";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkSurfaceVtkWriterFactory.h b/Core/Code/IO/mitkSurfaceVtkWriterFactory.h
index c32d0d9565..a2a1042f38 100644
--- a/Core/Code/IO/mitkSurfaceVtkWriterFactory.h
+++ b/Core/Code/IO/mitkSurfaceVtkWriterFactory.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 SURFACEWRITERFACTORY_H_HEADER_INCLUDED
#define SURFACEWRITERFACTORY_H_HEADER_INCLUDED
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
class MITK_CORE_EXPORT SurfaceVtkWriterFactory : public itk::ObjectFactoryBase
{
public:
mitkClassMacro( mitk::SurfaceVtkWriterFactory, itk::ObjectFactoryBase )
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
static bool IsRegistered = false;
if ( !IsRegistered )
{
SurfaceVtkWriterFactory::Pointer surfaceVtkWriterFactory = SurfaceVtkWriterFactory::New();
ObjectFactoryBase::RegisterFactory( surfaceVtkWriterFactory );
IsRegistered = true;
}
}
protected:
SurfaceVtkWriterFactory();
~SurfaceVtkWriterFactory();
private:
SurfaceVtkWriterFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkVtiFileIOFactory.cpp b/Core/Code/IO/mitkVtiFileIOFactory.cpp
index 29c66abfd8..458965b8b9 100644
--- a/Core/Code/IO/mitkVtiFileIOFactory.cpp
+++ b/Core/Code/IO/mitkVtiFileIOFactory.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtiFileIOFactory.h"
#include "mitkIOAdapter.h"
#include "mitkVtiFileReader.h"
#include "itkVersion.h"
namespace mitk
{
VtiFileIOFactory::VtiFileIOFactory()
{
this->RegisterOverride("mitkIOAdapter",
"mitkVtiFileReader",
"mitk Vti Image IO",
1,
itk::CreateObjectFunction<IOAdapter<VtiFileReader> >::New());
}
VtiFileIOFactory::~VtiFileIOFactory()
{
}
const char* VtiFileIOFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* VtiFileIOFactory::GetDescription() const
{
return "VtiFile IO Factory, allows the loading of vti files";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkVtiFileIOFactory.h b/Core/Code/IO/mitkVtiFileIOFactory.h
index 2f42a66bb7..4d51dd1e76 100644
--- a/Core/Code/IO/mitkVtiFileIOFactory.h
+++ b/Core/Code/IO/mitkVtiFileIOFactory.h
@@ -1,72 +1,71 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkVtiFileIOFactory_h
#define __mitkVtiFileIOFactory_h
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
//##Documentation
//## @brief Create instances of VtiFileReader objects using an object factory.
//##
//## @ingroup IO
class MITK_CORE_EXPORT VtiFileIOFactory : public itk::ObjectFactoryBase
{
public:
/** Standard class typedefs. */
typedef VtiFileIOFactory Self;
typedef itk::ObjectFactoryBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
static VtiFileIOFactory* FactoryNew() { return new VtiFileIOFactory;}
/** Run-time type information (and related methods). */
itkTypeMacro(VtiFileIOFactory, ObjectFactoryBase);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
VtiFileIOFactory::Pointer VtiFileIOFactory = VtiFileIOFactory::New();
ObjectFactoryBase::RegisterFactory(VtiFileIOFactory);
}
protected:
VtiFileIOFactory();
~VtiFileIOFactory();
private:
VtiFileIOFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkVtiFileReader.cpp b/Core/Code/IO/mitkVtiFileReader.cpp
index 1a171d7789..99550fa396 100644
--- a/Core/Code/IO/mitkVtiFileReader.cpp
+++ b/Core/Code/IO/mitkVtiFileReader.cpp
@@ -1,69 +1,68 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtiFileReader.h"
#include <vtkImageData.h>
#include <vtkXMLImageDataReader.h>
mitk::VtiFileReader::VtiFileReader()
: m_FileName(""), m_FilePrefix(""), m_FilePattern("")
{
}
mitk::VtiFileReader::~VtiFileReader()
{
}
void mitk::VtiFileReader::GenerateData()
{
if( m_FileName != "")
{
vtkXMLImageDataReader * vtkReader = vtkXMLImageDataReader::New();
vtkReader->SetFileName( m_FileName.c_str() );
vtkReader->Update();
if ( vtkReader->GetOutput() != NULL )
{
mitk::Image::Pointer output = this->GetOutput();
output->Initialize( vtkReader->GetOutput() );
output->SetVolume( vtkReader->GetOutput()->GetScalarPointer() );
}
vtkReader->Delete();
}
}
bool mitk::VtiFileReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
{
// First check the extension
if( filename == "" )
return false;
bool extensionFound = false;
std::string::size_type VTIPos = filename.rfind(".vti");
if ((VTIPos != std::string::npos) && (VTIPos == filename.length() - 4))
extensionFound = true;
VTIPos = filename.rfind(".VTI");
if ((VTIPos != std::string::npos) && (VTIPos == filename.length() - 4))
extensionFound = true;
if (!extensionFound)
return false;
return true;
}
diff --git a/Core/Code/IO/mitkVtiFileReader.h b/Core/Code/IO/mitkVtiFileReader.h
index 18ef9fe44d..19ddebcafb 100644
--- a/Core/Code/IO/mitkVtiFileReader.h
+++ b/Core/Code/IO/mitkVtiFileReader.h
@@ -1,71 +1,70 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 VtiFileReader_H_HEADER_INCLUDED
#define VtiFileReader_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkFileReader.h"
#include "mitkImageSource.h"
namespace mitk {
//##Documentation
//## @brief Reader to read image files in vtk file format
//## @ingroup IO
class MITK_CORE_EXPORT VtiFileReader : public ImageSource, public FileReader
{
public:
mitkClassMacro(VtiFileReader, FileReader);
/** Method for creation through the object factory. */
itkNewMacro(Self);
itkSetStringMacro(FileName);
itkGetStringMacro(FileName);
itkSetStringMacro(FilePrefix);
itkGetStringMacro(FilePrefix);
itkSetStringMacro(FilePattern);
itkGetStringMacro(FilePattern);
static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
protected:
VtiFileReader();
~VtiFileReader();
virtual void GenerateData();
//##Description
//## @brief Time when Header was last read
//itk::TimeStamp m_ReadHeaderTime;
protected:
std::string m_FileName;
std::string m_FilePrefix;
std::string m_FilePattern;
};
} // namespace mitk
#endif /* VtiFileReader_H_HEADER_INCLUDED */
diff --git a/Core/Code/IO/mitkVtkImageIOFactory.cpp b/Core/Code/IO/mitkVtkImageIOFactory.cpp
index 9ad0a455d5..f029046138 100644
--- a/Core/Code/IO/mitkVtkImageIOFactory.cpp
+++ b/Core/Code/IO/mitkVtkImageIOFactory.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkImageIOFactory.h"
#include "mitkIOAdapter.h"
#include "mitkVtkImageReader.h"
#include "itkVersion.h"
namespace mitk
{
VtkImageIOFactory::VtkImageIOFactory()
{
this->RegisterOverride("mitkIOAdapter",
"mitkVtkImageReader",
"mitk Vtk Image IO",
1,
itk::CreateObjectFunction<IOAdapter<VtkImageReader> >::New());
}
VtkImageIOFactory::~VtkImageIOFactory()
{
}
const char* VtkImageIOFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* VtkImageIOFactory::GetDescription() const
{
return "VtkImage IO Factory, allows the loading of pvtk files";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkVtkImageIOFactory.h b/Core/Code/IO/mitkVtkImageIOFactory.h
index dbccae5e28..a47b7c5784 100644
--- a/Core/Code/IO/mitkVtkImageIOFactory.h
+++ b/Core/Code/IO/mitkVtkImageIOFactory.h
@@ -1,72 +1,71 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkVtkImageIOFactory_h
#define __mitkVtkImageIOFactory_h
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
//##Documentation
//## @brief Create instances of VtkImageReader objects using an object factory.
//##
//## @ingroup IO
class MITK_CORE_EXPORT VtkImageIOFactory : public itk::ObjectFactoryBase
{
public:
/** Standard class typedefs. */
typedef VtkImageIOFactory Self;
typedef itk::ObjectFactoryBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
static VtkImageIOFactory* FactoryNew() { return new VtkImageIOFactory;}
/** Run-time type information (and related methods). */
itkTypeMacro(VtkImageIOFactory, ObjectFactoryBase);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
VtkImageIOFactory::Pointer VtkImageIOFactory = VtkImageIOFactory::New();
ObjectFactoryBase::RegisterFactory(VtkImageIOFactory);
}
protected:
VtkImageIOFactory();
~VtkImageIOFactory();
private:
VtkImageIOFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkVtkImageReader.cpp b/Core/Code/IO/mitkVtkImageReader.cpp
index f4c545c669..8b0b49501d 100644
--- a/Core/Code/IO/mitkVtkImageReader.cpp
+++ b/Core/Code/IO/mitkVtkImageReader.cpp
@@ -1,99 +1,98 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkImageReader.h"
#include <vtkDataReader.h>
#include <vtkStructuredPoints.h>
#include <vtkStructuredPointsReader.h>
mitk::VtkImageReader::VtkImageReader()
: m_FileName(""), m_FilePrefix(""), m_FilePattern("")
{
}
mitk::VtkImageReader::~VtkImageReader()
{
}
void mitk::VtkImageReader::GenerateData()
{
if( m_FileName != "")
{
MITK_INFO << "Loading " << m_FileName << " as vtk" << std::endl;
///We create a Generic Reader to test de .vtk/
vtkDataReader *chooser=vtkDataReader::New();
chooser->SetFileName(m_FileName.c_str() );
if(chooser->IsFileStructuredPoints())
{
///StructuredPoints/
MITK_INFO << "StructuredPoints"<< std::endl;
vtkStructuredPointsReader *reader=vtkStructuredPointsReader::New();
reader->SetFileName(m_FileName.c_str());
reader->Update();
if ( reader->GetOutput() != NULL )
{
mitk::Image::Pointer output = this->GetOutput();
output->Initialize( reader->GetOutput() );
output->SetVolume( reader->GetOutput()->GetScalarPointer());
}
reader->Delete();
}
else
{
MITK_ERROR << " ... sorry, this .vtk format is not supported yet."<<std::endl;
}
chooser->Delete();
}
}
bool mitk::VtkImageReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
{
// First check the extension
if( filename == "" )
return false;
bool extensionFound = false;
std::string::size_type PVTKPos = filename.rfind(".pvtk");
if ((PVTKPos != std::string::npos)
&& (PVTKPos == filename.length() - 5))
{
extensionFound = true;
}
PVTKPos = filename.rfind(".PVTK");
if ((PVTKPos != std::string::npos)
&& (PVTKPos == filename.length() - 5))
{
extensionFound = true;
}
if (extensionFound)
{
vtkDataReader *chooser=vtkDataReader::New();
chooser->SetFileName(filename.c_str() );
if(!chooser->IsFileStructuredPoints())
return false;
}
else
return false;
return true;
}
diff --git a/Core/Code/IO/mitkVtkImageReader.h b/Core/Code/IO/mitkVtkImageReader.h
index e365de44d1..b93f010721 100644
--- a/Core/Code/IO/mitkVtkImageReader.h
+++ b/Core/Code/IO/mitkVtkImageReader.h
@@ -1,71 +1,70 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 VtkImageReader_H_HEADER_INCLUDED
#define VtkImageReader_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkFileReader.h"
#include "mitkImageSource.h"
namespace mitk {
//##Documentation
//## @brief Reader to read image files in vtk file format
//## @ingroup IO
class MITK_CORE_EXPORT VtkImageReader : public ImageSource, public FileReader
{
public:
mitkClassMacro(VtkImageReader, FileReader);
/** Method for creation through the object factory. */
itkNewMacro(Self);
itkSetStringMacro(FileName);
itkGetStringMacro(FileName);
itkSetStringMacro(FilePrefix);
itkGetStringMacro(FilePrefix);
itkSetStringMacro(FilePattern);
itkGetStringMacro(FilePattern);
static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
protected:
VtkImageReader();
~VtkImageReader();
virtual void GenerateData();
//##Description
//## @brief Time when Header was last read
//itk::TimeStamp m_ReadHeaderTime;
protected:
std::string m_FileName;
std::string m_FilePrefix;
std::string m_FilePattern;
};
} // namespace mitk
#endif /* VtkImageReader_H_HEADER_INCLUDED */
diff --git a/Core/Code/IO/mitkVtkSurfaceIOFactory.cpp b/Core/Code/IO/mitkVtkSurfaceIOFactory.cpp
index b7f1a3779c..6a69c22440 100644
--- a/Core/Code/IO/mitkVtkSurfaceIOFactory.cpp
+++ b/Core/Code/IO/mitkVtkSurfaceIOFactory.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkSurfaceIOFactory.h"
#include "mitkIOAdapter.h"
#include "mitkVtkSurfaceReader.h"
#include "itkVersion.h"
namespace mitk
{
VtkSurfaceIOFactory::VtkSurfaceIOFactory()
{
this->RegisterOverride("mitkIOAdapter",
"mitkVtkSurfaceReader",
"mitk Vtk Surface IO",
1,
itk::CreateObjectFunction<IOAdapter<VtkSurfaceReader> >::New());
}
VtkSurfaceIOFactory::~VtkSurfaceIOFactory()
{
}
const char* VtkSurfaceIOFactory::GetITKSourceVersion() const
{
return ITK_SOURCE_VERSION;
}
const char* VtkSurfaceIOFactory::GetDescription() const
{
return "VtkSurface IO Factory, allows the loading of Vtk files";
}
} // end namespace mitk
diff --git a/Core/Code/IO/mitkVtkSurfaceIOFactory.h b/Core/Code/IO/mitkVtkSurfaceIOFactory.h
index ecd85a2de6..5ef84888b4 100644
--- a/Core/Code/IO/mitkVtkSurfaceIOFactory.h
+++ b/Core/Code/IO/mitkVtkSurfaceIOFactory.h
@@ -1,72 +1,71 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __mitkVtkSurfaceIOFactory_h
#define __mitkVtkSurfaceIOFactory_h
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "itkObjectFactoryBase.h"
#include "mitkBaseData.h"
namespace mitk
{
//##Documentation
//## @brief Create instances of VtkSurfaceReader objects using an object factory.
//##
//## @ingroup IO
class MITK_CORE_EXPORT VtkSurfaceIOFactory : public itk::ObjectFactoryBase
{
public:
/** Standard class typedefs. */
typedef VtkSurfaceIOFactory Self;
typedef itk::ObjectFactoryBase Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Class methods used to interface with the registered factories. */
virtual const char* GetITKSourceVersion(void) const;
virtual const char* GetDescription(void) const;
/** Method for class instantiation. */
itkFactorylessNewMacro(Self);
static VtkSurfaceIOFactory* FactoryNew() { return new VtkSurfaceIOFactory;}
/** Run-time type information (and related methods). */
itkTypeMacro(VtkSurfaceIOFactory, ObjectFactoryBase);
/** Register one factory of this type */
static void RegisterOneFactory(void)
{
VtkSurfaceIOFactory::Pointer VtkSurfaceIOFactory = VtkSurfaceIOFactory::New();
ObjectFactoryBase::RegisterFactory(VtkSurfaceIOFactory);
}
protected:
VtkSurfaceIOFactory();
~VtkSurfaceIOFactory();
private:
VtkSurfaceIOFactory(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
} // end namespace mitk
#endif
diff --git a/Core/Code/IO/mitkVtkSurfaceReader.cpp b/Core/Code/IO/mitkVtkSurfaceReader.cpp
index a2d3008d44..c0e209f288 100644
--- a/Core/Code/IO/mitkVtkSurfaceReader.cpp
+++ b/Core/Code/IO/mitkVtkSurfaceReader.cpp
@@ -1,127 +1,126 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkSurfaceReader.h"
#include <mitkSurface.h>
#include <vtkDataReader.h>
#include <vtkPolyDataReader.h>
#include <vtkXMLPolyDataReader.h>
#include <itksys/SystemTools.hxx>
mitk::VtkSurfaceReader::VtkSurfaceReader()
: m_FileName("")
{
}
mitk::VtkSurfaceReader::~VtkSurfaceReader()
{
}
void mitk::VtkSurfaceReader::GenerateData()
{
if( m_FileName != "")
{
bool success = false;
MITK_INFO << "Loading " << m_FileName << " as vtk" << std::endl;
std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName);
ext = itksys::SystemTools::LowerCase(ext);
if (ext == ".vtk")
{
///We create a Generic Reader to test de .vtk/
vtkDataReader *chooser=vtkDataReader::New();
chooser->SetFileName(m_FileName.c_str() );
if( chooser->IsFilePolyData())
{
///PolyData/
itkDebugMacro( << "PolyData" );
vtkPolyDataReader *reader = vtkPolyDataReader::New();
reader->SetFileName( m_FileName.c_str() );
reader->Update();
if ( reader->GetOutput() != NULL )
{
mitk::Surface::Pointer output = this->GetOutput();
output->SetVtkPolyData( reader->GetOutput() );
success = true;
}
reader->Delete();
}
chooser->Delete();
}
else
if (ext == ".vtp")
{
vtkXMLPolyDataReader *reader=vtkXMLPolyDataReader::New();
if( reader->CanReadFile(m_FileName.c_str()) )
{
///PolyData/
itkDebugMacro( << "XMLPolyData" );
reader->SetFileName( m_FileName.c_str() );
reader->Update();
if ( reader->GetOutput() != NULL )
{
mitk::Surface::Pointer output = this->GetOutput();
output->SetVtkPolyData( reader->GetOutput() );
success = true;
}
reader->Delete();
}
}
if(!success)
{
itkWarningMacro( << " ... sorry, this .vtk format is not supported yet." );
}
}
}
bool mitk::VtkSurfaceReader::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
{
// First check the extension
if( filename == "" )
return false;
std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename);
ext = itksys::SystemTools::LowerCase(ext);
if (ext == ".vtk")
{
vtkDataReader *chooser=vtkDataReader::New();
chooser->SetFileName(filename.c_str() );
if(!chooser->IsFilePolyData())
{
chooser->Delete();
return false;
}
chooser->Delete();
}
else
if (ext == ".vtp")
{
vtkXMLPolyDataReader *chooser=vtkXMLPolyDataReader::New();
if(!chooser->CanReadFile(filename.c_str()))
{
chooser->Delete();
return false;
}
chooser->Delete();
}
else
return false;
return true;
}
diff --git a/Core/Code/IO/mitkVtkSurfaceReader.h b/Core/Code/IO/mitkVtkSurfaceReader.h
index 5d2cf744f6..d87a92bda2 100644
--- a/Core/Code/IO/mitkVtkSurfaceReader.h
+++ b/Core/Code/IO/mitkVtkSurfaceReader.h
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 VtkSurfaceReader_H_HEADER_INCLUDED
#define VtkSurfaceReader_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkSurfaceSource.h"
namespace mitk {
//##Documentation
//## @brief Reader to read surface files in vtk-format
//## @ingroup IO
class MITK_CORE_EXPORT VtkSurfaceReader : public SurfaceSource
{
public:
mitkClassMacro(VtkSurfaceReader, SurfaceSource);
/** Method for creation through the object factory. */
itkNewMacro(Self);
itkSetStringMacro(FileName);
itkGetStringMacro(FileName);
itkSetStringMacro(FilePrefix);
itkGetStringMacro(FilePrefix);
itkSetStringMacro(FilePattern);
itkGetStringMacro(FilePattern);
static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern);
protected:
virtual void GenerateData();
VtkSurfaceReader();
~VtkSurfaceReader();
std::string m_FileName, m_FilePrefix, m_FilePattern;
};
} // namespace mitk
#endif /* VtkSurfaceReader_H_HEADER_INCLUDED */
diff --git a/Core/Code/IO/vtkPointSetXMLParser.cpp b/Core/Code/IO/vtkPointSetXMLParser.cpp
index b95590fdac..ea557b1062 100644
--- a/Core/Code/IO/vtkPointSetXMLParser.cpp
+++ b/Core/Code/IO/vtkPointSetXMLParser.cpp
@@ -1,206 +1,205 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "vtkPointSetXMLParser.h"
#include "vtkObjectFactory.h"
#include "mitkPointSetWriter.h"
#include "mitkOperation.h"
#include "mitkInteractionConst.h"
#include "mitkPointOperation.h"
namespace mitk
{
vtkStandardNewMacro(vtkPointSetXMLParser);
}
mitk::vtkPointSetXMLParser::vtkPointSetXMLParser()
{
}
mitk::vtkPointSetXMLParser::~vtkPointSetXMLParser()
{
}
int mitk::vtkPointSetXMLParser::InitializeParser()
{
vtkXMLParser::InitializeParser();
std::istream* stream = this -> GetStream();
if (!stream)
{
vtkErrorMacro("no stream available in XML file reader");
this->ParseError = 1;
return 0;
}
m_PreviousLocale = stream->getloc();
std::locale I("C");
stream->imbue(I);
return 1;
}
int mitk::vtkPointSetXMLParser::CleanupParser()
{
std::istream* stream = this -> GetStream();
if (!stream)
{
vtkErrorMacro("no stream available in XML file reader");
this->ParseError = 1;
return 0;
}
stream->imbue( m_PreviousLocale );
vtkXMLParser::CleanupParser();
return 1;
}
void mitk::vtkPointSetXMLParser::StartElement ( const char *name, const char ** /*atts */)
{
std::string currentElement = name;
//
// when a new point set begins in the file, create a new
// mitk::point set and store it in m_PointSetList
//
if ( currentElement == mitk::PointSetWriter::XML_POINT_SET )
{
m_CurrentPointSet = PointSetType::New();
}
//
// when a new point begins, initialize it to zero.
//
else if ( currentElement == mitk::PointSetWriter::XML_POINT )
{
m_CurrentPoint[ 0 ] = 0.0f;
m_CurrentPoint[ 1 ] = 0.0f;
m_CurrentPoint[ 2 ] = 0.0f;
m_CurId.clear();
m_CurXString.clear();
m_CurYString.clear();
m_CurZString.clear();
}
//
// the current element is pushed on to the stack
// to be able to detect some errors in the xml file
//
m_ParseStack.push( currentElement );
}
void mitk::vtkPointSetXMLParser::EndElement ( const char *name )
{
std::string currentElement = name;
//
// make sure, that the current end element matches with the
// last start tag
//
if ( m_ParseStack.top() != currentElement )
{
MITK_ERROR << "Top of parse stack ( " << m_ParseStack.top() << " ) is != currentEndElement ( " << currentElement << " )!" << std::endl;
}
m_ParseStack.pop();
//
// After a complete point set has been parsed, its
// output information is updated and it is inserted into the list
// of parsed point sets.
//
if (currentElement == mitk::PointSetWriter::XML_POINT_SET)
{
m_CurrentPointSet->UpdateOutputInformation();
m_PointSetList.push_back( m_CurrentPointSet );
}
//
// if we have finished parsing a point, insert it to the current
// point set.
//
else if ( currentElement == mitk::PointSetWriter::XML_POINT )
{
m_CurrentPointId = ParsePointIdentifier( m_CurId );
m_CurrentPoint[ 0 ] = ParseScalarType( m_CurXString );
m_CurrentPoint[ 1 ] = ParseScalarType( m_CurYString );
m_CurrentPoint[ 2 ] = ParseScalarType( m_CurZString );
mitk::PointOperation popInsert( mitk::OpINSERT, m_CurrentPoint, m_CurrentPointId );
mitk::PointOperation popDeactivate( mitk::OpDESELECTPOINT, m_CurrentPoint, m_CurrentPointId );
assert( m_CurrentPointSet.IsNotNull() );
m_CurrentPointSet->ExecuteOperation( &popInsert );
m_CurrentPointSet->ExecuteOperation( &popDeactivate );
}
}
void mitk::vtkPointSetXMLParser::CharacterDataHandler ( const char *inData, int inLength )
{
std::string currentElement = m_ParseStack.top();
if ( currentElement == mitk::PointSetWriter::XML_ID )
{
m_CurId.append( inData, inLength );
}
else if ( currentElement == mitk::PointSetWriter::XML_X )
{
m_CurXString.append(inData, inLength);
}
else if ( currentElement == mitk::PointSetWriter::XML_Y )
{
m_CurYString.append(inData, inLength);
}
else if ( currentElement == mitk::PointSetWriter::XML_Z )
{
m_CurZString.append(inData, inLength);
}
}
mitk::ScalarType mitk::vtkPointSetXMLParser::ParseScalarType( const std::string &data )
{
std::istringstream stm;
stm.str(data);
ScalarType number;
stm >>number;
return number;
}
mitk::vtkPointSetXMLParser::PointIdentifier mitk::vtkPointSetXMLParser::ParsePointIdentifier( const std::string &data )
{
std::istringstream stm;
stm.str(data);
PointIdentifier pointID;
stm >>pointID;
return pointID;
}
mitk::vtkPointSetXMLParser::PointSetList mitk::vtkPointSetXMLParser::GetParsedPointSets()
{
return m_PointSetList;
}
diff --git a/Core/Code/IO/vtkPointSetXMLParser.h b/Core/Code/IO/vtkPointSetXMLParser.h
index a64a02f134..ca5d2ad2c2 100644
--- a/Core/Code/IO/vtkPointSetXMLParser.h
+++ b/Core/Code/IO/vtkPointSetXMLParser.h
@@ -1,137 +1,136 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _VTK_POINT_SET_XML_READER__H_
#define _VTK_POINT_SET_XML_READER__H_
#include <mitkPointSet.h>
#include <vtkXMLParser.h>
#include <stack>
#include <list>
#include <string>
namespace mitk
{
/**
* @brief Implementation of the vtkXMLParser interface for reading mitk::PointSets.
*
* This class implements the XMLParser interface of the vtkXMLParser which is based
* on expat. It is used by the mitk::PointSetReader and is NOT INTENDED TO BE USED
* FROM THE END-USER. If you want to read point sets, use the mitk::PointSetReader.
* @ingroup Process
*/
class MITK_CORE_EXPORT vtkPointSetXMLParser : public vtkXMLParser
{
public:
vtkTypeMacro(vtkPointSetXMLParser,vtkXMLParser);
static vtkPointSetXMLParser* New();
typedef mitk::PointSet PointSetType;
typedef std::stack< std::string > ParseStack;
typedef std::list< PointSetType::Pointer > PointSetList;
typedef PointSetType::DataType::PointIdentifier PointIdentifier;
typedef PointSetType::PointType PointType;
virtual int InitializeParser();
virtual int CleanupParser();
/**
* Handler function which is called, when a new xml start-tag
* has been parsed.
*/
virtual void StartElement (const char *name, const char **atts);
/**
* Handler function which is called, when a xml end-tag
* has been parsed.
*/
virtual void EndElement (const char *name);
/**
* Handler function which is called, if characted data has been
* parsed by expat.
* @param inData a char array containing the parsed string data
* @param inLength the length of the parsed data string.
*/
virtual void CharacterDataHandler (const char *inData, int inLength);
/**
* Converts the given data to mitk::ScalarType.
*/
virtual mitk::ScalarType ParseScalarType(const std::string &data);
/**
* Converts the given data to an PointIdentifier
*/
virtual PointIdentifier ParsePointIdentifier(const std::string &data);
/**
* @returns the list of point sets which have been read from file.
* NOTE: your have to call the Parse() function, before this function.
*/
virtual PointSetList GetParsedPointSets();
protected:
vtkPointSetXMLParser();
virtual ~vtkPointSetXMLParser();
/**
* A stack containing the parsed start-tags.
* If an end tag is encountered, it is matched with the
* top element of the stack.
*/
ParseStack m_ParseStack;
/**
* Contains the parsed point sets.
*/
PointSetList m_PointSetList;
/**
* The current point set which is processed
* by the parser.
*/
PointSetType::Pointer m_CurrentPointSet;
/**
* The current point which is processed
* by the parser.
*/
PointType m_CurrentPoint;
std::string m_CurId;
std::string m_CurXString;
std::string m_CurYString;
std::string m_CurZString;
/**
* The current point id which is processed
* by the parser.
*/
PointIdentifier m_CurrentPointId;
std::locale m_PreviousLocale;
};
}
#endif // _VTK_POINT_SET_XML_READER__H_
diff --git a/Core/Code/Interactions/mitkAction.cpp b/Core/Code/Interactions/mitkAction.cpp
index 6ca890958e..0c0dcbd0fb 100644
--- a/Core/Code/Interactions/mitkAction.cpp
+++ b/Core/Code/Interactions/mitkAction.cpp
@@ -1,63 +1,62 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkAction.h"
namespace mitk {
/**
* Default Constructor
*/
Action::Action( int actionId )
:m_ActionId( actionId ), m_PropertiesList(NULL)
{}
Action::~Action()
{}
/**
* add a property
*/
void Action::AddProperty(const char* propertyKey, BaseProperty* property )
{
if (m_PropertiesList.IsNull())
m_PropertiesList = PropertyList::New();
m_PropertiesList->SetProperty( propertyKey, property );
}
/**
* return the actionId of this object
*/
int Action::GetActionId() const
{
return m_ActionId;
}
/**
* return the property with the given property key
*/
mitk::BaseProperty* Action::GetProperty( const char *propertyKey ) const
{
if (m_PropertiesList.IsNotNull())
return m_PropertiesList->GetProperty( propertyKey );
else
return NULL;
}
} // namespace mitk
diff --git a/Core/Code/Interactions/mitkAction.h b/Core/Code/Interactions/mitkAction.h
index 687c9a54de..962cbacc8e 100644
--- a/Core/Code/Interactions/mitkAction.h
+++ b/Core/Code/Interactions/mitkAction.h
@@ -1,83 +1,82 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 ACTION_H_HEADER_INCLUDED_C19AE06B
#define ACTION_H_HEADER_INCLUDED_C19AE06B
#include <MitkExports.h>
#include "mitkPropertyList.h"
#include <itkObject.h>
#include <itkObjectFactory.h>
namespace mitk {
//##Documentation
//## @brief represents an action, that is executed after a certain event (in statemachine-mechanism)
//##
//## @ingroup Interaction
class MITK_CORE_EXPORT Action : public itk::Object
{
public:
mitkClassMacro(Action, itk::Object);
/**
* @brief static New method to use SmartPointer
**/
mitkNewMacro1Param(Self, int);
/**
* @brief Adds a property to the list of properties.
**/
void AddProperty(const char* propertyKey, BaseProperty* property);
/**
* @brief Returns the Id of this action.
**/
int GetActionId() const;
/**
* @brief returns the specified property
**/
mitk::BaseProperty* GetProperty( const char *propertyKey ) const;
protected:
/**
* @brief Default Constructor.
* Set the actionId.
**/
Action( int actionId );
/**
* @brief Default Destructor
**/
~Action();
private:
/**
* @brief The Id of this action.
**/
int m_ActionId;
/**
* @brief An action can also have several properties that are needed to execute a special action.
**/
PropertyList::Pointer m_PropertiesList;
};
} // namespace mitk
#endif /* ACTION_H_HEADER_INCLUDED_C19AE06B */
diff --git a/Core/Code/Interactions/mitkAffineInteractor.cpp b/Core/Code/Interactions/mitkAffineInteractor.cpp
index aaaafac38d..cff2ca8186 100755
--- a/Core/Code/Interactions/mitkAffineInteractor.cpp
+++ b/Core/Code/Interactions/mitkAffineInteractor.cpp
@@ -1,370 +1,369 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkAffineInteractor.h"
#include "mitkInteractionConst.h"
#include "mitkDataNode.h"
#include "mitkGeometry3D.h"
#include "mitkRotationOperation.h"
#include "mitkPointOperation.h"
#include "mitkPositionEvent.h"
#include "mitkStateEvent.h"
#include "mitkOperationEvent.h"
#include "mitkUndoController.h"
#include "mitkDisplayPositionEvent.h"
#include "vtkTransform.h"
#include "mitkVtkPropRenderer.h"
#include "mitkProperties.h"
#include <itkBoundingBox.h>
#include <itkFixedArray.h>
#include "mitkAction.h"
//#include "mitkBoundingObject.h"
#include "mitkRenderingManager.h"
#include <math.h>
#include <vtkWorldPointPicker.h>
#include <vtkPicker.h>
#include "mitkGlobalInteraction.h"
#include "mitkFocusManager.h"
#include "mitkEventMapper.h"
#include "vtkProp3D.h"
#include "mitkVtkInteractorCameraController.h"
#include <vtkInteractorObserver.h>
#include "vtkRenderer.h"
#include "vtkCamera.h"
#include <vtkInteractorObserver.h>
#include <iostream>
mitk::AffineInteractor::AffineInteractor(const char * type, DataNode* dataNode)
: Interactor(type, dataNode)
{
}
bool mitk::AffineInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
bool ok = false;
TimeSlicedGeometry* inputtimegeometry = GetData()->GetTimeSlicedGeometry();
if (inputtimegeometry == NULL)
return false;
Geometry3D* geometry = inputtimegeometry->GetGeometry3D(m_TimeStep);
mitk::DisplayPositionEvent const *event = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
switch (action->GetActionId())
{
case AcCHECKELEMENT:
{
mitk::Point3D worldPoint = event->GetWorldPosition();
/* now we have a worldpoint. check if it is inside our object and select/deselect it accordingly */
mitk::BoolProperty::Pointer selected;
mitk::ColorProperty::Pointer color;
mitk::StateEvent* newStateEvent = NULL;
selected = dynamic_cast<mitk::BoolProperty*>(m_DataNode->GetProperty("selected"));
if ( selected.IsNull() ) {
selected = mitk::BoolProperty::New();
m_DataNode->GetPropertyList()->SetProperty("selected", selected);
}
color = dynamic_cast<mitk::ColorProperty*>(m_DataNode->GetProperty("color"));
if ( color.IsNull() ) {
color = mitk::ColorProperty::New();
m_DataNode->GetPropertyList()->SetProperty("color", color);
}
if (this->CheckSelected(worldPoint, m_TimeStep))
{
newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
selected->SetValue(true);
color->SetColor(1.0, 1.0, 0.0);
}
else
{
newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
selected = mitk::BoolProperty::New(false);
color->SetColor(0.0, 0.0, 1.0);
/*
mitk::BoundingObject* b = dynamic_cast<mitk::BoundingObject*>(m_DataNode->GetData());
if(b != NULL)
{
color = (b->GetPositive())? mitk::ColorProperty::New(0.0, 0.0, 1.0) : mitk::ColorProperty::New(1.0, 0.0, 0.0); // if deselected, a boundingobject is colored according to its positive/negative state
}
else
color = mitk::ColorProperty::New(1.0, 1.0, 1.0); // if deselcted and no bounding object, color is white
*/
}
/* write new state (selected/not selected) to the property */
this->HandleEvent( newStateEvent );
ok = true;
break;
}
case AcADD:
{
mitk::Point3D worldPoint = event->GetWorldPosition();
mitk::StateEvent* newStateEvent = NULL;
if (this->CheckSelected(worldPoint, m_TimeStep))
{
newStateEvent = new mitk::StateEvent(EIDYES, event);
m_DataNode->GetPropertyList()->SetProperty("selected", mitk::BoolProperty::New(true)); // TODO: Generate an Select Operation and send it to the undo controller ?
}
else // if not selected, do nothing (don't deselect)
{
newStateEvent = new mitk::StateEvent(EIDNO, event);
}
//call HandleEvent to leave the guard-state
this->HandleEvent( newStateEvent );
ok = true;
break;
}
case AcTRANSLATESTART:
case AcROTATESTART:
case AcSCALESTART:
{
m_LastMousePosition = event->GetWorldPosition();
ok = true;
break;
}
case AcTRANSLATE:
{
mitk::Point3D newPosition;
newPosition = event->GetWorldPosition();
newPosition -= m_LastMousePosition.GetVectorFromOrigin(); // compute difference between actual and last mouse position
m_LastMousePosition = event->GetWorldPosition(); // save current mouse position as last position
/* create operation with position difference */
mitk::PointOperation* doOp = new mitk::PointOperation(OpMOVE, newPosition, 0); // Index is not used here
if (m_UndoEnabled) //write to UndoMechanism
{
mitk::Point3D oldPosition=geometry->GetCornerPoint(0);
PointOperation* undoOp = new mitk::PointOperation(OpMOVE, oldPosition, 0);
OperationEvent *operationEvent = new OperationEvent(geometry, doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
/* execute the Operation */
geometry->ExecuteOperation(doOp);
ok = true;
break;
}
case AcTRANSLATEEND:
{
m_UndoController->SetOperationEvent(new UndoStackItem("Move object"));
m_DataNode->InvokeEvent(TranslateEvent());
break;
}
case AcROTATE:
{
mitk::Point3D p = event->GetWorldPosition();
mitk::Vector3D newPosition = p.GetVectorFromOrigin();
mitk::Point3D dataPosition = geometry->GetCenter();
newPosition = newPosition - dataPosition.GetVectorFromOrigin(); // calculate vector from center of the data object to the current mouse position
mitk::Vector3D startPosition = m_LastMousePosition.GetVectorFromOrigin() - dataPosition.GetVectorFromOrigin(); // calculate vector from center of the data object to the last mouse position
/* calculate rotation axis (by calculating the cross produkt of the vectors) */
mitk::Vector3D rotationaxis;
rotationaxis[0] = startPosition[1] * newPosition[2] - startPosition[2] * newPosition[1];
rotationaxis[1] = startPosition[2] * newPosition[0] - startPosition[0] * newPosition[2];
rotationaxis[2] = startPosition[0] * newPosition[1] - startPosition[1] * newPosition[0];
/* calculate rotation angle in degrees */
mitk::ScalarType angle = atan2((mitk::ScalarType)rotationaxis.GetNorm(), (mitk::ScalarType) (newPosition * startPosition)) * (180/vnl_math::pi);
m_LastMousePosition = p; // save current mouse position as last mouse position
/* create operation with center of rotation, angle and axis and send it to the geometry and Undo controller */
mitk::RotationOperation* doOp = new mitk::RotationOperation(OpROTATE, dataPosition, rotationaxis, angle);
if (m_UndoEnabled) //write to UndoMechanism
{
RotationOperation* undoOp = new mitk::RotationOperation(OpROTATE, dataPosition, rotationaxis, -angle);
OperationEvent *operationEvent = new OperationEvent(geometry, doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
/* execute the Operation */
geometry->ExecuteOperation(doOp);
ok = true;
break;
}
case AcROTATEEND:
{
m_UndoController->SetOperationEvent(new UndoStackItem("Rotate object"));
m_DataNode->InvokeEvent(RotateEvent());
break;
}
case AcSCALE:
{
mitk::Point3D p = event->GetWorldPosition();
mitk::Vector3D v = p - m_LastMousePosition;
/* calculate scale changes */
mitk::Point3D newScale;
newScale[0] = (geometry->GetAxisVector(0) * v) / geometry->GetExtentInMM(0); // Scalarprodukt of normalized Axis
newScale[1] = (geometry->GetAxisVector(1) * v) / geometry->GetExtentInMM(1); // and direction vector of mouse movement
newScale[2] = (geometry->GetAxisVector(2) * v) / geometry->GetExtentInMM(2); // is the length of the movement vectors
// projection onto the axis
/* convert movement to local object coordinate system and mirror it to the positive quadrant */
Vector3D start;
Vector3D end;
mitk::ScalarType convert[3];
itk2vtk(m_LastMousePosition, convert);
geometry->GetVtkTransform()->GetInverse()->TransformPoint(convert, convert); // transform start point to local object coordinates
start[0] = fabs(convert[0]); start[1] = fabs(convert[1]); start[2] = fabs(convert[2]); // mirror it to the positive quadrant
itk2vtk(p, convert);
geometry->GetVtkTransform()->GetInverse()->TransformPoint(convert, convert); // transform end point to local object coordinates
end[0] = fabs(convert[0]); end[1] = fabs(convert[1]); end[2] = fabs(convert[2]); // mirror it to the positive quadrant
/* check if mouse movement is towards or away from the objects axes and adjust scale factors accordingly */
Vector3D vLocal = start - end;
newScale[0] = (vLocal[0] > 0.0) ? -fabs(newScale[0]) : +fabs(newScale[0]);
newScale[1] = (vLocal[1] > 0.0) ? -fabs(newScale[1]) : +fabs(newScale[1]);
newScale[2] = (vLocal[2] > 0.0) ? -fabs(newScale[2]) : +fabs(newScale[2]);
m_LastMousePosition = p; // update lastPosition for next mouse move
/* generate Operation and send it to the receiving geometry */
PointOperation* doOp = new mitk::PointOperation(OpSCALE, newScale, 0); // Index is not used here
if (m_UndoEnabled) //write to UndoMechanism
{
mitk::Point3D oldScaleData;
oldScaleData[0] = -newScale[0];
oldScaleData[1] = -newScale[1];
oldScaleData[2] = -newScale[2];
PointOperation* undoOp = new mitk::PointOperation(OpSCALE, oldScaleData, 0);
OperationEvent *operationEvent = new OperationEvent(geometry, doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
/* execute the Operation */
geometry->ExecuteOperation(doOp);
/* Update Volume Property with new value */
/*
mitk::BoundingObject* b = dynamic_cast<mitk::BoundingObject*>(m_DataNode->GetData());
if (b != NULL)
{
m_DataNode->GetPropertyList()->SetProperty("volume", FloatProperty::New(b->GetVolume()));
//MITK_INFO << "Volume of Boundingobject is " << b->GetVolume()/1000.0 << " ml" << std::endl;
}
*/
ok = true;
break;
}
case AcSCALEEND:
{
m_UndoController->SetOperationEvent(new UndoStackItem("Scale object"));
m_DataNode->InvokeEvent(ScaleEvent());
break;
}
default:
ok = Superclass::ExecuteAction(action, stateEvent);//, objectEventId, groupEventId);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return ok;
}
bool mitk::AffineInteractor::CheckSelected(const mitk::Point3D& worldPoint, int timestep )
{
bool selected = false;
if (m_DataNode->GetBoolProperty("selected", selected) == false) // if property does not exist
m_DataNode->SetProperty("selected", mitk::BoolProperty::New(false)); // create it
// check if mouseclick has hit the object
/*
mitk::BoundingObject::Pointer boundingObject = dynamic_cast<mitk::BoundingObject*>(m_DataNode->GetData());
if(boundingObject.IsNotNull()) // if it is a bounding object, use its inside function for exact hit calculation
{
selected = boundingObject->IsInside(worldPoint); // check if point is inside the object
}
else // use the data objects bounding box to determine if hit
*/
{
const Geometry3D* geometry = GetData()->GetUpdatedTimeSlicedGeometry()->GetGeometry3D( timestep );
selected = geometry->IsInside(worldPoint);
}
return selected;
}
bool mitk::AffineInteractor::ConvertDisplayEventToWorldPosition(mitk::DisplayPositionEvent const* displayEvent, mitk::Point3D& worldPoint)
{
mitk::Point2D displayPoint = displayEvent->GetDisplayPosition();
/* Copied from vtk Sphere widget */
double focalPoint[4], position[4];
double z;
FocusManager::FocusElement* fe = mitk::GlobalInteraction::GetInstance()->GetFocus();
mitk::VtkPropRenderer* glRenderer = dynamic_cast<mitk::VtkPropRenderer*>( fe );
if ( glRenderer == NULL )
{
return false;
}
vtkRenderer *renderer = glRenderer->GetVtkRenderer();
vtkCamera *camera = renderer->GetActiveCamera();
if ( !camera )
{
return false;
}
// Compute the two points defining the motion vector
camera->GetFocalPoint(focalPoint);
//this->ComputeWorldToDisplay(focalPoint[0], focalPoint[1], focalPoint[2], focalPoint);
renderer->SetWorldPoint(focalPoint[0], focalPoint[1], focalPoint[2], 1.0);
renderer->WorldToDisplay();
renderer->GetDisplayPoint(focalPoint);
z = focalPoint[2];
// this->ComputeDisplayToWorld(displayPoint.x, displayPoint.y, z, position);
renderer->SetDisplayPoint(displayPoint[0], displayPoint[1], z);
renderer->DisplayToWorld();
renderer->GetWorldPoint(position);
if (position[3])
{
worldPoint[0] = position[0] / position[3];
worldPoint[1] = position[1] / position[3];
worldPoint[2] = position[2] / position[3];
position[3] = 1.0;
}
else
{
worldPoint[0] = position[0];
worldPoint[1] = position[1];
worldPoint[2] = position[2];
}
return true;
}
float mitk::AffineInteractor::CanHandleEvent( StateEvent const* stateEvent ) const
{
float jd = 0.0f;
if ( stateEvent->GetEvent()->GetSender()->GetMapperID() == mitk::BaseRenderer::Standard3D )
{
MITK_DEBUG << "Sorry, mitkAffineInteractor does not support interaction in a 3D view at the moment.";
return jd;
}
return Superclass::CanHandleEvent( stateEvent );
}
diff --git a/Core/Code/Interactions/mitkAffineInteractor.h b/Core/Code/Interactions/mitkAffineInteractor.h
index faf1edfde2..9fdd65c596 100755
--- a/Core/Code/Interactions/mitkAffineInteractor.h
+++ b/Core/Code/Interactions/mitkAffineInteractor.h
@@ -1,84 +1,83 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKAFFINEINTERACTOR_H_HEADER_INCLUDED_C188C29F
#define MITKAFFINEINTERACTOR_H_HEADER_INCLUDED_C188C29F
#include <MitkExports.h>
#include "mitkInteractor.h"
#include "mitkVector.h"
namespace mitk {
class DisplayPositionEvent;
//##Documentation
//## @brief Interactor for Affine transformations translate, rotate and scale
//##
//## An object of this class can translate, rotate and scale the data objects
//## by modifying its geometry.
//## @ingroup Interaction
//create events for interactions
#pragma GCC visibility push(default)
itkEventMacro(AffineInteractionEvent, itk::AnyEvent);
itkEventMacro(ScaleEvent, AffineInteractionEvent);
itkEventMacro(RotateEvent, AffineInteractionEvent);
itkEventMacro(TranslateEvent, AffineInteractionEvent);
#pragma GCC visibility pop
class MITK_CORE_EXPORT AffineInteractor : public Interactor
{
public:
mitkClassMacro(AffineInteractor,Interactor);
// itkNewMacro(Self);
mitkNewMacro2Param(Self, const char*, DataNode*);
protected:
// AffineInteractor(); //obsolete
//##Documentation
//## @brief Constructor
//##
//## @param dataNode is the node, this Interactor is connected to
//## @param type is the type of StateMachine like declared in the XML-Configure-File
AffineInteractor(const char * type, DataNode* dataNode);
//##Documentation
//## @brief Destructor
~AffineInteractor(){};
virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
//##Documentation
//## @brief calculates how good the data this state machine handles is hit by the event.
//##
//## Returns a value between 0 and 1.
//## (Used by GlobalInteraction to decide which DESELECTED state machine to send the event to.)
//##
//## \WARNING This is interactor currently does not work for interaction in 3D. Try using mitkAffineInteractor3D instead.
virtual float CanHandleEvent(StateEvent const* stateEvent) const;
bool CheckSelected(const mitk::Point3D& worldPoint, int timestep);
bool ConvertDisplayEventToWorldPosition(mitk::DisplayPositionEvent const* displayEvent, mitk::Point3D& worldPoint);
mitk::Point3D m_LastMousePosition;
};
} // namespace mitk
#endif /* MITKAFFINEINTERACTOR_H_HEADER_INCLUDED_C188C29F */
diff --git a/Core/Code/Interactions/mitkCoordinateSupplier.cpp b/Core/Code/Interactions/mitkCoordinateSupplier.cpp
index ef86e3d6da..e17b4e0d0b 100755
--- a/Core/Code/Interactions/mitkCoordinateSupplier.cpp
+++ b/Core/Code/Interactions/mitkCoordinateSupplier.cpp
@@ -1,163 +1,162 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDisplayCoordinateOperation.h"
//has to be on top, otherwise compiler error!
#include "mitkCoordinateSupplier.h"
#include "mitkOperation.h"
#include "mitkOperationActor.h"
#include "mitkPointOperation.h"
#include "mitkPositionEvent.h"
#include "mitkStateEvent.h"
#include "mitkUndoController.h"
//and not here!
#include <string>
#include "mitkInteractionConst.h"
#include "mitkAction.h"
mitk::CoordinateSupplier::CoordinateSupplier(const char * type, mitk::OperationActor* operationActor)
: mitk::StateMachine(type), m_Destination(operationActor)
{
m_CurrentPoint.Fill(0);
}
mitk::CoordinateSupplier::~CoordinateSupplier()
{
}
bool mitk::CoordinateSupplier::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
bool ok = false;
const PositionEvent* posEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
PointOperation* doOp=NULL;
if(posEvent!=NULL)
{
ScalarType timeInMS = 0;
if(stateEvent->GetEvent()->GetSender()!=NULL)
{
const Geometry2D* worldGeometry = stateEvent->GetEvent()->GetSender()->GetCurrentWorldGeometry2D();
assert( worldGeometry != NULL );
timeInMS = worldGeometry->GetTimeBounds()[ 0 ];
}
else
{
itkWarningMacro(<<"StateEvent::GetSender()==NULL - setting timeInMS to 0");
}
switch (action->GetActionId())
{
case AcNEWPOINT:
{
if (m_Destination == NULL)
return false;
m_OldPoint = posEvent->GetWorldPosition();
doOp = new mitk::PointOperation(OpADD, timeInMS, m_OldPoint, 0);
//Undo
if (m_UndoEnabled)
{
PointOperation* undoOp = new PointOperation(OpDELETE, m_OldPoint, 0);
OperationEvent *operationEvent = new OperationEvent( m_Destination, doOp, undoOp );
m_UndoController->SetOperationEvent(operationEvent);
}
//execute the Operation
m_Destination->ExecuteOperation(doOp);
ok = true;
break;
}
case AcINITMOVEMENT:
{
if (m_Destination == NULL)
return false;
//move the point to the coordinate //not used, cause same to MovePoint... check xml-file
mitk::Point3D movePoint = posEvent->GetWorldPosition();
doOp = new mitk::PointOperation(OpMOVE, timeInMS, movePoint, 0);
//execute the Operation
m_Destination->ExecuteOperation(doOp);
ok = true;
break;
}
case AcMOVEPOINT:
case AcMOVE:
{
mitk::Point3D movePoint = posEvent->GetWorldPosition();
m_CurrentPoint = movePoint;
if (m_Destination == NULL)
return false;
doOp = new mitk::PointOperation(OpMOVE, timeInMS, movePoint, 0);
//execute the Operation
m_Destination->ExecuteOperation(doOp);
ok = true;
break;
}
case AcFINISHMOVEMENT:
{
if (m_Destination == NULL)
return false;
/*finishes a Movement from the coordinate supplier:
gets the lastpoint from the undolist and writes an undo-operation so
that the movement of the coordinatesupplier is undoable.*/
mitk::Point3D movePoint = posEvent->GetWorldPosition();
mitk::Point3D oldMovePoint; oldMovePoint.Fill(0);
doOp = new mitk::PointOperation(OpMOVE, timeInMS, movePoint, 0);
PointOperation* finishOp = new mitk::PointOperation(OpTERMINATE, movePoint, 0);
if (m_UndoEnabled )
{
//get the last Position from the UndoList
OperationEvent *lastOperationEvent = m_UndoController->GetLastOfType(m_Destination, OpMOVE);
if (lastOperationEvent != NULL)
{
PointOperation* lastOp = dynamic_cast<PointOperation *>(lastOperationEvent->GetOperation());
if (lastOp != NULL)
{
oldMovePoint = lastOp->GetPoint();
}
}
PointOperation* undoOp = new PointOperation(OpMOVE, timeInMS, oldMovePoint, 0, "Move slices");
OperationEvent *operationEvent = new OperationEvent(m_Destination, doOp, undoOp, "Move slices");
m_UndoController->SetOperationEvent(operationEvent);
}
//execute the Operation
m_Destination->ExecuteOperation(doOp);
m_Destination->ExecuteOperation(finishOp);
ok = true;
delete finishOp;
break;
}
default:
ok = false;
break;
}
return ok;
}
const mitk::DisplayPositionEvent* displPosEvent = dynamic_cast<const mitk::DisplayPositionEvent *>(stateEvent->GetEvent());
if(displPosEvent!=NULL)
{
return true;
}
return false;
}
diff --git a/Core/Code/Interactions/mitkCoordinateSupplier.h b/Core/Code/Interactions/mitkCoordinateSupplier.h
index f6f3840dd1..1e21de6b15 100755
--- a/Core/Code/Interactions/mitkCoordinateSupplier.h
+++ b/Core/Code/Interactions/mitkCoordinateSupplier.h
@@ -1,66 +1,65 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKCOORDINATESUPPLIER_H
#define MITKCOORDINATESUPPLIER_H
#include <MitkExports.h>
#include "mitkStateMachine.h"
#include "mitkVector.h"
namespace mitk {
class Operation;
class OperationActor;
//##Documentation
//## @brief Interactor
//##
//## sends a Point, that can be processed in its own OperationActor
//## @ingroup Interaction
class MITK_CORE_EXPORT CoordinateSupplier : public StateMachine
{
public:
mitkClassMacro(CoordinateSupplier, StateMachine);
mitkNewMacro2Param(Self, const char*, OperationActor*);
itkGetConstReferenceMacro(CurrentPoint, Point3D);
protected:
//##Documentation
//## @brief Constructor with needed arguments
//## @param type: string, that describes the StateMachine-Scheme to take from all SM (see XML-File)
//## @param operationActor: the Data, operations (+ points) are send to
CoordinateSupplier(const char * type, OperationActor* operationActor);
~CoordinateSupplier();
//##Documentation
//## @brief executes the actions that are sent to this statemachine
//## derived from StateMachine
virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
private:
OperationActor* m_Destination;
Point3D m_OldPoint;
Point3D m_CurrentPoint;
};
} // namespace mitk
#endif /* MITKCOORDINATESUPPLIER_H */
diff --git a/Core/Code/Interactions/mitkCrosshairPositionEvent.h b/Core/Code/Interactions/mitkCrosshairPositionEvent.h
index dd95ab8186..f2ac971f58 100644
--- a/Core/Code/Interactions/mitkCrosshairPositionEvent.h
+++ b/Core/Code/Interactions/mitkCrosshairPositionEvent.h
@@ -1,36 +1,35 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 mitkCrosshairPositionEvent_h
#define mitkCrosshairPositionEvent_h
#include <MitkExports.h>
#include "mitkEvent.h"
namespace mitk {
/** A special mitk::Event thrown by the SliceNavigationController on mouse scroll
*/
class MITK_CORE_EXPORT CrosshairPositionEvent : public Event
{
public:
CrosshairPositionEvent(BaseRenderer* sender);
};
}
#endif
diff --git a/Core/Code/Interactions/mitkDisplayCoordinateOperation.cpp b/Core/Code/Interactions/mitkDisplayCoordinateOperation.cpp
index 19b14fc683..c9b79165c6 100644
--- a/Core/Code/Interactions/mitkDisplayCoordinateOperation.cpp
+++ b/Core/Code/Interactions/mitkDisplayCoordinateOperation.cpp
@@ -1,75 +1,74 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDisplayCoordinateOperation.h"
mitk::DisplayCoordinateOperation::DisplayCoordinateOperation(mitk::OperationType operationType,
mitk::BaseRenderer* renderer,
const mitk::Point2D& startDisplayCoordinate,
const mitk::Point2D& lastDisplayCoordinate,
const mitk::Point2D& currentDisplayCoordinate
)
: mitk::Operation(operationType),
m_Renderer(renderer),
m_StartDisplayCoordinate(startDisplayCoordinate),
m_LastDisplayCoordinate(lastDisplayCoordinate),
m_CurrentDisplayCoordinate(currentDisplayCoordinate)
{
}
mitk::DisplayCoordinateOperation::DisplayCoordinateOperation(mitk::OperationType operationType,
mitk::BaseRenderer* renderer,
const mitk::Point2D& startDisplayCoordinate,
const mitk::Point2D& lastDisplayCoordinate,
const mitk::Point2D& currentDisplayCoordinate,
const mitk::Point2D& startCoordinateInMM
)
: mitk::Operation(operationType),
m_Renderer(renderer),
m_StartDisplayCoordinate(startDisplayCoordinate),
m_LastDisplayCoordinate(lastDisplayCoordinate),
m_CurrentDisplayCoordinate(currentDisplayCoordinate),
m_StartCoordinateInMM(startCoordinateInMM)
{
}
mitk::DisplayCoordinateOperation::~DisplayCoordinateOperation()
{
}
mitk::BaseRenderer* mitk::DisplayCoordinateOperation::GetRenderer()
{
return m_Renderer;
}
mitk::Vector2D mitk::DisplayCoordinateOperation::GetLastToCurrentDisplayVector()
{
return m_CurrentDisplayCoordinate-m_LastDisplayCoordinate;
}
mitk::Vector2D mitk::DisplayCoordinateOperation::GetStartToCurrentDisplayVector()
{
return m_CurrentDisplayCoordinate-m_StartDisplayCoordinate;
}
mitk::Vector2D mitk::DisplayCoordinateOperation::GetStartToLastDisplayVector()
{
return m_LastDisplayCoordinate-m_StartDisplayCoordinate;
}
diff --git a/Core/Code/Interactions/mitkDisplayCoordinateOperation.h b/Core/Code/Interactions/mitkDisplayCoordinateOperation.h
index c22d082260..54336d8032 100644
--- a/Core/Code/Interactions/mitkDisplayCoordinateOperation.h
+++ b/Core/Code/Interactions/mitkDisplayCoordinateOperation.h
@@ -1,83 +1,82 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKDISPLAYCOORDINATEOPERATION_H_HEADER_INCLUDED_C10E33D0
#define MITKDISPLAYCOORDINATEOPERATION_H_HEADER_INCLUDED_C10E33D0
#include <MitkExports.h>
#include "mitkBaseRenderer.h"
#include "mitkVector.h"
#include "mitkOperation.h"
#include <mitkWeakPointer.h>
#define mitkGetMacro(name,type) \
virtual type Get##name () \
{ \
return this->m_##name; \
}
namespace mitk {
//##Documentation
//## @brief Operation with informations necessary for operations of DisplayVectorInteractor
//## @ingroup Undo
class MITK_CORE_EXPORT DisplayCoordinateOperation : public Operation
{
public:
DisplayCoordinateOperation(mitk::OperationType operationType,
mitk::BaseRenderer* renderer,
const mitk::Point2D& startDisplayCoordinate,
const mitk::Point2D& lastDisplayCoordinate,
const mitk::Point2D& currentDisplayCoordinate
);
DisplayCoordinateOperation(mitk::OperationType operationType,
mitk::BaseRenderer* renderer,
const mitk::Point2D& startDisplayCoordinate,
const mitk::Point2D& lastDisplayCoordinate,
const mitk::Point2D& currentDisplayCoordinate,
const mitk::Point2D& startCoordinateInMM
);
virtual ~DisplayCoordinateOperation();
mitk::BaseRenderer* GetRenderer();
mitkGetMacro(StartDisplayCoordinate, mitk::Point2D);
mitkGetMacro(LastDisplayCoordinate, mitk::Point2D);
mitkGetMacro(CurrentDisplayCoordinate, mitk::Point2D);
mitkGetMacro(StartCoordinateInMM, mitk::Point2D);
mitk::Vector2D GetLastToCurrentDisplayVector();
mitk::Vector2D GetStartToCurrentDisplayVector();
mitk::Vector2D GetStartToLastDisplayVector();
private:
mitk::WeakPointer< mitk::BaseRenderer > m_Renderer;
const mitk::Point2D m_StartDisplayCoordinate;
const mitk::Point2D m_LastDisplayCoordinate;
const mitk::Point2D m_CurrentDisplayCoordinate;
const mitk::Point2D m_StartCoordinateInMM;
};
}
#endif /* MITKDISPLAYCOORDINATEOPERATION_H_HEADER_INCLUDED_C10E33D0 */
diff --git a/Core/Code/Interactions/mitkDisplayInteractor.cpp b/Core/Code/Interactions/mitkDisplayInteractor.cpp
index f927d42a6d..2473a66da1 100644
--- a/Core/Code/Interactions/mitkDisplayInteractor.cpp
+++ b/Core/Code/Interactions/mitkDisplayInteractor.cpp
@@ -1,91 +1,90 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDisplayInteractor.h"
#include <mitkOperationActor.h>
#include <mitkEventMapper.h>
#include <mitkGlobalInteraction.h>
#include <mitkCoordinateSupplier.h>
#include <mitkDisplayCoordinateOperation.h>
#include <mitkDisplayVectorInteractor.h>
#include <mitkBaseRenderer.h>
#include <mitkRenderingManager.h>
#include <mitkInteractionConst.h>
mitk::DisplayInteractor::DisplayInteractor(mitk::BaseRenderer * ren)
{
m_ParentRenderer = ren;
}
void mitk::DisplayInteractor::ExecuteOperation(mitk::Operation * operation)
{
//bool ok;//as return type
mitk::DisplayCoordinateOperation* dcOperation=dynamic_cast<mitk::DisplayCoordinateOperation*>(operation);
if ( dcOperation != NULL )
{
/****ZOOM & MOVE of the whole volume****/
mitk::BaseRenderer* renderer = dcOperation->GetRenderer();
if( renderer == NULL || (m_ParentRenderer != NULL && m_ParentRenderer != renderer))
return;
switch (operation->GetOperationType())
{
case OpMOVE :
{
renderer->GetDisplayGeometry()->MoveBy(dcOperation->GetLastToCurrentDisplayVector()*(-1.0));
renderer->GetRenderingManager()->RequestUpdate(renderer->GetRenderWindow());
//ok = true;
}
break;
case OpZOOM :
{
float distance = dcOperation->GetLastToCurrentDisplayVector()[1];
//float factor= 1.0 + distance * 0.05; // stupid because factors from +1 and -1 dont give results that represent inverse zooms
float factor = 1.0;
if (distance < 0.0)
{
factor = 1.0 / 1.05;
}
else if (distance > 0.0)
{
factor = 1.0 * 1.05; // 5%
}
else // distance == 0.0
{
// nothing to do, factor remains 1.0
}
renderer->GetDisplayGeometry()->ZoomWithFixedWorldCoordinates(factor, dcOperation->GetStartDisplayCoordinate(), dcOperation->GetStartCoordinateInMM());
renderer->GetRenderingManager()->RequestUpdate(renderer->GetRenderWindow());
//ok = true;
}
break;
default:
;
}
}
}
diff --git a/Core/Code/Interactions/mitkDisplayInteractor.h b/Core/Code/Interactions/mitkDisplayInteractor.h
index dbe2e8381a..7fee378004 100644
--- a/Core/Code/Interactions/mitkDisplayInteractor.h
+++ b/Core/Code/Interactions/mitkDisplayInteractor.h
@@ -1,62 +1,61 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITK_DISPLAY_INTERACTOR_H_
#define _MITK_DISPLAY_INTERACTOR_H_
#include "mitkOperationActor.h"
//#include "mitkBaseRenderer.h"
namespace mitk {
class BaseRenderer;
//##Documentation
//## @brief The class handles zooming and panning events
//##
//## One can connect it via itk::GlobalInteraction->AddStateMachine(new mitk::DisplayVectorInteractor("move", new DisplayInterActor()));
//## to the global state machine.
//## @ingroup Interaction
class MITK_CORE_EXPORT DisplayInteractor : public mitk::OperationActor
{
public:
/*! \brief constructor for renderer specific zooming panning initialization
The window associated with the passed renderer will be the only one where
this interactor works on.
*/
DisplayInteractor(mitk::BaseRenderer *ren = 0);
/*!
\brief implementation of ExecuteOperation from mitk::OperationActor interface
this method triggers the zooming and panning stuff in the appropriate renderer
*/
virtual void ExecuteOperation(mitk::Operation* operation);
private:
/*!
the renderer which can be affected by the interactor instance
*/
mitk::BaseRenderer * m_ParentRenderer;
};
} // end of namespace mitk
#endif //_MITK_DISPLAY_INTERACTOR_H_
diff --git a/Core/Code/Interactions/mitkDisplayPositionEvent.cpp b/Core/Code/Interactions/mitkDisplayPositionEvent.cpp
index c3cd8ccf01..238ef5bcfc 100644
--- a/Core/Code/Interactions/mitkDisplayPositionEvent.cpp
+++ b/Core/Code/Interactions/mitkDisplayPositionEvent.cpp
@@ -1,77 +1,76 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDisplayPositionEvent.h"
#include "mitkBaseRenderer.h"
mitk::DisplayPositionEvent::DisplayPositionEvent(
mitk::BaseRenderer *sender, int type, int button, int buttonState, int key,
const mitk::Point2D& displPosition )
: Event( sender, type, button, buttonState, key ),
m_DisplayPosition( displPosition ),
m_WorldPositionIsSet( false ),
m_PickedObjectIsSet( false )
{
}
const mitk::Point3D& mitk::DisplayPositionEvent::GetWorldPosition() const
{
// Method performs position picking and sets world position
if ( m_WorldPositionIsSet )
return m_WorldPosition;
assert( m_Sender != NULL );
m_Sender->PickWorldPoint( m_DisplayPosition, m_WorldPosition );
m_WorldPositionIsSet = true;
return m_WorldPosition;
}
mitk::DataNode *mitk::DisplayPositionEvent::GetPickedObjectNode() const
{
// Method performs object picking and sets both object and world position
if ( m_PickedObjectIsSet )
{
return m_PickedObjectNode;
}
assert( m_Sender != NULL );
m_PickedObjectNode = m_Sender->PickObject( m_DisplayPosition, m_WorldPosition );
m_PickedObjectIsSet = true;
m_WorldPositionIsSet = true;
return m_PickedObjectNode;
}
mitk::BaseData *mitk::DisplayPositionEvent::GetPickedObject() const
{
mitk::DataNode *node = this->GetPickedObjectNode();
if ( node != NULL )
{
return node->GetData();
}
else
{
return NULL;
}
}
diff --git a/Core/Code/Interactions/mitkDisplayPositionEvent.h b/Core/Code/Interactions/mitkDisplayPositionEvent.h
index 6e30002bdd..05f5c36087 100644
--- a/Core/Code/Interactions/mitkDisplayPositionEvent.h
+++ b/Core/Code/Interactions/mitkDisplayPositionEvent.h
@@ -1,81 +1,80 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 DISPLAYPOSITIONEVENT_H_HEADER_INCLUDED_C184F366
#define DISPLAYPOSITIONEVENT_H_HEADER_INCLUDED_C184F366
#include <MitkExports.h>
#include "mitkEvent.h"
#include "mitkVector.h"
#include "mitkDataNode.h"
namespace mitk {
/**
* \brief Event that stores coordinates
*
* Stores display position of the mouse.
*
* If requested, the correspondent 3D world position in mm is calculated via
* picking (delegated to the BaseRenderer). Additionally, the mitk::BaseData or
* mitk::DataNode corresponding to the picked object in the (3D) scene can
* be retrieved.
* \ingroup Interaction
*/
class MITK_CORE_EXPORT DisplayPositionEvent : public Event
{
public:
/** \brief Constructor with all necessary arguments.
*
* \param sender is the renderer that caused that event
* \param type, button, buttonState, key: information from the Event
* \param displPosition is the 2D Position of the mouse
*/
DisplayPositionEvent(BaseRenderer* sender, int type, int button, int buttonState, int key, const Point2D& displPosition);
const Point2D& GetDisplayPosition() const
{
return m_DisplayPosition;
}
void SetDisplayPosition(const Point2D& displPosition) { m_DisplayPosition = displPosition; }
const Point3D& GetWorldPosition() const;
/** Returns node with object at the current position (NULL if not applicable) */
mitk::DataNode *GetPickedObjectNode() const;
/** Returns object at the current position (NULL if not applicable) */
mitk::BaseData *GetPickedObject() const;
protected:
Point2D m_DisplayPosition;
mutable Point3D m_WorldPosition;
mutable bool m_WorldPositionIsSet;
mutable mitk::DataNode::Pointer m_PickedObjectNode;
mutable bool m_PickedObjectIsSet;
};
typedef DisplayPositionEvent MouseEvent;
} // namespace mitk
#endif /* DISPLAYPOSITIONozsiEVENT_H_HEADER_INCLUDED_C184F366 */
diff --git a/Core/Code/Interactions/mitkDisplayVectorInteractor.cpp b/Core/Code/Interactions/mitkDisplayVectorInteractor.cpp
index 83bd294250..64b16a3de0 100644
--- a/Core/Code/Interactions/mitkDisplayVectorInteractor.cpp
+++ b/Core/Code/Interactions/mitkDisplayVectorInteractor.cpp
@@ -1,172 +1,171 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDisplayVectorInteractor.h"
#include "mitkOperation.h"
#include "mitkDisplayCoordinateOperation.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkUndoController.h"
#include "mitkStateEvent.h"
#include "mitkInteractionConst.h"
#include "mitkAction.h"
void mitk::DisplayVectorInteractor::ExecuteOperation(Operation* itkNotUsed( operation ) )
{
/*DisplayCoordinateOperation* dcOperation = static_cast<DisplayCoordinateOperation*>(operation);
if(dcOperation==NULL) return;
switch(operation->GetOperationType())
{
case OpSELECTPOINT:
m_Sender=dcOperation->GetRenderer();
m_StartDisplayCoordinate=dcOperation->GetStartDisplayCoordinate();
m_LastDisplayCoordinate=dcOperation->GetLastDisplayCoordinate();
m_CurrentDisplayCoordinate=dcOperation->GetCurrentDisplayCoordinate();
// MITK_INFO << m_CurrentDisplayCoordinate << std::endl;
MITK_INFO<<"Message from DisplayVectorInteractor.cpp::ExecuteOperation() : "
<< "StartDisplayCoordinate:" << m_StartDisplayCoordinate
<< "LastDisplayCoordinate:" << m_LastDisplayCoordinate
<< "CurrentDisplayCoordinate:" << m_CurrentDisplayCoordinate
<< std::endl;
break;
}*/
}
bool mitk::DisplayVectorInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
bool ok=false;
const DisplayPositionEvent* posEvent=dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
if(posEvent==NULL) return false;
int actionId = action->GetActionId();
//initzoom and initmove is the same!
if (actionId == AcINITZOOM)
actionId = AcINITMOVE;
switch(actionId)
{
//case 0:
// {
// DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpTEST, posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
// if (m_UndoEnabled) //write to UndoMechanism
// {
// DisplayCoordinateOperation* undoOp = new DisplayCoordinateOperation(OpTEST, m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);
//
//
// OperationEvent *operationEvent = new OperationEvent(this, doOp, undoOp);
// m_UndoController->SetOperationEvent(operationEvent);
// }
//
// //execute the Operation
// m_Destination->ExecuteOperation(doOp);
// ok = true;
// break;
// }
case AcSENDCOORDINATES:
{
DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpSENDCOORDINATES, posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
m_Destination->ExecuteOperation(doOp);
ok = true;
break;
}
case AcINITMOVE:
{
m_Sender=posEvent->GetSender();
mitk::Vector2D origin = m_Sender->GetDisplayGeometry()->GetOriginInMM();
double scaleFactorMMPerDisplayUnit = m_Sender->GetDisplayGeometry()->GetScaleFactorMMPerDisplayUnit();
m_StartDisplayCoordinate=posEvent->GetDisplayPosition();
m_LastDisplayCoordinate=posEvent->GetDisplayPosition();
m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
m_StartCoordinateInMM=mitk::Point2D( ( origin+m_StartDisplayCoordinate.GetVectorFromOrigin()*scaleFactorMMPerDisplayUnit ).GetDataPointer() );
ok = true;
break;
}
case AcMOVE:
{
DisplayCoordinateOperation* doOp = new DisplayCoordinateOperation(OpMOVE, m_Sender, m_StartDisplayCoordinate, m_CurrentDisplayCoordinate, posEvent->GetDisplayPosition());
//make Operation
m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
//execute the Operation
m_Destination->ExecuteOperation(doOp);
ok = true;
break;
}
case AcFINISHMOVE:
{
if (m_UndoEnabled) //write to UndoMechanism
{
DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpMOVE, m_Sender, m_StartDisplayCoordinate, m_StartDisplayCoordinate, posEvent->GetDisplayPosition());
DisplayCoordinateOperation* undoOp = new mitk::DisplayCoordinateOperation(OpMOVE, posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), m_StartDisplayCoordinate);
OperationEvent *operationEvent = new OperationEvent(m_Destination, doOp, undoOp, "Move view");
m_UndoController->SetOperationEvent(operationEvent);
}
ok = true;
break;
}
case AcZOOM:
{
DisplayCoordinateOperation* doOp = new DisplayCoordinateOperation(OpZOOM, m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, posEvent->GetDisplayPosition(),m_StartCoordinateInMM);
if (m_UndoEnabled) //write to UndoMechanism
{
DisplayCoordinateOperation* undoOp = new mitk::DisplayCoordinateOperation(OpZOOM, posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), m_LastDisplayCoordinate);
OperationEvent *operationEvent = new OperationEvent(m_Destination, doOp, undoOp, "Zoom view");
m_UndoController->SetOperationEvent(operationEvent);
}
//make Operation
m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
//MITK_INFO << m_CurrentDisplayCoordinate << std::endl;
//execute the Operation
m_Destination->ExecuteOperation(doOp);
ok = true;
break;
}
default:
ok = false;
break;
}
return ok;
}
mitk::DisplayVectorInteractor::DisplayVectorInteractor(const char * type, mitk::OperationActor* destination)
: mitk::StateMachine(type), m_Sender(NULL), m_Destination(destination)
{
m_StartDisplayCoordinate.Fill(0);
m_LastDisplayCoordinate.Fill(0);
m_CurrentDisplayCoordinate.Fill(0);
if(m_Destination==NULL)
m_Destination=this;
}
mitk::DisplayVectorInteractor::~DisplayVectorInteractor()
{
}
diff --git a/Core/Code/Interactions/mitkDisplayVectorInteractor.h b/Core/Code/Interactions/mitkDisplayVectorInteractor.h
index c9963de278..2facfac41c 100644
--- a/Core/Code/Interactions/mitkDisplayVectorInteractor.h
+++ b/Core/Code/Interactions/mitkDisplayVectorInteractor.h
@@ -1,80 +1,79 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKDISPLAYVECTORINTERACTOR_H_HEADER_INCLUDED_C10DC4EB
#define MITKDISPLAYVECTORINTERACTOR_H_HEADER_INCLUDED_C10DC4EB
#include <MitkExports.h>
#include "mitkBaseRenderer.h"
#include "mitkStateMachine.h"
namespace mitk {
class Operation;
class OperationActor;
/**
*@brief Interactor for displaying different slices in orthogonal views.
* This includes the interaction of Zooming and Panning.
* @ingroup Interaction
**/
class MITK_CORE_EXPORT DisplayVectorInteractor : public StateMachine
{
public:
mitkClassMacro(DisplayVectorInteractor, StateMachine);
mitkNewMacro2Param(Self, const char*, OperationActor*);
/**
* @brief Method derived from OperationActor to recieve and execute operations
**/
virtual void ExecuteOperation(Operation* operation);
protected:
/**
* @brief Default Constructor
**/
DisplayVectorInteractor(const char * type, mitk::OperationActor* destination=NULL);
/**
* @brief Default Destructor
**/
virtual ~DisplayVectorInteractor();
/**
* @brief Method derived from StateMachine to implement the own actions
**/
virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
private:
BaseRenderer::Pointer m_Sender;
mitk::Point2D m_StartDisplayCoordinate;
mitk::Point2D m_LastDisplayCoordinate;
mitk::Point2D m_CurrentDisplayCoordinate;
mitk::Point2D m_StartCoordinateInMM;
OperationActor* m_Destination;
};
} // namespace mitk
#endif /* MITKDISPLAYVECTORINTERACTOR_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Core/Code/Interactions/mitkDisplayVectorInteractorLevelWindow.cpp b/Core/Code/Interactions/mitkDisplayVectorInteractorLevelWindow.cpp
index 85df1bde29..1eaaa6ce09 100644
--- a/Core/Code/Interactions/mitkDisplayVectorInteractorLevelWindow.cpp
+++ b/Core/Code/Interactions/mitkDisplayVectorInteractorLevelWindow.cpp
@@ -1,132 +1,131 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-01-14 14:20:26 +0100 (Thu, 14 Jan 2010) $
-Version: $Revision: 21047 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDisplayVectorInteractorLevelWindow.h"
#include "mitkOperation.h"
#include "mitkDisplayCoordinateOperation.h"
#include "mitkStateEvent.h"
#include "mitkInteractionConst.h"
#include "mitkAction.h"
#include "mitkStandaloneDataStorage.h"
#include "mitkNodePredicateDataType.h"
#include "mitkLevelWindowProperty.h"
#include "mitkLevelWindow.h"
void mitk::DisplayVectorInteractorLevelWindow::ExecuteOperation(Operation* itkNotUsed( operation ) )
{
}
bool mitk::DisplayVectorInteractorLevelWindow::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
bool ok=false;
const DisplayPositionEvent* posEvent=dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
if(posEvent==NULL) return false;
int actionId = action->GetActionId();
switch(actionId)
{
case AcINITMOVE:
// MITK_INFO << "AcINITMOVE";
{
m_Sender=posEvent->GetSender();
m_StartDisplayCoordinate=posEvent->GetDisplayPosition();
m_LastDisplayCoordinate=posEvent->GetDisplayPosition();
m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
ok = true;
break;
}
case AcLEVELWINDOW:
{
m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
mitk::DataStorage::Pointer storage = m_Sender->GetDataStorage();
mitk::DataNode::Pointer node = NULL;
mitk::DataStorage::SetOfObjects::ConstPointer allImageNodes = storage->GetSubset(mitk::NodePredicateDataType::New( "Image") );
for ( unsigned int i = 0; i < allImageNodes->size() ; i++ )
{
bool isActiveImage = false;
bool propFound = allImageNodes->at( i )->GetBoolProperty( "imageForLevelWindow", isActiveImage );
if ( propFound && isActiveImage )
{
node = allImageNodes->at( i );
continue;
}
}
if ( node.IsNull() )
{
node = storage->GetNode( mitk::NodePredicateDataType::New( "Image" ) );
}
if ( node.IsNull() )
{
return false;
}
mitk::LevelWindow lv = mitk::LevelWindow();
node->GetLevelWindow(lv);
int level = lv.GetLevel();
int window = lv.GetWindow();
level += ( m_CurrentDisplayCoordinate[0] - m_LastDisplayCoordinate[0] )*2;
window += ( m_CurrentDisplayCoordinate[1] - m_LastDisplayCoordinate[1] )*2;
lv.SetLevelWindow( level, window );
dynamic_cast<mitk::LevelWindowProperty*>(node->GetProperty("levelwindow"))->SetLevelWindow( lv );
m_Sender->GetRenderingManager()->RequestUpdateAll();
ok = true;
break;
}
case AcFINISHMOVE:
// MITK_INFO << "AcFINISHMOVE";
{
ok = true;
break;
}
default:
ok = false;
break;
}
return ok;
}
mitk::DisplayVectorInteractorLevelWindow::DisplayVectorInteractorLevelWindow(const char * type)
: mitk::StateMachine(type), m_Sender(NULL)
{
m_StartDisplayCoordinate.Fill(0);
m_LastDisplayCoordinate.Fill(0);
m_CurrentDisplayCoordinate.Fill(0);
m_UndoEnabled = false;
}
mitk::DisplayVectorInteractorLevelWindow::~DisplayVectorInteractorLevelWindow()
{
}
diff --git a/Core/Code/Interactions/mitkDisplayVectorInteractorLevelWindow.h b/Core/Code/Interactions/mitkDisplayVectorInteractorLevelWindow.h
index 7880012606..621c52e621 100644
--- a/Core/Code/Interactions/mitkDisplayVectorInteractorLevelWindow.h
+++ b/Core/Code/Interactions/mitkDisplayVectorInteractorLevelWindow.h
@@ -1,93 +1,92 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-28 17:19:30 +0200 (Thu, 28 May 2009) $
-Version: $Revision: 17495 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKDisplayVectorInteractorLevelWindow_H_HEADER_INCLUDED_C10DC4EB
#define MITKDisplayVectorInteractorLevelWindow_H_HEADER_INCLUDED_C10DC4EB
#include <MitkExports.h>
#include "mitkBaseRenderer.h"
#include "mitkStateMachine.h"
namespace mitk {
class Operation;
class OperationActor;
/**
* @brief Interactor for adjusting both level- and window-values for an image
*
* This class implements an Interactor for adjusting the LevelWindow. It is defined by the 'LevelWindow'-statemachine which maps 'initmove' to right mousebutton pressed,
* 'levelwindow' to right mousebutton and move and 'finishmove' to right mousebutton released.
*
* Using this tool, it is possible to increase the 'level'-value of the selected image
* ( if no image has the 'selected'-property == true, the first image in the DataStorage is used )
* by moving the mouse right and decreasing the level by moving the mouse to the left.
*
* The 'window'-value and also be adjusted by moving the mouse-curser up (increase) and down (decrease).
*
* @ingroup MITK_CORE_EXPORT
**/
class MITK_CORE_EXPORT DisplayVectorInteractorLevelWindow : public StateMachine
{
public:
mitkClassMacro(DisplayVectorInteractorLevelWindow, StateMachine);
mitkNewMacro1Param(Self, const char*);
//static Pointer New(const char* type)
//{
// Pointer smartPtr = new DisplayVectorInteractorLevelWindow ( type );
// smartPtr->UnRegister();
// return smartPtr;
//}
/**
* @brief Method derived from OperationActor to recieve and execute operations
**/
virtual void ExecuteOperation(Operation* operation);
protected:
/**
* @brief Default Constructor
**/
DisplayVectorInteractorLevelWindow(const char * type);
/**
* @brief Default Destructor
**/
virtual ~DisplayVectorInteractorLevelWindow();
/**
* @brief Method derived from StateMachine to implement the own actions
**/
virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
private:
BaseRenderer::Pointer m_Sender;
mitk::Point2D m_StartDisplayCoordinate;
mitk::Point2D m_LastDisplayCoordinate;
mitk::Point2D m_CurrentDisplayCoordinate;
};
} // namespace mitk
#endif /* MITKDISPLAYVECTORINTERACTOR_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Core/Code/Interactions/mitkDisplayVectorInteractorScroll.cpp b/Core/Code/Interactions/mitkDisplayVectorInteractorScroll.cpp
index f087294717..f876493942 100644
--- a/Core/Code/Interactions/mitkDisplayVectorInteractorScroll.cpp
+++ b/Core/Code/Interactions/mitkDisplayVectorInteractorScroll.cpp
@@ -1,225 +1,224 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-01-14 14:20:26 +0100 (Thu, 14 Jan 2010) $
-Version: $Revision: 21047 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDisplayVectorInteractorScroll.h"
#include "mitkOperation.h"
#include "mitkDisplayCoordinateOperation.h"
//#include "mitkDisplayPositionEvent.h"
#include "mitkUndoController.h"
#include "mitkStateEvent.h"
#include "mitkInteractionConst.h"
#include "mitkAction.h"
void mitk::DisplayVectorInteractorScroll::ExecuteOperation(Operation* itkNotUsed( operation ) )
{
}
bool mitk::DisplayVectorInteractorScroll::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
bool ok=false;
const DisplayPositionEvent* posEvent=dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
m_IsAltModifierActive = false;
int actionId = action->GetActionId();
switch(actionId)
{
case AcINITMOVE:
{
if(posEvent==NULL) return false;
m_Sender=posEvent->GetSender();
m_StartDisplayCoordinate=posEvent->GetDisplayPosition();
m_LastDisplayCoordinate=posEvent->GetDisplayPosition();
m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
ok = true;
break;
}
case AcSCROLLMOUSEWHEEL:
{
const WheelEvent* wheelEvent=dynamic_cast<const WheelEvent*>(stateEvent->GetEvent());
if(wheelEvent != NULL)
{
int buttonState = stateEvent->GetEvent()->GetButtonState();
if(buttonState == 1024)
{
m_IsAltModifierActive = true;
}
mitk::SliceNavigationController::Pointer sliceNaviController = wheelEvent->GetSender()->GetSliceNavigationController();
if ( !sliceNaviController->GetSliceLocked() )
{
this->InvokeEvent( StartScrollInteractionEvent() );
mitk::Stepper* stepper = sliceNaviController->GetSlice();
if (stepper->GetSteps() <= 1)
{
stepper = sliceNaviController->GetTime();
}
// get the desired delta
int delta = wheelEvent->GetDelta();
if ( m_InvertScrollingDirection )
delta *= -1; // If we want to invert the scrolling direction -> delta * -1
if ( delta < 0 )
{
stepper->Next();
}
else
{
stepper->Previous();
}
}
this->InvokeEvent( EndScrollInteractionEvent() );
}
ok = true;
break;
}
case AcSCROLL:
{
if(posEvent==NULL) return false;
int buttonState = stateEvent->GetEvent()->GetButtonState();
//1025 = Alt+LeftMouseButton+Move
//1028 = Alt+MiddleMouseButton+Move
if(buttonState == 1025 || buttonState == 1028 )
{
m_IsAltModifierActive = true;
}
mitk::SliceNavigationController::Pointer sliceNaviController = m_Sender->GetSliceNavigationController();
if(sliceNaviController)
{
this->InvokeEvent( StartScrollInteractionEvent() );
int delta = 0;
delta = m_LastDisplayCoordinate[1]-posEvent->GetDisplayPosition()[1];
// if we moved less than 'm_IndexToSliceModifier' pixels slice ONE slice only
if ( delta>0 && delta<m_IndexToSliceModifier )
{
delta=m_IndexToSliceModifier;
}
else if(delta<0 && delta>-m_IndexToSliceModifier)
{
delta=-m_IndexToSliceModifier;
}
delta /= m_IndexToSliceModifier;
if ( m_InvertScrollingDirection )
delta *= -1;
int newPos = sliceNaviController->GetSlice()->GetPos() + delta;
// if auto repeat is on, start at first slice if you reach the last slice and vice versa
int maxSlices = sliceNaviController->GetSlice()->GetSteps();
if ( m_AutoRepeat )
{
while(newPos<0)
{
newPos += maxSlices;
}
while(newPos>=maxSlices)
{
newPos -= maxSlices;
}
}
else
{
// if the new slice is below 0 we still show slice 0
// due to the stepper using unsigned int we have to do this ourselves
if ( newPos < 1 )
newPos = 0;
}
// set the new position
sliceNaviController->GetSlice()->SetPos( newPos );
this->InvokeEvent( EndScrollInteractionEvent() );
}
m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
}
case AcFINISHMOVE:
{
ok = true;
break;
}
default:
ok = false;
break;
}
return ok;
}
void mitk::DisplayVectorInteractorScroll::SetIndexToSliceModifier( int modifier )
{
m_IndexToSliceModifier = modifier;
}
void mitk::DisplayVectorInteractorScroll::SetAutoRepeat( bool autoRepeat )
{
m_AutoRepeat = autoRepeat;
}
mitk::DisplayVectorInteractorScroll::DisplayVectorInteractorScroll(const char * type, mitk::OperationActor* destination)
: mitk::StateMachine(type)
, m_Sender(NULL)
, m_Destination(destination)
, m_IndexToSliceModifier(4)
, m_AutoRepeat( false )
, m_InvertScrollingDirection( false )
, m_IsAltModifierActive( false )
{
m_StartDisplayCoordinate.Fill(0);
m_LastDisplayCoordinate.Fill(0);
m_CurrentDisplayCoordinate.Fill(0);
m_UndoEnabled = false;
//if(m_Destination==NULL)
// m_Destination=this;
}
mitk::DisplayVectorInteractorScroll::~DisplayVectorInteractorScroll()
{
if ( m_Destination != this )
delete m_Destination;
}
void mitk::DisplayVectorInteractorScroll::SetInvertScrollingDirection( bool invert )
{
m_InvertScrollingDirection = invert;
}
bool mitk::DisplayVectorInteractorScroll::IsAltModifierActive() const
{
return m_IsAltModifierActive;
}
diff --git a/Core/Code/Interactions/mitkDisplayVectorInteractorScroll.h b/Core/Code/Interactions/mitkDisplayVectorInteractorScroll.h
index abce7e8a35..20522f73c6 100644
--- a/Core/Code/Interactions/mitkDisplayVectorInteractorScroll.h
+++ b/Core/Code/Interactions/mitkDisplayVectorInteractorScroll.h
@@ -1,124 +1,123 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-28 17:19:30 +0200 (Thu, 28 May 2009) $
-Version: $Revision: 17495 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKDISPLAYVECTORINTERACTORSCROLL_H_HEADER_INCLUDED_C10DC4EB
#define MITKDISPLAYVECTORINTERACTORSCROLL_H_HEADER_INCLUDED_C10DC4EB
#include <MitkExports.h>
#include "mitkBaseRenderer.h"
#include "mitkStateMachine.h"
namespace mitk {
class Operation;
class OperationActor;
/**
* @brief Interactor for scrolling through the slices of an image
*
* This class implements an Interactor for slice-scrolling. It is defined by the 'Scroll'-statemachine which maps 'initmove' to left mousebutton pressed,
* 'scroll' to left mousebutton and move and 'finishmove' to left mousebutton released.
*
* Thus it is possible to scroll through the slices of an image rapidly, without using the mousewheel.
*
* @ingroup MITK_CORE_EXPORT
**/
class MITK_CORE_EXPORT DisplayVectorInteractorScroll : public StateMachine
{
public:
mitkClassMacro(DisplayVectorInteractorScroll, StateMachine);
mitkNewMacro2Param(Self, const char*, OperationActor*);
#pragma GCC visibility push(default)
itkEventMacro( InteractionEvent, itk::AnyEvent );
itkEventMacro( StartScrollInteractionEvent, InteractionEvent );
itkEventMacro( EndScrollInteractionEvent, InteractionEvent );
#pragma GCC visibility pop
/**
* @brief Method derived from OperationActor to recieve and execute operations
**/
virtual void ExecuteOperation(Operation* operation);
/**
* \brief Defines how many slices are scrolled per pixel that the mouse cursor has moved
*/
void SetIndexToSliceModifier( int modifier );
void SetAutoRepeat( bool autoRepeat );
void SetInvertScrollingDirection( bool );
bool IsAltModifierActive() const;
protected:
/**
* @brief Default Constructor
**/
DisplayVectorInteractorScroll(const char * type, mitk::OperationActor* destination=NULL);
/**
* @brief Default Destructor
**/
virtual ~DisplayVectorInteractorScroll();
/**
* @brief Method derived from StateMachine to implement the own actions
**/
virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
private:
BaseRenderer::Pointer m_Sender;
mitk::Point2D m_StartDisplayCoordinate;
mitk::Point2D m_LastDisplayCoordinate;
mitk::Point2D m_CurrentDisplayCoordinate;
OperationActor* m_Destination;
/**
* \brief Modifier that defines how many slices are scrolled per pixel that the mouse has moved
*
* This modifier defines how many slices the scene is scrolled per pixel that the mouse cursor has moved.
* By default the modifier is 4. This means that when the user moves the cursor by 4 pixels in Y-direction
* the scene is scrolled by one slice. If the user has moved the the cursor by 20 pixels, the scene is
* scrolled by 5 slices.
*
* If the cursor has moved less than m_IndexToSliceModifier pixels the scene is scrolled by one slice.
*/
int m_IndexToSliceModifier;
/**
* \brief Defines if it is possible to scroll endlessly
*
* If AutoRepeat is on, scrolling further than the last slice will restart at the first slice and vice versa
*/
bool m_AutoRepeat;
bool m_InvertScrollingDirection;
bool m_IsAltModifierActive;
};
} // namespace mitk
#endif /* MITKDISPLAYVECTORINTERACTOR_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Core/Code/Interactions/mitkEvent.cpp b/Core/Code/Interactions/mitkEvent.cpp
index 2eb97088f3..daca6fbbe0 100644
--- a/Core/Code/Interactions/mitkEvent.cpp
+++ b/Core/Code/Interactions/mitkEvent.cpp
@@ -1,74 +1,73 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkEvent.h"
mitk::Event::Event(mitk::BaseRenderer* sender, int type, int button,
int buttonState, int key)
: m_Sender( sender ), m_Type( type ), m_Button( button ), m_ButtonState( buttonState ),
m_Key( key )
{
}
mitk::Event::~Event()
{
}
mitk::BaseRenderer* mitk::Event::GetSender() const
{
return m_Sender;
}
int mitk::Event::GetType() const
{
return m_Type;
}
int mitk::Event::GetButtonState() const
{
return m_ButtonState;
}
int mitk::Event::GetButton() const
{
return m_Button;
}
int mitk::Event::GetKey() const
{
return m_Key;
}
bool mitk::Event::operator==(const Event& event) const
{
const mitk::Event *input = dynamic_cast<const mitk::Event*>(&event);
if(input==0) return false;
if ( (m_Type == event.GetType())
&& (m_Button == event.GetButton())
&& (m_ButtonState == event.GetButtonState())
&& (m_Key == event.GetKey()) )
{
return true;
}
else
{
return false;
}
}
diff --git a/Core/Code/Interactions/mitkEvent.h b/Core/Code/Interactions/mitkEvent.h
index c16d289f9a..a412bb41dc 100644
--- a/Core/Code/Interactions/mitkEvent.h
+++ b/Core/Code/Interactions/mitkEvent.h
@@ -1,77 +1,76 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 EVENT_H_HEADER_INCLUDED_C1889CEE
#define EVENT_H_HEADER_INCLUDED_C1889CEE
#include <MitkExports.h>
namespace mitk {
class BaseRenderer;
//##Documentation
//## @brief represents an Event with all its information
//##
//## Class, that stores mouse as well as key-events. Type stores the type of
//## event, that has been activated (KeyPress, MouseMove...), Button and Key
//## represent the cause of this event and ButtonState holds the Modifiers,
//## that might have been pressed during the appearance of this event.
//## Ether Button (Mouse) or Key (Keyboard) is set. if both are set
//## accidentally then the button is accepted.
//## @ingroup Interaction
class MITK_CORE_EXPORT Event
{
public:
//##Documentation
//## @param sender Needed for DisplayCoordinateOperation in DisplayVectorInteractor....???? if not needed, then set on NULL
//## @param type Type of Event: Mouse or Key Event? (look in mitkInteractionConst.h)
//## @param button Mouse button
//## @param buttonState Which other key has been pressed? (Mouse/Keyboard modifier-keys)
//## @param key Pressed key
Event(mitk::BaseRenderer* sender, int type, int button, int buttonState, int key);
virtual ~Event();
mitk::BaseRenderer* GetSender() const;
int GetType() const;
int GetButton() const;
int GetKey() const;
bool operator==(const Event& event) const;
int GetButtonState() const;
protected:
mitk::BaseRenderer* m_Sender;
int m_Type;
int m_Button;
int m_ButtonState;
int m_Key;
};
} // namespace mitk
#endif /* EVENT_H_HEADER_INCLUDED_C1889CEE */
diff --git a/Core/Code/Interactions/mitkEventDescription.cpp b/Core/Code/Interactions/mitkEventDescription.cpp
index 8177b85a70..082531acfe 100644
--- a/Core/Code/Interactions/mitkEventDescription.cpp
+++ b/Core/Code/Interactions/mitkEventDescription.cpp
@@ -1,34 +1,33 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkEventDescription.h"
mitk::EventDescription::EventDescription(int type, int button, int buttonState, int key, std::string name, int id)
: Event(NULL, type, button, buttonState, key), m_Name(name), m_Id(id)
{}
std::string mitk::EventDescription::GetName() const
{
return m_Name;
}
int mitk::EventDescription::GetId() const
{
return m_Id;
}
diff --git a/Core/Code/Interactions/mitkEventDescription.h b/Core/Code/Interactions/mitkEventDescription.h
index 64fbcb2f21..d5c6c685e3 100644
--- a/Core/Code/Interactions/mitkEventDescription.h
+++ b/Core/Code/Interactions/mitkEventDescription.h
@@ -1,53 +1,52 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 EVENTDESCRIPTION_H_HEADER_INCLUDED_C188FC4D
#define EVENTDESCRIPTION_H_HEADER_INCLUDED_C188FC4D
#include <MitkExports.h>
#include "mitkEvent.h"
#include <string>
namespace mitk {
//##Documentation
//## @brief adds additional Information (Name and EventID) to an Event
//##
//## A name and an ID is added to the information of an event, so the event can
//## be processed futher on.
//## @ingroup Interaction
class MITK_CORE_EXPORT EventDescription : public Event
{
public:
EventDescription(int type, int button, int buttonState,int key, std::string name, int id);
std::string GetName() const;
int GetId() const;
private:
std::string m_Name;
int m_Id;
};
} // namespace mitk
#endif /* EVENTDESCRIPTION_H_HEADER_INCLUDED_C188FC4D */
diff --git a/Core/Code/Interactions/mitkEventMapper.cpp b/Core/Code/Interactions/mitkEventMapper.cpp
index ba824ea125..10939949d6 100644
--- a/Core/Code/Interactions/mitkEventMapper.cpp
+++ b/Core/Code/Interactions/mitkEventMapper.cpp
@@ -1,700 +1,699 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
/**
* EventMapping:
* This class maps the Events, usually given by the OS or here by QT, to a MITK internal EventId.
* It loads all information from the xml-file (possible, understandable Events with the mitkEventID).
* If an event appears, the method MapEvent is called with the event params.
* This Method looks up the event params, and tries to find an mitkEventId to it.
* If yes, then sends the event and the found ID to the globalStateMachine, which handles all
* further operations of that event.
*
*/
#include "mitkEventMapper.h"
#include "mitkInteractionConst.h"
#include "mitkStateEvent.h"
#include "mitkOperationEvent.h"
#include "mitkGlobalInteraction.h"
#include <mitkEventMapperAddOn.h>
#include "mitkStandardFileLocations.h"
//#include <mitkInteractionDebugger.h>
#include "mitkConfig.h"
#include "mitkCoreObjectFactory.h"
#include <itkOutputWindow.h>
#include <itkMacro.h>
#include <vtkObjectFactory.h>
#include <vector>
namespace mitk
{
vtkStandardNewMacro(EventMapper);
}
#ifdef MBI_INTERNAL_CONFERENCE
#include <mitkGeometry3D.h>
#include <mitkDisplayPositionEvent.h>
#include <mitkConferenceKit.h>
#include <mitkConferenceToken.h>
#include <mitkBaseRenderer.h>
#endif //MBI_INTERNAL_CONFERENCE
//XML Event
const std::string mitk::EventMapper::STYLE = "STYLE";
const std::string mitk::EventMapper::NAME = "NAME";
const std::string mitk::EventMapper::ID = "ID";
const std::string mitk::EventMapper::TYPE = "TYPE";
const std::string mitk::EventMapper::BUTTON = "BUTTON";
const std::string mitk::EventMapper::BUTTONSTATE = "BUTTONSTATE";
const std::string mitk::EventMapper::KEY = "KEY";
const std::string mitk::EventMapper::EVENTS = "events";
const std::string mitk::EventMapper::EVENT = "event";
mitk::EventMapper::EventDescriptionVec mitk::EventMapper::m_EventDescriptions;
std::string mitk::EventMapper::m_XmlFileName;
mitk::StateEvent mitk::EventMapper::m_StateEvent;
std::string mitk::EventMapper::m_StyleName;
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
mitk::EventMapper::EventMapper()
{
//map with string to key for mapping string from xml-file to int
m_EventConstMap["Type_None"] = mitk::Type_None; // invalid event
m_EventConstMap["Type_Timer"] = mitk::Type_Timer; // timer event
m_EventConstMap["Type_MouseButtonPress"] = mitk::Type_MouseButtonPress; // mouse button pressed
m_EventConstMap["Type_MouseButtonRelease"] = mitk::Type_MouseButtonRelease; // mouse button released
m_EventConstMap["Type_MouseButtonDblClick"] = mitk::Type_MouseButtonDblClick; // mouse button double click
m_EventConstMap["Type_MouseMove"] = mitk::Type_MouseMove; // mouse move
m_EventConstMap["Type_KeyPress"] = mitk::Type_KeyPress; // key pressed
m_EventConstMap["Type_KeyRelease"] = mitk::Type_KeyRelease; // key released
m_EventConstMap["Type_FocusIn"] = 8; // keyboard focus received
m_EventConstMap["Type_FocusOut"] = 9; // keyboard focus lost
m_EventConstMap["Type_Enter"] = 10; // mouse enters widget
m_EventConstMap["Type_Leave"] = 11; // mouse leaves widget
m_EventConstMap["Type_Paint"] = 12; // paint widget
m_EventConstMap["Type_Move"] = 13; // move widget
m_EventConstMap["Type_Resize"] = 14; // resize widget
m_EventConstMap["Type_Create"] = 15; // after object creation
m_EventConstMap["Type_Destroy"] = 16; // during object destruction
m_EventConstMap["Type_Show"] = 17; // widget is shown
m_EventConstMap["Type_Hide"] = 18; // widget is hidden
m_EventConstMap["Type_Close"] = 19; // request to close widget
m_EventConstMap["Type_Quit"] = 20; // request to quit application
m_EventConstMap["Type_Reparent"] = 21; // widget has been reparented
m_EventConstMap["Type_ShowMinimized"] = 22; // widget is shown minimized
m_EventConstMap["Type_ShowNormal"] = 23; // widget is shown normal
m_EventConstMap["Type_WindowActivate"] = 24; // window was activated
m_EventConstMap["Type_WindowDeactivate"] = 25; // window was deactivated
m_EventConstMap["Type_ShowToParent"] = 26; // widget is shown to parent
m_EventConstMap["Type_HideToParent"] = 27; // widget is hidden to parent
m_EventConstMap["Type_ShowMaximized"] = 28; // widget is shown maximized
m_EventConstMap["Type_ShowFullScreen"] = 29; // widget is shown full-screen
m_EventConstMap["Type_Accel"] = 30; // accelerator event
m_EventConstMap["Type_Wheel"] = 31; // wheel event
m_EventConstMap["Type_AccelAvailable"] = 32; // accelerator available event
m_EventConstMap["Type_CaptionChange"] = 33; // caption changed
m_EventConstMap["Type_IconChange"] = 34; // icon changed
m_EventConstMap["Type_ParentFontChange"] = 35; // parent font changed
m_EventConstMap["Type_ApplicationFontChange"] = 36;// application font changed
m_EventConstMap["Type_ParentPaletteChange"] = 37; // parent palette changed
m_EventConstMap["Type_ApplicationPaletteChange"] = 38;// application palette changed
m_EventConstMap["Type_PaletteChange"] = 39; // widget palette changed
m_EventConstMap["Type_Clipboard"] = 40; // internal clipboard event
m_EventConstMap["Type_Speech"] = 42; // reserved for speech input
m_EventConstMap["Type_SockAct"] = 50; // socket activation
m_EventConstMap["Type_AccelOverride"] = 51; // accelerator override event
m_EventConstMap["Type_DeferredDelete"] = 52; // deferred delete event
m_EventConstMap["Type_DragEnter"] = 60; // drag moves into widget
m_EventConstMap["Type_DragMove"] = 61; // drag moves in widget
m_EventConstMap["Type_DragLeave"] = 62; // drag leaves or is cancelled
m_EventConstMap["Type_Drop"] = 63; // actual drop
m_EventConstMap["Type_DragResponse"] = 64; // drag accepted/rejected
m_EventConstMap["Type_ChildInserted"] = 70; // new child widget
m_EventConstMap["Type_ChildRemoved"] = 71; // deleted child widget
m_EventConstMap["Type_LayoutHint"] = 72; // child min/max size changed
m_EventConstMap["Type_ShowWindowRequest"] = 73; // widget's window should be mapped
m_EventConstMap["Type_ActivateControl"] = 80; // ActiveX activation
m_EventConstMap["Type_DeactivateControl"] = 81; // ActiveX deactivation
m_EventConstMap["Type_ContextMenu"] = 82; // context popup menu
m_EventConstMap["Type_IMStart"] = 83; // input method composition start
m_EventConstMap["Type_IMCompose"] = 84; // input method composition
m_EventConstMap["Type_IMEnd"] = 85; // input method composition end
m_EventConstMap["Type_Accessibility"] = 86; // accessibility information is requested
m_EventConstMap["Type_TabletMove"] = 87; // Wacom tablet event
m_EventConstMap["Type_LocaleChange"] = 88; // the system locale changed
m_EventConstMap["Type_LanguageChange"] = 89; // the application language changed
m_EventConstMap["Type_LayoutDirectionChange"] = 90; // the layout direction changed
m_EventConstMap["Type_Style"] = 91; // internal style event
m_EventConstMap["Type_TabletPress"] = 92; // tablet press
m_EventConstMap["Type_TabletRelease"] = 93; // tablet release
// apparently not necessary, since the IDs can be assigned earlier (in the AddOns after they are generated in the driver)
//m_EventConstMap["Type_TDMouseInput"] = mitk::Type_TDMouseInput; // 3D mouse input occured
m_EventConstMap["Type_User"] = 1000; // first user event id
m_EventConstMap["Type_MaxUser"] = 65535; // last user event id
//ButtonState
m_EventConstMap["BS_NoButton"] = mitk::BS_NoButton;//0x0000
m_EventConstMap["BS_LeftButton"] = mitk::BS_LeftButton;//0x0001
m_EventConstMap["BS_RightButton"] = mitk::BS_RightButton;//0x0002
m_EventConstMap["BS_MidButton"] = mitk::BS_MidButton;//0x0004
m_EventConstMap["BS_MouseButtonMask"] = mitk::BS_MouseButtonMask;//0x0007
m_EventConstMap["BS_ShiftButton"] = mitk::BS_ShiftButton;//0x0008
m_EventConstMap["BS_ControlButton"] = mitk::BS_ControlButton;//0x0010
m_EventConstMap["BS_AltButton"] = mitk::BS_AltButton;//0x0020
m_EventConstMap["BS_KeyButtonMask"] = mitk::BS_KeyButtonMask;//0x0038
m_EventConstMap["BS_Keypad"] = mitk::BS_Keypad;//0x4000
//Modifier
m_EventConstMap["Mod_SHIFT"] = 0x00200000;
m_EventConstMap["Mod_CTRL"] = 0x00400000;
m_EventConstMap["Mod_ALT"] = 0x00800000;
m_EventConstMap["Mod_MODIFIER_MASK"] = 0x00e00000;
m_EventConstMap["Mod_UNICODE_ACCEL"] = 0x10000000;
m_EventConstMap["Mod_ASCII_ACCEL"] = 0x10000000;
//Key
m_EventConstMap["Key_Escape"] = 0x1000;
m_EventConstMap["Key_Tab"] = 0x1001;
m_EventConstMap["Key_Backtab"] = 0x1002;
m_EventConstMap["Key_BackTab"] = 0x1002;
m_EventConstMap["Key_Backspace"] = 0x1003;
m_EventConstMap["Key_BackSpace"] = 0x1003;
m_EventConstMap["Key_Return"] = 0x1004;
m_EventConstMap["Key_Enter"] = 0x1005;
m_EventConstMap["Key_Insert"] = 0x1006;
m_EventConstMap["Key_Delete"] = 0x1007;
m_EventConstMap["Key_Pause"] = 0x1008;
m_EventConstMap["Key_Print"] = 0x1009;
m_EventConstMap["Key_SysReq"] = 0x100a;
m_EventConstMap["Key_Home"] = 0x1010;
m_EventConstMap["Key_End"] = 0x1011;
m_EventConstMap["Key_Left"] = 0x1012;
m_EventConstMap["Key_Up"] = 0x1013;
m_EventConstMap["Key_Right"] = 0x1014;
m_EventConstMap["Key_Down"] = 0x1015;
m_EventConstMap["Key_Prior"] = 0x1016;
m_EventConstMap["Key_PageUp"] = 0x1016;
m_EventConstMap["Key_Next"] = 0x1017;
m_EventConstMap["Key_PageDown"] = 0x1017;
m_EventConstMap["Key_Shift"] = 0x1020;
m_EventConstMap["Key_Control"] = 0x1021;
m_EventConstMap["Key_Meta"] = 0x1022;
m_EventConstMap["Key_Alt"] = 0x1023;
m_EventConstMap["Key_CapsLock"] = 0x1024;
m_EventConstMap["Key_NumLock"] = 0x1025;
m_EventConstMap["Key_ScrollLock"] = 0x1026;
m_EventConstMap["Key_F1"] = 0x1030;
m_EventConstMap["Key_F2"] = 0x1031;
m_EventConstMap["Key_F3"] = 0x1032;
m_EventConstMap["Key_F4"] = 0x1033;
m_EventConstMap["Key_F5"] = 0x1034;
m_EventConstMap["Key_F6"] = 0x1035;
m_EventConstMap["Key_F7"] = 0x1036;
m_EventConstMap["Key_F8"] = 0x1037;
m_EventConstMap["Key_F9"] = 0x1038;
m_EventConstMap["Key_F10"] = 0x1039;
m_EventConstMap["Key_F11"] = 0x103a;
m_EventConstMap["Key_F12"] = 0x103b;
m_EventConstMap["Key_F13"] = 0x103c;
m_EventConstMap["Key_F14"] = 0x103d;
m_EventConstMap["Key_F15"] = 0x103e;
m_EventConstMap["Key_F16"] = 0x103f;
m_EventConstMap["Key_F17"] = 0x1040;
m_EventConstMap["Key_F18"] = 0x1041;
m_EventConstMap["Key_F19"] = 0x1042;
m_EventConstMap["Key_F20"] = 0x1043;
m_EventConstMap["Key_F21"] = 0x1044;
m_EventConstMap["Key_F22"] = 0x1045;
m_EventConstMap["Key_F23"] = 0x1046;
m_EventConstMap["Key_F24"] = 0x1047;
m_EventConstMap["Key_F25"] = 0x1048;
m_EventConstMap["Key_F26"] = 0x1049;
m_EventConstMap["Key_F27"] = 0x104a;
m_EventConstMap["Key_F28"] = 0x104b;
m_EventConstMap["Key_F29"] = 0x104c;
m_EventConstMap["Key_F30"] = 0x104d;
m_EventConstMap["Key_F31"] = 0x104e;
m_EventConstMap["Key_F32"] = 0x104f;
m_EventConstMap["Key_F33"] = 0x1050;
m_EventConstMap["Key_F34"] = 0x1051;
m_EventConstMap["Key_F35"] = 0x1052;
m_EventConstMap["Key_Super_L"] = 0x1053;
m_EventConstMap["Key_Super_R"] = 0x1054;
m_EventConstMap["Key_Menu"] = 0x1055;
m_EventConstMap["Key_Hyper_L"] = 0x1056;
m_EventConstMap["Key_Hyper_R"] = 0x1057;
m_EventConstMap["Key_Help"] = 0x1058;
m_EventConstMap["Key_Muhenkan"] = 0x1122;
m_EventConstMap["Key_Henkan"] = 0x1123;
m_EventConstMap["Key_Hiragana_Katakana"] = 0x1127;
m_EventConstMap["Key_Zenkaku_Hankaku"] = 0x112A;
m_EventConstMap["Key_Space"] = 0x20;
m_EventConstMap["Key_Any"] = 0x20;
m_EventConstMap["Key_Exclam"] = 0x21;
m_EventConstMap["Key_QuoteDbl"] = 0x22;
m_EventConstMap["Key_NumberSign"] = 0x23;
m_EventConstMap["Key_Dollar"] = 0x24;
m_EventConstMap["Key_Percent"] = 0x25;
m_EventConstMap["Key_Ampersand"] = 0x26;
m_EventConstMap["Key_Apostrophe"] = 0x27;
m_EventConstMap["Key_ParenLeft"] = 0x28;
m_EventConstMap["Key_ParenRight"] = 0x29;
m_EventConstMap["Key_Asterisk"] = 0x2a;
m_EventConstMap["Key_Plus"] = 0x2b;
m_EventConstMap["Key_Comma"] = 0x2c;
m_EventConstMap["Key_Minus"] = 0x2d;
m_EventConstMap["Key_Period"] = 0x2e;
m_EventConstMap["Key_Slash"] = 0x2f;
m_EventConstMap["Key_0"] = 0x30;
m_EventConstMap["Key_1"] = 0x31;
m_EventConstMap["Key_2"] = 0x32;
m_EventConstMap["Key_3"] = 0x33;
m_EventConstMap["Key_4"] = 0x34;
m_EventConstMap["Key_5"] = 0x35;
m_EventConstMap["Key_6"] = 0x36;
m_EventConstMap["Key_7"] = 0x37;
m_EventConstMap["Key_8"] = 0x38;
m_EventConstMap["Key_9"] = 0x39;
m_EventConstMap["Key_Colon"] = 0x3a;
m_EventConstMap["Key_Semicolon"] = 0x3b;
m_EventConstMap["Key_Less"] = 0x3c;
m_EventConstMap["Key_Equal"] = 0x3d;
m_EventConstMap["Key_Greater"] = 0x3e;
m_EventConstMap["Key_Question"] = 0x3f;
m_EventConstMap["Key_At"] = 0x40;
m_EventConstMap["Key_A"] = 0x41;
m_EventConstMap["Key_B"] = 0x42;
m_EventConstMap["Key_C"] = 0x43;
m_EventConstMap["Key_D"] = 0x44;
m_EventConstMap["Key_E"] = 0x45;
m_EventConstMap["Key_F"] = 0x46;
m_EventConstMap["Key_G"] = 0x47;
m_EventConstMap["Key_H"] = 0x48;
m_EventConstMap["Key_I"] = 0x49;
m_EventConstMap["Key_J"] = 0x4a;
m_EventConstMap["Key_K"] = 0x4b;
m_EventConstMap["Key_L"] = 0x4c;
m_EventConstMap["Key_M"] = 0x4d;
m_EventConstMap["Key_N"] = 0x4e;
m_EventConstMap["Key_O"] = 0x4f;
m_EventConstMap["Key_P"] = 0x50;
m_EventConstMap["Key_Q"] = 0x51;
m_EventConstMap["Key_R"] = 0x52;
m_EventConstMap["Key_S"] = 0x53;
m_EventConstMap["Key_T"] = 0x54;
m_EventConstMap["Key_U"] = 0x55;
m_EventConstMap["Key_V"] = 0x56;
m_EventConstMap["Key_W"] = 0x57;
m_EventConstMap["Key_X"] = 0x58;
m_EventConstMap["Key_Y"] = 0x59;
m_EventConstMap["Key_Z"] = 0x5a;
m_EventConstMap["Key_BracketLeft"] = 0x5b;
m_EventConstMap["Key_Backslash"] = 0x5c;
m_EventConstMap["Key_BracketRight"] = 0x5d;
m_EventConstMap["Key_AsciiCircum"] = 0x5e;
m_EventConstMap["Key_Underscore"] = 0x5f;
m_EventConstMap["Key_QuoteLeft"] = 0x60;
m_EventConstMap["Key_BraceLeft"] = 0x7b;
m_EventConstMap["Key_Bar"] = 0x7c;
m_EventConstMap["Key_BraceRight"] = 0x7d;
m_EventConstMap["Key_AsciiTilde"] = 0x7e;
m_EventConstMap["Key_nobreakspace"] = 0x0a0;
m_EventConstMap["Key_exclamdown"] = 0x0a1;
m_EventConstMap["Key_cent"] = 0x0a2;
m_EventConstMap["Key_sterling"] = 0x0a3;
m_EventConstMap["Key_currency"] = 0x0a4;
m_EventConstMap["Key_yen"] = 0x0a5;
m_EventConstMap["Key_brokenbar"] = 0x0a6;
m_EventConstMap["Key_section"] = 0x0a7;
m_EventConstMap["Key_diaeresis"] = 0x0a8;
m_EventConstMap["Key_copyright"] = 0x0a9;
m_EventConstMap["Key_ordfeminine"] = 0x0aa;
m_EventConstMap["Key_guillemotleft"] = 0x0ab;
m_EventConstMap["Key_notsign"] = 0x0ac;
m_EventConstMap["Key_hyphen"] = 0x0ad;
m_EventConstMap["Key_registered"] = 0x0ae;
m_EventConstMap["Key_macron"] = 0x0af;
m_EventConstMap["Key_degree"] = 0x0b0;
m_EventConstMap["Key_plusminus"] = 0x0b1;
m_EventConstMap["Key_twosuperior"] = 0x0b2;
m_EventConstMap["Key_threesuperior"] = 0x0b3;
m_EventConstMap["Key_acute"] = 0x0b4;
m_EventConstMap["Key_mu"] = 0x0b5;
m_EventConstMap["Key_paragraph"] = 0x0b6;
m_EventConstMap["Key_periodcentered"] = 0x0b7;
m_EventConstMap["Key_cedilla"] = 0x0b8;
m_EventConstMap["Key_onesuperior"] = 0x0b9;
m_EventConstMap["Key_masculine"] = 0x0ba;
m_EventConstMap["Key_guillemotright"] = 0x0bb;
m_EventConstMap["Key_onequarter"] = 0x0bc;
m_EventConstMap["Key_onehalf"] = 0x0bd;
m_EventConstMap["Key_threequarters"] = 0x0be;
m_EventConstMap["Key_questiondown"] = 0x0bf;
m_EventConstMap["Key_Agrave"] = 0x0c0;
m_EventConstMap["Key_Aacute"] = 0x0c1;
m_EventConstMap["Key_Acircumflex"] = 0x0c2;
m_EventConstMap["Key_Atilde"] = 0x0c3;
m_EventConstMap["Key_Adiaeresis"] = 0x0c4;
m_EventConstMap["Key_Aring"] = 0x0c5;
m_EventConstMap["Key_AE"] = 0x0c6;
m_EventConstMap["Key_Ccedilla"] = 0x0c7;
m_EventConstMap["Key_Egrave"] = 0x0c8;
m_EventConstMap["Key_Eacute"] = 0x0c9;
m_EventConstMap["Key_Ecircumflex"] = 0x0ca;
m_EventConstMap["Key_Ediaeresis"] = 0x0cb;
m_EventConstMap["Key_Igrave"] = 0x0cc;
m_EventConstMap["Key_Iacute"] = 0x0cd;
m_EventConstMap["Key_Icircumflex"] = 0x0ce;
m_EventConstMap["Key_Idiaeresis"] = 0x0cf;
m_EventConstMap["Key_ETH"] = 0x0d0;
m_EventConstMap["Key_Ntilde"] = 0x0d1;
m_EventConstMap["Key_Ograve"] = 0x0d2;
m_EventConstMap["Key_Oacute"] = 0x0d3;
m_EventConstMap["Key_Ocircumflex"] = 0x0d4;
m_EventConstMap["Key_Otilde"] = 0x0d5;
m_EventConstMap["Key_Odiaeresis"] = 0x0d6;
m_EventConstMap["Key_multiply"] = 0x0d7;
m_EventConstMap["Key_Ooblique"] = 0x0d8;
m_EventConstMap["Key_Ugrave"] = 0x0d9;
m_EventConstMap["Key_Uacute"] = 0x0da;
m_EventConstMap["Key_Ucircumflex"] = 0x0db;
m_EventConstMap["Key_Udiaeresis"] = 0x0dc;
m_EventConstMap["Key_Yacute"] = 0x0dd;
m_EventConstMap["Key_THORN"] = 0x0de;
m_EventConstMap["Key_ssharp"] = 0x0df;
m_EventConstMap["Key_agrave"] = 0x0e0;
m_EventConstMap["Key_aacute"] = 0x0e1;
m_EventConstMap["Key_acircumflex"] = 0x0e2;
m_EventConstMap["Key_atilde"] = 0x0e3;
m_EventConstMap["Key_adiaeresis"] = 0x0e4;
m_EventConstMap["Key_aring"] = 0x0e5;
m_EventConstMap["Key_ae"] = 0x0e6;
m_EventConstMap["Key_ccedilla"] = 0x0e7;
m_EventConstMap["Key_egrave"] = 0x0e8;
m_EventConstMap["Key_eacute"] = 0x0e9;
m_EventConstMap["Key_ecircumflex"] = 0x0ea;
m_EventConstMap["Key_ediaeresis"] = 0x0eb;
m_EventConstMap["Key_igrave"] = 0x0ec;
m_EventConstMap["Key_iacute"] = 0x0ed;
m_EventConstMap["Key_icircumflex"] = 0x0ee;
m_EventConstMap["Key_idiaeresis"] = 0x0ef;
m_EventConstMap["Key_eth"] = 0x0f0;
m_EventConstMap["Key_ntilde"] = 0x0f1;
m_EventConstMap["Key_ograve"] = 0x0f2;
m_EventConstMap["Key_oacute"] = 0x0f3;
m_EventConstMap["Key_ocircumflex"] = 0x0f4;
m_EventConstMap["Key_otilde"] = 0x0f5;
m_EventConstMap["Key_odiaeresis"] = 0x0f6;
m_EventConstMap["Key_division"] = 0x0f7;
m_EventConstMap["Key_oslash"] = 0x0f8;
m_EventConstMap["Key_ugrave"] = 0x0f9;
m_EventConstMap["Key_uacute"] = 0x0fa;
m_EventConstMap["Key_ucircumflex"] = 0x0fb;
m_EventConstMap["Key_udiaeresis"] = 0x0fc;
m_EventConstMap["Key_yacute"] = 0x0fd;
m_EventConstMap["Key_thorn"] = 0x0fe;
m_EventConstMap["Key_ydiaeresis"] = 0x0ff;
m_EventConstMap["Key_unknown"] = 0xffff;
m_EventConstMap["Key_none"] = 0xffff;
}
mitk::EventMapper::~EventMapper()
{
}
//##Documentation
//## searches for the event in m_EventDescription and adds the corresponding eventID
//##
bool mitk::EventMapper::MapEvent(Event* event, GlobalInteraction* globalInteraction, int mitkPostedEventID )
{
int eventID = mitkPostedEventID;
if( mitkPostedEventID == 0 )
{
//search the event in the list of event descriptions, if found, then take the number and produce a stateevent
EventDescriptionVecIter iter;
for (iter = m_EventDescriptions.begin(); iter!=m_EventDescriptions.end();iter++)
{
if (*iter == *event)
break;
}
if (iter == m_EventDescriptions.end())//not found
return false;
eventID = (*iter).GetId();
}
//set the Menger_Var m_StateEvent and send to StateMachine, which does everything further!
m_StateEvent.Set( eventID, event );
/*
Group and Object EventId:
then EventMapper has the power to decide which operations hang together;
each event causes n (n e N) operations (e.g. StateChanges, data-operations...).
Undo must recall all these coherent operations, so all of the same objectId.
But Undo has also the power to recall more operationsets, for example a set for building up a new object,
so that a newly build up object is deleted after a Undo and not only the latest set point.
The StateMachines::ExecuteAction have the power to descide weather a new GroupID has to be calculated
(by example after the editing of a new object)
A user interaction with the mouse is started by a mousePressEvent, continues with a MouseMove and finishes with a MouseReleaseEvent
*/
switch (event->GetType())
{
case mitk::Type_MouseButtonPress://Increase
mitk::OperationEvent::IncCurrObjectEventId();
break;
case mitk::Type_MouseMove://same
break;
case mitk::Type_MouseButtonRelease://same
break;
case mitk::Type_User://same
break;
case mitk::Type_KeyPress://Increase
mitk::OperationEvent::IncCurrObjectEventId();
break;
default://increase
mitk::OperationEvent::IncCurrObjectEventId();
}
#ifdef MBI_INTERNAL_CONFERENCE
//Conference - pass local events through
if ( mitkPostedEventID == 0 )
{
mitk::CoreObjectFactory::GetInstance()->MapEvent(event,eventID);
}
#endif //MBI_INTERNAL_CONFERENCE
mitk::OperationEvent::ExecuteIncrement();
if ( globalInteraction != NULL )
{
return globalInteraction->HandleEvent( &m_StateEvent );
}
else
{
return mitk::GlobalInteraction::GetInstance()->HandleEvent(&m_StateEvent);
}
}
bool mitk::EventMapper::LoadBehavior(std::string fileName)
{
if ( fileName.empty() )
return false;
if (m_XmlFileName.length() > 0)
{
if (fileName.compare(m_XmlFileName) == 0)
return true; // this is nothing bad, we already loaded this file.
}
this->SetFileName( fileName.c_str() );
m_XmlFileName = fileName.c_str();
return ( this->Parse() );
}
bool mitk::EventMapper::LoadBehaviorString(std::string xmlString)
{
if ( xmlString.empty() )
return false;
return ( this->Parse(xmlString.c_str(), xmlString.length()) );
}
bool mitk::EventMapper::LoadStandardBehavior()
{
// Search for StateMachine.xml, bypass relative path in mitkSourceTree for additional search
std::string xmlFileName = mitk::StandardFileLocations::GetInstance()->FindFile("StateMachine.xml", "Core/Code/Interactions");
if(xmlFileName != "")
return LoadBehavior(xmlFileName);
return false;
}
//##Documentation
//## @brief converts the given const String declared in the xml-file
//## to the defined const int
inline int mitk::EventMapper::convertConstString2ConstInt(std::string input)
{
ConstMapIter tempIt = m_EventConstMap.find(input.c_str());
if (tempIt != m_EventConstMap.end())
{
return (tempIt)->second;
}
//mitk::StatusBar::GetInstance()->DisplayText("Warning! from mitkEventMapper.cpp: Couldn't find matching Event Int from Event String in XML-File");
return -1;//for didn't find anything
}
void mitk::EventMapper::StartElement (const char *elementName, const char **atts)
{
if ( elementName == EVENT )
{
// EventDescription(int type, int button, int buttonState,int key, std::string name, int id)
EventDescription eventDescr( convertConstString2ConstInt( ReadXMLStringAttribut( TYPE, atts )),
convertConstString2ConstInt( ReadXMLStringAttribut( BUTTON, atts )),
ReadXMLIntegerAttribut( BUTTONSTATE, atts ),
convertConstString2ConstInt( ReadXMLStringAttribut( KEY, atts )),
ReadXMLStringAttribut( NAME, atts ),
ReadXMLIntegerAttribut( ID, atts ));
//check for a double entry unless it is an event for internal usage
if (eventDescr.GetType()!= mitk::Type_User)
{
for (EventDescriptionVecIter iter = m_EventDescriptions.begin(); iter!=m_EventDescriptions.end(); iter++)
{
if (*iter == eventDescr)
{
MITK_DEBUG << "Event description " << eventDescr.GetName() << " already present! Skipping event description";
return;
}
}
}
m_EventDescriptions.push_back(eventDescr);
}
else if ( elementName == EVENTS )
m_StyleName = ReadXMLStringAttribut( STYLE, atts );
}
std::string mitk::EventMapper::GetStyleName() const
{
return m_StyleName;
}
std::string mitk::EventMapper::ReadXMLStringAttribut( std::string name, const char** atts )
{
if(atts)
{
const char** attsIter = atts;
while(*attsIter)
{
if ( name == *attsIter )
{
attsIter++;
return *attsIter;
}
attsIter++;
attsIter++;
}
}
return std::string();
}
int mitk::EventMapper::ReadXMLIntegerAttribut( std::string name, const char** atts )
{
std::string s = ReadXMLStringAttribut( name, atts );
static const std::string hex = "0x";
int result;
if ( s[0] == hex[0] && s[1] == hex[1] )
result = strtol( s.c_str(), NULL, 16 );
else
result = atoi( s.c_str() );
return result;
}
void mitk::EventMapper::SetStateEvent(mitk::Event* event)
{
m_StateEvent.Set( m_StateEvent.GetId(), event );
}
bool mitk::EventMapper::RefreshStateEvent(mitk::StateEvent* stateEvent)
{
//search the event within stateEvent in the list of event descriptions, if found adapt stateEvent ID
EventDescriptionVecIter iter;
for (iter = m_EventDescriptions.begin(); iter!=m_EventDescriptions.end(); iter++)
{
if (*iter == *(stateEvent->GetEvent()))
break;
}
if (iter != m_EventDescriptions.end())//found
{
stateEvent->Set((*iter).GetId(), stateEvent->GetEvent());
return true;
}
else
return false;
return false;
}
void mitk::EventMapper::AddEventMapperAddOn(mitk::EventMapperAddOn* newAddOn)
{
bool addOnAlreadyAdded = false;
for(AddOnVectorType::const_iterator it = this->m_AddOnVector.begin();it != m_AddOnVector.end();it++)
{
if(*it == newAddOn)
{
addOnAlreadyAdded = true;
break;
}
}
if(!addOnAlreadyAdded)
{
m_AddOnVector.push_back(newAddOn);
MITK_INFO << "AddOn Count: " << m_AddOnVector.size();
}
}
void mitk::EventMapper::RemoveEventMapperAddOn(mitk::EventMapperAddOn* unusedAddOn)
{
for(AddOnVectorType::iterator it = this->m_AddOnVector.begin();it != m_AddOnVector.end();it++)
{
if(*it == unusedAddOn)
{
m_AddOnVector.erase(it);
break;
}
}
}
diff --git a/Core/Code/Interactions/mitkEventMapper.h b/Core/Code/Interactions/mitkEventMapper.h
index 8c8c4411ae..43fb3cc32b 100644
--- a/Core/Code/Interactions/mitkEventMapper.h
+++ b/Core/Code/Interactions/mitkEventMapper.h
@@ -1,202 +1,201 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 EVENTMAPPER_H_HEADER_INCLUDED
#define EVENTMAPPER_H_HEADER_INCLUDED
#include <mitkEvent.h>
#include <MitkExports.h>
#include <mitkEventDescription.h>
#include <vtkXMLParser.h>
#include <itkSmartPointer.h>
#include <vector>
#include <map>
namespace mitk {
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
typedef std::string msgString;
//for friendship wor to set the stateevent after calculating
class GlobalInteraction;
class StateMachine;
class StateEvent;
class EventMapperAddOn;
//##Documentation
//## @brief Maps an Event to its description
//##
//## EventMapping:
//## This class mapps the Events, usually given by the OS or here by QT, to a MITK internal EventId.
//## It loads all information from the xml-file (possible, understandable Events with the mitkEventID).
//## If an event appears, the method MapEvent is called with the event params.
//## This Method looks up the event params, and tries to find an mitkEventId to it.
//## If yes, then sends the event and the found ID to the globalStateMachine, which handles all
//## further operations of that event.
//## For Undo-Mechanism a statechanging StateMachine::HandleEvent is connected to an ObjectEventID and an GroupEventId.
//## That way a fine an raw Undo is possible (fine for ObjectID by ObjectID, raw for GroupID for GroupID)
//## Here the ObjectEventID gets increased,
//## not the GroupEventId(must get increased by a StateMachine, that has the information when a new Group of operation starts)
//## @ingroup Interaction
class MITK_CORE_EXPORT EventMapper : public vtkXMLParser
{
public:
static EventMapper *New();
vtkTypeMacro(EventMapper,vtkXMLParser);
typedef std::vector<mitk::EventDescription> EventDescriptionVec;
typedef std::vector<mitk::EventDescription>::iterator EventDescriptionVecIter;
typedef std::map<const char*, int, ltstr> ConstMap;
typedef std::map<const char*, int, ltstr>::iterator ConstMapIter;
typedef std::vector< itk::SmartPointer<mitk::EventMapperAddOn> > AddOnVectorType;
//##Documentation
//## searches the Event in m_EventDescription
//## and if included transmits the event to globalInteraction.
//## If specified, a custom instance of GlobalInteraction will be used,
//## otherwise the method will retrieve the default (singleton) instance.
//## the optional parameter should be used in a conference to avoid a
//## feedback
static bool MapEvent(Event* event, GlobalInteraction* globalInteraction = NULL, int mitkPostedEventID=0 );
//##Documentation
//## Searches for the event within stateEvent in the internal map of event descriptions
//## If entry found the stateEvent ID is adapted
//## maps the Event in m_EventDescription with the ID
//## and if found returns true,
//## if not found it returns false
static bool RefreshStateEvent(StateEvent* stateEvent);
//##Documentation
//## loads an XML-File containing events and adds definition to internal mapping list
//##
//## Several files can be loaded. Event descriptions have to be unique or a warning will be displayed.
//## If the same file is loaded twice,
//## it will only be parsed the first time.
//## If a file A, then a file B and then file A is to be loaded, warnings
//## will be displayed when loading file A the second time.
bool LoadBehavior(std::string fileName);
//##Documentation
//## loads Events into m_EventDescriptions from xml string
//## also involved: EventMapper::startEvent(...)
bool LoadBehaviorString(std::string xmlString);
//##Documentation
//## Try to load standard behavior file "StateMachine.xml"
//##
//## Search strategy:
//## \li try environment variable "MITKCONF" (path to "StateMachine.xml")
//## \li try "./StateMachine.xml"
//## \li try via source directory (using MITKROOT from cmake-created
//## mitkConfig.h) "MITKROOT/Interactions/mitkBaseInteraction/StateMachine.xml"
bool LoadStandardBehavior();
//##Documentation
//## reads a Tag from an XML-file
//## adds Events to m_EventDescription
std::string GetStyleName() const;
//friendship because of SetStateEvent for computing WorldCoordinates
friend class mitk::GlobalInteraction;
/**
* @brief adds a new EventMapper addon
*/
void AddEventMapperAddOn(mitk::EventMapperAddOn* newAddOn);
/**
* @brief removes an EventMapper addon
*/
void RemoveEventMapperAddOn(mitk::EventMapperAddOn* unusedAddOn);
protected:
EventMapper();
~EventMapper();
//##Documentation
//##@brief method only for GlobalInteraction to change the Event (from DiplayPositionEvent to PositionEvent)
static void SetStateEvent(Event* event);
private:
//##Documentation
//## @brief method used in XLM-Reading; gets called when a start-tag is read
void StartElement (const char *elementName, const char **atts);
//##Documentation
//## @brief reads an XML-String-Attribute
std::string ReadXMLStringAttribut( std::string name, const char** atts);
//##Documentation
//## @brief reads an XML-Integer-Attribute
int ReadXMLIntegerAttribut( std::string name, const char** atts );
//##Documentation
//## @brief converts the strings given by the XML-Behaviour-File to int
inline int convertConstString2ConstInt(std::string input);
//static std::string Convert2String(int input);
//static std::string Convert2String(double input);
//static std::string Convert2String(float input);
//##Documentation
//## @brief maps the strings to int for convertion from XML-Behaviour-File
ConstMap m_EventConstMap;
//##Documentation
//## @brief stores the information for the connection between QT-Events and the internal EventId.
//## gets this information from xml-File
static EventDescriptionVec m_EventDescriptions;
static std::string m_XmlFileName;
static StateEvent m_StateEvent;
//##Documentation
//## @brief stores the name of the Event-Style loaded
static std::string m_StyleName;
static const std::string STYLE;
static const std::string NAME;
static const std::string ID;
static const std::string TYPE;
static const std::string BUTTON;
static const std::string BUTTONSTATE;
static const std::string KEY;
static const std::string EVENTS;
static const std::string EVENT;
/**
* @brief all available EventMapper addons consisting of one or more input devices
*/
AddOnVectorType m_AddOnVector;
};
} // namespace mitk
#endif /* EVENTMAPPER_H_HEADER_INCLUDED_C187864A */
diff --git a/Core/Code/Interactions/mitkEventMapperAddOn.h b/Core/Code/Interactions/mitkEventMapperAddOn.h
index 00204f0732..d9b86db09c 100644
--- a/Core/Code/Interactions/mitkEventMapperAddOn.h
+++ b/Core/Code/Interactions/mitkEventMapperAddOn.h
@@ -1,49 +1,48 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-03-31 17:34:48 +0200 (Mi, 31 Mrz 2010) $
-Version: $Revision: 21985 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKEVENTMAPPERADDON_H_
#define MITKEVENTMAPPERADDON_H_
#include <mitkStateEvent.h>
#include <mitkGlobalInteraction.h>
namespace mitk {
/**
* The event mapper addon resembles an interface, that allows addons, which are not stored in the core <br>
* to be used inside the core. For an additional input device it is mandatory to inherit from this class.
*
* @noimplement This interface is not intended to be implemented by clients.
* @ingroup Interaction
*/
class MITK_CORE_EXPORT EventMapperAddOn : public itk::Object
{
public:
/**
* Forwards an event fired by the driver of device to the <code>mitk::GlobalInteraction</code>
*
* @param e the event, who should be processed
*/
virtual void ForwardEvent(const mitk::StateEvent* e)
{
mitk::GlobalInteraction::GetInstance()->HandleEvent(e);
}
}; // end struct EventMapperAddOn
} // end namespace mitk
#endif /* MITKEVENTMAPPERADDON_H_ */
diff --git a/Core/Code/Interactions/mitkGlobalInteraction.cpp b/Core/Code/Interactions/mitkGlobalInteraction.cpp
index bd88ad216a..a73ccb5d74 100755
--- a/Core/Code/Interactions/mitkGlobalInteraction.cpp
+++ b/Core/Code/Interactions/mitkGlobalInteraction.cpp
@@ -1,458 +1,457 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGlobalInteraction.h"
#include "mitkInteractionConst.h"
#include "mitkStateEvent.h"
#include "mitkPositionEvent.h"
#include <itksys/SystemTools.hxx>
#include <vtkWorldPointPicker.h>
mitk::GlobalInteraction::GlobalInteraction()
: StateMachine(NULL)
, m_StateMachineFactory(NULL)
, m_EventMapper(NULL)
, m_CurrentlyInInformListenersLoop(false)
, m_CurrentlyInInformInteractorsLoop(false)
, m_IsInitialized(false)
{
}
mitk::GlobalInteraction::~GlobalInteraction()
{
//s_GlobalInteraction doesn't have to be set = NULL;
// StateMachineFactory and EventMapper have to be deleted explicitly, as they inherit from Vtk
if (this->IsInitialized())
{
m_StateMachineFactory->Delete();
m_StateMachineFactory = NULL;
m_EventMapper->Delete();
m_EventMapper = NULL;
}
m_ListenerList.clear();
m_InteractorList.clear();
m_SelectedList.clear();
m_JurisdictionMap.clear();
m_FocusManager = NULL;
}
inline mitk::StateEvent* GenerateEmptyStateEvent(int eventId)
{
mitk::Event *noEvent = new mitk::Event(NULL,
mitk::Type_User,
mitk::BS_NoButton,
mitk::BS_NoButton,
mitk::Key_none);
mitk::StateEvent *stateEvent = new mitk::StateEvent(eventId, noEvent);
return stateEvent;
}
void mitk::GlobalInteraction::AddListener(mitk::StateMachine* listener)
{
if(listener == NULL) return;
if(dynamic_cast<Interactor*>(listener)!=NULL)
{
MITK_WARN << "Trying to add an Interactor ("
<< listener->GetNameOfClass() << ") as a listener. "
<< "This will probably cause problems";
}
if ( std::find(m_ListenerList.begin(), m_ListenerList.end(),listener) == m_ListenerList.end() )
{
m_ListenerList.push_back(listener);
}
}
bool mitk::GlobalInteraction::RemoveListener(mitk::StateMachine* listener)
{
// Defers removal to a time after the current event handling is finished. Otherwise the implementation of InformListeners would crash sometimes.
m_ListenersFlaggedForRemoval.push_back(listener);
StateMachineListIter position = std::find(m_ListenerList.begin(), m_ListenerList.end(),listener);
bool removePossible = (position != m_ListenerList.end());
RemoveFlaggedListeners();
return removePossible;
}
void mitk::GlobalInteraction::RemoveFlaggedListeners()
{
if (m_CurrentlyInInformListenersLoop) return;
// iterate flagged listeners, remove them if possible
if (m_ListenersFlaggedForRemoval.empty()) return;
for (StateMachineCPointerListIter it = m_ListenersFlaggedForRemoval.begin(); it != m_ListenersFlaggedForRemoval.end(); ++it)
{
StateMachineListIter foundPosition = std::find( m_ListenerList.begin(), m_ListenerList.end(), *it );
if (foundPosition != m_ListenerList.end())
{
m_ListenerList.erase( foundPosition );
}
}
m_ListenersFlaggedForRemoval.clear();
}
void mitk::GlobalInteraction::AddInteractor(mitk::Interactor* interactor)
{
if(interactor == NULL) return;
if ( std::find(m_InteractorList.begin(), m_InteractorList.end(),interactor) == m_InteractorList.end() )
{
m_InteractorList.push_back(interactor);
//if Interactor already selected, then add to selected list
if (interactor->GetMode()==Interactor::SMSELECTED)
this->AddToSelectedInteractors(interactor);
}
}
bool mitk::GlobalInteraction::InteractorRegistered (mitk::Interactor* interactor)
{
if ( std::find(m_InteractorList.begin(), m_InteractorList.end(), interactor) == m_InteractorList.end() )
return false;
else
return true;
}
bool mitk::GlobalInteraction::ListenerRegistered (mitk::StateMachine* listener)
{
if ( std::find(m_ListenerList.begin(), m_ListenerList.end(), listener) == m_ListenerList.end() )
return false;
else
return true;
}
bool mitk::GlobalInteraction::RemoveInteractor(mitk::Interactor* interactor)
{
InteractorListIter position = std::find(m_InteractorList.begin(), m_InteractorList.end(),interactor);
if (position == m_InteractorList.end())
return false;
position = m_InteractorList.erase(position);
//check if the interactor is also held in SelectedList
this->RemoveFromSelectedInteractors(interactor);
//check if in JurisdictionMap
for (InteractorMapIter it = m_JurisdictionMap.begin(); it != m_JurisdictionMap.end(); it++)
{
if ((*it).second == interactor)
{
if (m_CurrentInteractorIter == it)
m_CurrentInteractorIter = m_JurisdictionMap.end();
m_JurisdictionMap.erase(it);
break;
}
}
return true;
}
void mitk::GlobalInteraction::InformListeners(mitk::StateEvent const* stateEvent)
{
m_CurrentlyInInformListenersLoop = true;
for (StateMachineListIter it = m_ListenerList.begin(); it != m_ListenerList.end(); it++)
{
if((*it).IsNotNull())
(*it)->HandleEvent(stateEvent);
}
m_CurrentlyInInformListenersLoop = false;
RemoveFlaggedListeners();
}
bool mitk::GlobalInteraction::AskSelected(mitk::StateEvent const* stateEvent)
{
if (m_SelectedList.empty())
return false;
bool ok = false, oneOk = false;
//copy of m_SelectedList to be stable if an iterator gets removed during the following steps
InteractorList copyOfSelectedList = m_SelectedList;
InteractorListIter it = copyOfSelectedList.begin();
for (; it != copyOfSelectedList.end(); it++)
{
oneOk = (*it)->HandleEvent(stateEvent);
//if one HandleEvent did succeed, then set returnvalue on true;
if (oneOk)
ok = true;
}
return ok;
}
void mitk::GlobalInteraction::FillJurisdictionMap(mitk::StateEvent const* stateEvent, float threshold)
{
m_JurisdictionMap.clear();
for (InteractorListIter it = m_InteractorList.begin(); it != m_InteractorList.end(); it++)
{
if ((*it).IsNotNull())
{
//first ask for CanHandleEvent(..) and write it into the map if > 0
float value = (*it)->CanHandleEvent(stateEvent);
if (value > threshold)
{
m_JurisdictionMap.insert(InteractorMap::value_type(value, (*it)));
}
}
}
//set the iterator to the first element to start stepping through interactors
if (! m_JurisdictionMap.empty())
m_CurrentInteractorIter = m_JurisdictionMap.begin();
else
m_CurrentInteractorIter = m_JurisdictionMap.end();
}
/*
* Go through the list of interactors, that could possibly handle an event and ask if it has handled the event.
* If an interactor has handled an event, it should add itself to the list of selectedInteractors
* Ask as long as no interactor answers, that it could be handled
*/
bool mitk::GlobalInteraction::AskCurrentInteractor(mitk::StateEvent const* stateEvent)
{
//no need to check if we don't have any interactors. nearly equal to m_CurrentInteractorIter == m_JurisdictionMap.end
if (m_JurisdictionMap.empty())
return false;
bool handled = false;
while ( m_CurrentInteractorIter != m_JurisdictionMap.end()&& !handled)
{
handled = (*m_CurrentInteractorIter).second->HandleEvent(stateEvent);
if (!handled)
m_CurrentInteractorIter++;
}
//loop for later usage
if (m_CurrentInteractorIter == m_JurisdictionMap.end())
m_CurrentInteractorIter = m_JurisdictionMap.begin();
return handled;
}
bool mitk::GlobalInteraction::AddFocusElement(mitk::FocusManager::FocusElement* element)
{
return m_FocusManager->AddElement(element);
}
bool mitk::GlobalInteraction::RemoveFocusElement(mitk::FocusManager::FocusElement* element)
{
return m_FocusManager->RemoveElement(element);
}
mitk::FocusManager::FocusElement* mitk::GlobalInteraction::GetFocus()
{
return m_FocusManager->GetFocused();
}
bool mitk::GlobalInteraction::SetFocus(mitk::FocusManager::FocusElement* element)
{
return m_FocusManager->SetFocused(element);
}
mitk::FocusManager* mitk::GlobalInteraction::GetFocusManager()
{
return m_FocusManager.GetPointer();
}
mitk::EventMapper* mitk::GlobalInteraction::GetEventMapper()
{
if (!this->IsInitialized())
{
MITK_FATAL <<"Global Interaction needs initialization!\n";
return NULL;
}
return m_EventMapper;
}
bool mitk::GlobalInteraction::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
bool ok = false;
ok = false;
switch (action->GetActionId())
{
case AcDONOTHING:
ok = true;
break;
case AcINFORMLISTENERS:
InformListeners(stateEvent);
ok = true;
break;
case AcASKINTERACTORS:
if (! AskSelected(stateEvent))//no interactor selected anymore
{
//fill the jurisdictionMap to ask them bit by bit.
//currentInteractor is set here to the beginning
FillJurisdictionMap(stateEvent, 0);
//ask the Interactors to handle that event
AskCurrentInteractor(stateEvent);
}
ok = true;
break;
default:
ok = true;
}
return ok;
}
mitk::GlobalInteraction* mitk::GlobalInteraction::GetInstance()
{
static mitk::GlobalInteraction::Pointer s_GlobalInteraction;
if (s_GlobalInteraction.IsNull())
{
s_GlobalInteraction = mitk::GlobalInteraction::New();
}
return s_GlobalInteraction;
}
mitk::State* mitk::GlobalInteraction::GetStartState(const char* type)
{
if ( this->IsInitialized() )
return m_StateMachineFactory->GetStartState(type);
MITK_FATAL << "Fatal Error in mitkGlobalInteraction.cpp: GlobalInteraction not initialized!\n";
return NULL;
}
bool mitk::GlobalInteraction::AddToSelectedInteractors(mitk::Interactor* interactor)
{
InteractorListIter position = std::find(m_SelectedList.begin(), m_SelectedList.end(),interactor);
if (position != m_SelectedList.end())
{
//already added so don't add once more!
return true;
}
else
m_SelectedList.push_back(interactor);
return true;
}
bool mitk::GlobalInteraction::RemoveFromSelectedInteractors(mitk::Interactor* interactor)
{
if (interactor == NULL)
return false;
InteractorListIter position = std::find(m_SelectedList.begin(), m_SelectedList.end(),interactor);
if (position != m_SelectedList.end())
{
position = m_SelectedList.erase(position);
return true;
}
else
return false;
}
mitk::StateMachineFactory* mitk::GlobalInteraction::GetStateMachineFactory()
{
return m_StateMachineFactory;
}
bool mitk::GlobalInteraction::Initialize(const char* globalInteractionName, const std::string XMLBehaviorInput)
{
if (this->IsInitialized())
{
MITK_WARN <<"Global Interaction has already been initialized.\n";
return false;
}
m_FocusManager = FocusManager::New();
// instantiates m_StateMachineFactory and load interaction patterns from XML string
//if factory has been initialized before, delete it and initialize once more to not add patterns
if (m_StateMachineFactory)
m_StateMachineFactory->Delete();
m_StateMachineFactory = StateMachineFactory::New();
//if EventMapper was initialized before, delete it and initialize once more
// to create new event descriptions and not to add them
if (m_EventMapper)
m_EventMapper->Delete();
m_EventMapper = EventMapper::New();
bool success = true;
if (XMLBehaviorInput == "")
{
//load default behavior
success &= m_StateMachineFactory->LoadStandardBehavior();
success &= m_EventMapper->LoadStandardBehavior();
}
else if (itksys::SystemTools::FileExists(XMLBehaviorInput.c_str()) )
{
// load standard behavior from file
success &= m_StateMachineFactory->LoadBehavior(XMLBehaviorInput);
success &= m_EventMapper->LoadBehavior(XMLBehaviorInput);
}
else
{
//load standard behavior from XML string
success &= m_StateMachineFactory->LoadBehaviorString(XMLBehaviorInput);
success &= m_EventMapper->LoadBehaviorString(XMLBehaviorInput);
}
if(!success)
{
MITK_FATAL << "Error initializing global interaction!\n";
return false;
}
//now instantiate what could not be done in InitializeStateStates because StateMachineFactory was not up yet:
// (Re-) Initialize Superclass (StateMachine), because type was not given at time of construction
m_Type = globalInteractionName;
//get the start state of the pattern
State::Pointer startState = m_StateMachineFactory->GetStartState(globalInteractionName);
if (startState.IsNull())
{
MITK_FATAL << "Fatal Error in mitkGlobalInteraction.cpp: No StartState recieved from StateMachineFactory!\n";
return false;
}
//clear the vector
m_CurrentStateVector.clear();
//add the start state pointer for the first time step to the list
m_CurrentStateVector.push_back(startState);
m_IsInitialized = true;
return true;
}
diff --git a/Core/Code/Interactions/mitkGlobalInteraction.h b/Core/Code/Interactions/mitkGlobalInteraction.h
index a642f297d0..8947e9e0e7 100755
--- a/Core/Code/Interactions/mitkGlobalInteraction.h
+++ b/Core/Code/Interactions/mitkGlobalInteraction.h
@@ -1,275 +1,274 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 GLOBALINTERACTION_H_HEADER_INCLUDED_C152938A
#define GLOBALINTERACTION_H_HEADER_INCLUDED_C152938A
#include "mitkFocusManager.h"
#include <MitkExports.h>
#include "mitkStateMachineFactory.h"
#include "mitkEventMapper.h"
#include "mitkInteractor.h"
namespace mitk {
class PositionEvent;
//##Documentation
//## @brief handles all global Events
//##
//## superior statemachine, that spreads the events to all other interactors
//##
//## Initialization
//## Attention: GlobalInteraction <strong>must</strong> be initialized by the Initialize() method
//## before usage by giving it an XML scheme. Possibilities are giving it an empty string (default),
//## the filename of an XML file or the actual XML content as std::string. If an empty string is given,
//## the content is tried to be loaded from the default file location.
//##
//## Concept of sending events:
//## In this concept of interaction, the statemachines can be divided into two main statemachines:
//## Listeners and interactors.
//## Listeners only receive the event to process it, but don't change any data. They want to listen to all events.
//## Interactors do change data according to the received event. They do not need to receive all events, only
//## those they are interested in.
//##
//## To divide these two types of statemachine this class holds three lists and one map:
//## m_ListenerList, m_InteractorList, m_SelectedList and m_JurisdictionMap
//## The list m_ListenerList holds all listeners.
//## m_InteractorList holds all interactors, and the List m_SelectedList holds all machines, that were set to SELECTED or SUBSELECTED.
//## m_JurisdictionMap maps values returned from CanHandleEvent to the asked Interactors.
//## Through this map stepping through interactors, that were not selected and could handle that event, can be done.
//##
//## First the listeners are informed with the event.
//## Then the selected or subselected interactors are asked if they can handle that event.
//## They can handle it, if the mode of the interactor after HandleEvent(..) is still in SMSELECTED or SMSUBSELECTED.
//## They can't handle it, if the mode changed to SMDESELECTED. Then the interactor is removed from the selected-list.
//## In that case, all interactors are asked to calculate and return their area of jurisdiction.
//## An iterator is held on one interactor in the map. With the iterator, the map can be looped through so
//## so that several geometric objects, that lie on top of each other, can be selected.
//## @ingroup Interaction
class MITK_CORE_EXPORT GlobalInteraction : public StateMachine
{
public:
mitkClassMacro(GlobalInteraction, StateMachine);
itkNewMacro(Self);
typedef std::vector<StateMachine::Pointer> StateMachineList;
typedef std::vector<StateMachine*> StateMachineCPointerList;
typedef StateMachineList::iterator StateMachineListIter;
typedef StateMachineCPointerList::iterator StateMachineCPointerListIter;
typedef std::vector<Interactor::Pointer> InteractorList;
typedef InteractorList::iterator InteractorListIter;
typedef std::multimap<float, Interactor::Pointer, std::greater<double> > InteractorMap;
typedef InteractorMap::iterator InteractorMapIter;
//##Documentation
//## @brief add an Interactor to the list of all interactors that are asked for handling an event
//##
//## returns true in case of success
void AddInteractor(Interactor* interactor);
//##Documentation
//## @brief remove a certain Interactor from the set of interactors that are asked for handling an event
//##
//## returns true in case of success
bool RemoveInteractor(Interactor* interactor);
//##Documentation
//## @brief returns true, if the given interactor is already added to the Interactor-List
bool InteractorRegistered (Interactor* interactor);
//##Documentation
//## @brief add a Listener to the list of all Listeners that are informed of an event
//##
//## returns true in case of success
void AddListener(StateMachine* listener);
//##Documentation
//## @brief remove a certain Listener from the set of Listeners that are informed of an event
//##
//## returns true in case of success
bool RemoveListener(StateMachine* listener);
//##Documentation
//## @brief returns true, if the given interactor is already added to the Listener-List
bool ListenerRegistered (StateMachine* listener);
//##Documentation
//## @brief adds an element in the list in FocusManager
//##
//## true if success, false if the element is already in list
bool AddFocusElement(FocusManager::FocusElement* element);
//##Documentation
//## @brief Removes an element in FocusManager
//##
//## true if success, false if the element was not in the list
bool RemoveFocusElement(FocusManager::FocusElement* element);
//##Documentation
//## @brief Returns the focused Element in FocusManager
FocusManager::FocusElement* GetFocus();
//##Documentation
//## @brief Sets the given Element to focused
//##
//## returns true if the given element was found and focused
bool SetFocus(FocusManager::FocusElement* element);
//##Documentation
//## @brief Returns the pointer to the FocusManager
//##
//## to add the observer for an event
FocusManager* GetFocusManager();
//##Documentation
//## @brief Returns the pointer to the EventMapper
//##
//## to add an addon
EventMapper* GetEventMapper();
/**
* @brief Return StateMachineFactory
**/
StateMachineFactory* GetStateMachineFactory();
/**
* @brief Returns the StartState of the StateMachine with the name type;
*
* Asks member StateMachineFactory for the StartState.
* Returns NULL if no entry with name type is found.
**/
State* GetStartState(const char* type);
//##Documentation
//## @brief Returns the global (singleton) instance of
//## GlobalInteraction. Create it, if it does not exist.
static GlobalInteraction* GetInstance();
//##Documentation
//## @brief Initializes the global (singleton) instance of
//## GlobalInteraction via an XML string. Must! be done before usage. Can be done only once.
//## Can be used with an empty string (default), a file name with path, or the actual XML content as string.
bool Initialize(const char* globalInteractionName, const std::string XMLBehaviorInput = "");
//##Documentation
//## @brief Check if GlobalInteraction has already been initialized. Init must! be done before usage.
bool IsInitialized() {return m_IsInitialized;};
//so that the interactors can call AddToSelectedInteractors() and RemoveFromSelectedInteractors()
friend class Interactor;
protected:
/**
* @brief Default Constructor with type to load the StateMachinePattern of the StateMachine
* @param XMLbehaviorFile the file which contains the statemachine and event patterns
* @param type the name of the statemachine pattern this class shall use
**/
GlobalInteraction();
/**
* @brief Default destructor.
**/
~GlobalInteraction();
virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
/*
*@brief adds the given interactor to the list of selected interactors.
* This list is asked first to handle an event.
*/
virtual bool AddToSelectedInteractors(Interactor* interactor);
/*
*@brief removes the given interactor from the list of selected interactors
* This list is asked first to handle an event.
*/
virtual bool RemoveFromSelectedInteractors(Interactor* interactor);
private:
//##Documentation
//##@brief informing all statemachines that are held in the list m_ListenerList
void InformListeners(mitk::StateEvent const* stateEvent);
//##Documentation
//##@brief asking the selected Interactor if an event can be handled
//##
//## returns false if no Interactor could handle the event
bool AskSelected(mitk::StateEvent const* stateEvent);
//##Documentation
//##@brief asking next interactor of m_JurisdictionMap
bool AskCurrentInteractor(mitk::StateEvent const* stateEvent);
//##Documentation
//##@brief filling m_JurisdictionMap
//##
//## @ params swell: if the calculated jurisdiction value is above swell, then add it to the map
void FillJurisdictionMap(mitk::StateEvent const* stateEvent, float threshold);
void RemoveFlaggedListeners();
StateMachineCPointerList m_ListenersFlaggedForRemoval;
//##Documentation
//## @brief list of all listening statemachines, that want to receive all events
StateMachineList m_ListenerList;
//##Documentation
//## @brief list of all interactors (statemachine, that change data)
InteractorList m_InteractorList;
//##Documentation
//## @brief list of all interactors, that are in Mode SELECTED or SUBSELECTED
InteractorList m_SelectedList;
//##Documentation
//## @brief map for sorting all interactors by the value returned from CanHandleEvent(..).
//##
//## With that list certain interactors can be looped through like diving through layers
InteractorMap m_JurisdictionMap;
//##Documentation
//## @brief iterator on an entry in m_JurisdictionMap for stepping through interactors
InteractorMapIter m_CurrentInteractorIter;
//##Documentation
//## @brief holds a list of BaseRenderer and one focused
FocusManager::Pointer m_FocusManager;
/**
* @brief StatemachineFactory loads statemachine patterns and provides start states
**/
StateMachineFactory* m_StateMachineFactory;
/**
* @brief EventMapper loads event patterns
**/
EventMapper* m_EventMapper;
bool m_CurrentlyInInformListenersLoop;
bool m_CurrentlyInInformInteractorsLoop;
bool m_IsInitialized;
};
} // namespace mitk
#endif /* GLOBALINTERACTION_H_HEADER_INCLUDED_C152938A */
diff --git a/Core/Code/Interactions/mitkInteractionConst.h b/Core/Code/Interactions/mitkInteractionConst.h
index 0008a96f22..2ae48728d0 100644
--- a/Core/Code/Interactions/mitkInteractionConst.h
+++ b/Core/Code/Interactions/mitkInteractionConst.h
@@ -1,783 +1,782 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKINTERACTCONST_H
#define MITKINTERACTCONST_H
//##Documentation
//## @file mitkInteractionConst.h
//## @brief Constants for most interaction classes, due to the generic StateMachines.
//##
//## Changes in Type, ButtonState or Key has to be don in mitkEventMapper.cpp, too.
//## @ingroup Interaction
/*Prefixes for Constants:
E = Enumeration
EID = EventId's
Op = Operations
Ac = Action
Type_ = Type of Event
BS_ = ButtonStates and Buttons
Key_ = Keys like in QT
*/
namespace mitk{
//Constants for EventIds; use the according constant to through an event in the code
enum EEventIds
{
EIDNULLEVENT = 0,
EIDLEFTMOUSEBTN = 1,
EIDRIGHTMOUSEBTN = 2,
EIDLEFTMOUSEBTNANDSHIFT = 3,
EIDMIDDLEMOUSEBTN = 4,
EIDLEFTMOUSEBTNANDCTRL = 5,
EIDMIDDLEMOUSEBTNANDCTRL = 6,
EIDRIGHTMOUSEBTNANDCTRL = 7,
EIDLEFTMOUSEBTNDOUBLECLICK = 8,
EIDMOUSEWHEEL = 9,
EIDLEFTMOUSERELEASE = 505,
EIDMIDDLEMOUSERELEASE = 506,
EIDRIGHTMOUSERELEASE = 507,
EIDLEFTMOUSERELEASEANDSHIFT = 508,
EIDMOUSEMOVE = 520,
EIDLEFTMOUSEBTNANDMOUSEWHEEL = 521,
EIDRIGHTMOUSEBTNANDMOUSEWHEEL = 522,
EIDMIDDLEMOUSEBTNANDMOUSEWHEEL = 523,
EIDLEFTMOUSEBTNANDMOUSEMOVE = 530,
EIDRIGHTMOUSEBTNANDMOUSEMOVE = 531,
EIDMIDDLEMOUSEBTNANDMOUSEMOVE = 533,
EIDCTRLANDLEFTMOUSEBTNANDMOUSEMOVE = 534,
EIDCTRLANDRIGHTMOUSEBTNANDMOUSEMOVE = 535,
EIDCTRLANDMIDDLEMOUSEBTNANDMOUSEMOVE = 536,
EIDCTRLANDLEFTMOUSEBTNRELEASE = 537,
EIDCTRLANDRIGHTMOUSEBTNRELEASE = 538,
EIDCTRLANDMIDDLEMOUSEBTNRELEASE = 539,
EIDSHIFTANDCTRLANDMIDDLEMOUSEBTN = 540,
EIDSHIFTANDLEFTMOUSEBTNANDMOUSEMOVE = 541,
EIDSHIFTANDCTRLANDMOUSEMOVE = 542,
EIDSHIFTANDCTRLANDMOUSERELEASE = 543,
EIDALTANDLEFTMOUSEBTN = 600,
EIDALTANDLEFTMOUSEBTNANDMOUSEMOVE = 610,
EIDALTANDLEFTMOUSERELEASE = 620,
EIDCTRLANDLEFTMOUSEWHEEL = 630,
EIDALTANDMOUSEWHEEL = 640,
EIDALTANDMIDDLEMOUSEBTN = 641,
EIDALTANDMIDDLEMOUSEBTNANDMOVE = 642,
EIDALTANDMIDDLEMOUSEBTNRELEASE = 643,
EIDALTANDSHIFTANDRIGHTMOUSEBTN = 644,
EIDALTANDSHIFTANDRIGHTMOUSEBTNANDMOUSEMOVE = 645,
EIDALTANDSHIFTANDRIGHTMOUSEBTNRELEASE = 646,
EIDSHIFTANDRIGHTMOUSEPRESS = 2000,
EIDSHIFTANDRIGHTMOUSEMOVE = 2001,
EIDSHIFTANDRIGHTMOUSERELEASE = 2002,
EIDSHIFTANDMIDDLEMOUSEPRESS = 2003,
EIDSHIFTANDMIDDLEMOUSEMOVE = 2004,
EIDSHIFTANDMIDDLEMOUSERELEASE = 2005,
EIDSPACENAVIGATORINPUT = 4001, // 3d Mouse, SpaceNavigator input
EIDSPACENAVIGATORKEYDOWN = 4002, // 3d Mouse, KeyDown
EIDWIIMOTEINPUT = 4003, // WiiMote input
EIDWIIMOTEBUTTON = 4004, // WiiMote home button
EIDWIIMOTEBUTTONB = 4005, // WiiMote b button
EIDSTRGANDN = 10,
EIDSTRGANDE = 11,
EIDDELETE = 12,
EIDN = 13,
EIDESCAPE = 14,
EIDP = 15,
EIDR = 16,
EIDT = 17,
EIDS = 18,
EIDE = 19,
EIDSTRGANDALTANDA = 20,
EIDSTRGANDALTANDB = 21,
EIDH = 22,
EIDRETURN = 23,
EIDENTER = 24,
EIDSPACE = 25,
EIDPLUS = 26,
EIDMINUS = 27,
EIDSTRGANDALTANDH = 30,
EIDSTRGANDALTANDI = 31,
EIDSTRGANDALTANDS = 40,
EIDALT = 90,
EIDSTRGANDB = 91,
EIDNEW = 1000,
EIDOLD = 1001,
EIDFINISHED = 1002,
EIDNO = 1003,
EIDYES = 1004,
EIDSAME = 1005,
EIDNOANDLASTOBJECT = 1006,
EIDNOANDNOTLASTOBJECT = 1007,
EIDLAST = 1008,
EIDNOTLAST = 1009,
EIDSTSMALERNMINUS1 = 1010,
EIDSTLARGERNMINUS1 = 1011,
EIDPOSITIONEVENT = 1012,
EIDEDIT = 1013,
EIDSMALLERN = 1014,
EIDEQUALSN = 1015,
EIDLARGERN = 1016,
EIDEMPTY = 1017,
EIDSUBDESELECT = 1020,
EIDSMTOSELECTED = 1030,
EIDSMTODESELECTED = 1031,
EIDTIP = 1050,
EIDHEAD = 1051,
EIDBODY = 1052,
EIDCLEAR = 1100,
EIDACTIVATETOOL = 1300,
EIDPRINT = 3001,
EV_INIT = 5551001,
EV_PREVIOUS = 5551002,
EV_PATH_COLLECTION_SELECTED = 5551003,
EV_NAVIGATION_SELECTED = 5551004,
EV_LESS_THEN_MIN_COUNT = 5551005,
EV_READY = 5551006,
EV_NEXT = 5551007,
EV_DONE = 5551008,
EV_NEW_LANDMARK = 5551009,
EV_REMOVE_LANDMARK = 5551010,
EIDINSIDE = 2500,
EIDA = 4001,
EIDB = 4002,
EIDC = 4003,
EIDD = 4004,
EIDF = 4005,
EIDG = 4006,
EIDI = 4007,
EIDJ = 4008,
EIDK = 4009,
EIDL = 4010,
EIDM = 4011,
EIDO = 4012,
EIDQ = 4013,
EIDU = 4014,
EIDV = 4015,
EIDW = 4016,
EIDX = 4017,
EIDY = 4018,
EIDZ = 4019,
EID1 = 4020,
EID2 = 4021,
EID3 = 4022,
EID4 = 4023,
EID5 = 4024,
EID6 = 4025,
EID7 = 4026,
EID8 = 4027,
EID9 = 4028,
EID0 = 4029,
EIDFIGUREHOVER = 12340,
EIDNOFIGUREHOVER = 12341
};
//##Constants for Operations
//## xomments are always examples of the usage
enum EOperations
{
OpNOTHING = 0,
OpTEST = 1,
OpNEWCELL = 10, //add a new cell
OpADD = 100, //add a point or a vessel
OpUNDOADD = 101,
OpADDLINE = 1001, //add a line
OpINSERT = 200, //insert a point at position
OpINSERTLINE = 201, //insert a line at position
OpINSERTPOINT = 202,
OpCLOSECELL = 250, //close a cell (to a polygon)
OpOPENCELL = 251, //close a cell (to a polygon)
OpMOVE = 300, //move a point
OpMOVELINE = 301, //move a line
OpMOVECELL = 302, //move a line
OpUNDOMOVE = 303,
OpMOVEPOINTUP = 304,
OpMOVEPOINTDOWN = 305,
OpREMOVE = 400, //remove a point at position
OpREMOVELINE = 401, //remove a line at position
OpREMOVECELL = 402, //remove a cell
OpREMOVEPOINT = 403,
OpDELETE = 500, //delete
OpDELETELINE = 501, //delete the last line in a cell
OpUNDELETE = 502,
OpDELETECELL = 505,
OpSTATECHANGE = 600, //change a state
OpTIMECHANGE = 601, //change a state
OpTERMINATE = 666, //change a state
OpSELECTPOINT = 700,
OpSELECTLINE = 701,
OpSELECTCELL = 702,
OpSELECTSUBOBJECT = 703, //for VesselGraphInteractor
//OpSELECTNEWSUBOBJECT = 704, //for VesselGraphInteractor
OpSELECT = 705,
OpDESELECTPOINT = 800,
OpDESELECTLINE = 801,
OpDESELECTCELL = 802,
OpDESELECTSUBOBJECT = 803, //for VesselGraphInteractor
OpDESELECTALL = 804, //for VesselGraphInteractor
OpDESELECT = 805,
OpNAVIGATE = 900,
OpZOOM = 1000,
OpSCALE = 1100,
OpROTATE = 1200,
OpORIENT = 1201,
OpRESTOREPLANEPOSITION = 1202,
OpSETPOINTTYPE = 1210,
OpMODECHANGE = 1500,
OpSENDCOORDINATES = 1600,
OpPERIPHERYSEARCH = 2000, //used in VesselGraphInteractor
OpROOTSEARCH = 2001, //used in VesselGraphInteractor
OpTHICKSTVESSELSEARCH = 2002, //used in VesselGraphInteractor
OpSHORTESTPATHSEARCH = 2003, //used in VesselGraphInteractor
OpATTRIBUTATION = 2004, //used in VesselGraphInteractor
OpDEFAULT = 2006, //used in VesselGraphInteractor
OpSURFACECHANGED = 3000, // used for changing polydata in surfaces
};
//##Constants for EventMapping...
//##connects the statemachine.xml-File with the implemented conditions.
//##within one statemachine the choice of the actionconstants is freely
//##
//## ActionId
enum EActions
{
AcDONOTHING = 0,
AcINITNEWOBJECT = 5,
AcINITEDITOBJECT = 6,
AcINITEDITGROUP = 7,
AcINITMOVEMENT = 8,
AcINITMOVE = 9,
AcINITFOREGROUND = 45, // used in SeedsInteractor for setting the foreground seeds
AcINITBACKGROUND = 46, // used in SeedsInteractor for setting the background seeds
AcINITNEUTRAL = 47, // used in SeedsInteractor for setting the neutral seeds (rubber)
AcINITUPDATE = 1235, // For shape model deformation
AcADDPOINT = 10,
AcADD = 11,
AcADDLINE = 12,
AcADDANDFINISH = 13,
AcADDSELECTEDTOGROUP = 64,
AcCHECKPOINT = 21,
AcCHECKLINE = 22,
AcCHECKCELL = 23,
AcCHECKELEMENT = 30, // check if there is a element close enough (picking)
AcCHECKOBJECT = 31, // check if an object is hit
AcCHECKNMINUS1 = 32, // check if the number of elements is equal to N-1
AcCHECKEQUALS1 = 33, // check if the number of elements in the data is equal to 1
AcCHECKNUMBEROFPOINTS = 330, //check the number of elements in the data
AcCHECKSELECTED = 34, // check if the given element is selected or not
AcCHECKONESELECTED = 340, //check if there is an element that is selected
AcCHECKHOVERING = 341, //check if there is an element that is selected
AcCHECKGREATERZERO = 35, // check if the current number of elements is greater than 0
AcCHECKGREATERTWO = 36, // check if the current number of elements is greater than two
AcCHECKOPERATION = 37, // check if the operation is of one spectial type
AcCHECKONESUBINTERACTOR = 38,
AcCHECKSUBINTERACTORS = 39,
AcFINISHOBJECT = 40,
AcFINISHGROUP = 41,
AcFINISHMOVEMENT = 42,
AcFINISHMOVE = 43,
AcFINISH = 44,
AcSEARCHOBJECT = 50,
AcSEARCHGROUP = 51,
AcSEARCHANOTHEROBJECT = 52, // one object is selected and another object is to be added to selection
AcSELECTPICKEDOBJECT = 60, // select the picked object and deselect others
AcSELECTANOTHEROBJECT = 61,
AcSELECTGROUP = 62,
AcSELECTALL = 63,
AcSELECT = 65,
AcSELECTPOINT = 66,
AcSELECTLINE = 68,
AcSELECTCELL = 67,
AcSELECTSUBOBJECT = 69, // used in VesselGraphInteractor
AcDESELECTOBJECT = 70, // deselect picked from group
AcDESELECTALL = 72,
AcDESELECT = 75,
AcDESELECTPOINT = 76,
AcDESELECTLINE = 78,
AcDESELECTCELL = 77,
AcNEWPOINT = 80,
AcNEWSUBOBJECT = 81,
AcMOVEPOINT = 90,
AcMOVESELECTED = 91,
AcMOVE = 92,
AcMOVEPOINTUP = 93,
AcMOVEPOINTDOWN = 94,
AcREMOVEPOINT = 100,
AcREMOVE = 101,
AcREMOVELINE = 102,
AcREMOVEALL = 103,
AcREMOVESELECTEDSUBOBJECT = 104, // used in VesselGraphInteractor
AcWHEEL = 105,
AcPLUS = 106,
AcMINUS = 107,
AcDELETEPOINT = 120,
AcCLEAR = 130, // clear all elements from a list
AcINSERTPOINT = 110,
AcINSERTLINE = 111,
AC_SET_NEXT_BUTTON_VISIBLE = 5550001,
AC_SET_NEXT_BUTTON_INVISIBLE = 5550002,
AC_SET_PREVIOUS_BUTTON_VISIBLE = 5550003,
AC_SET_PREVIOUS_BUTTON_INVISIBLE = 5550004,
AC_SET_ASSISTAND_WIDGET_STECK = 5550005,
AC_SETMAX_COUNT_REF_POINTS = 5550006,
AC_SET_NEXT_BUTTON_TEXT = 5550007,
AC_CHECK_LANDMARK_COUNT = 5550008,
AC_SET_DONE_FALSE = 5550009,
AC_INIT = 55500010,
AC_SET_APPLICATION_SELECTED_FALSE = 55500011,
AC_SENSOR_ATTACHED = 55500012,
AC_CLOSE_ASSISTENT = 55500013,
AC_START_APPLICATION_TEXT = 55500014,
AC_START_NAVIGATION = 55500015,
AC_START_PATHCOLLECTION = 55500016,
AC_LOAD_LANDMARKS = 55500017,
AC_CALCULATE_LANDMARK_TRANSFORM = 55500018,
AcTERMINATE_INTERACTION = 666,
AcTRANSLATESTART = 1000,
AcTRANSLATE = 1001,
AcSCALESTART = 1002,
AcSCALE = 1003,
AcROTATESTART = 1004,
AcROTATE = 1005,
AcINITAFFINEINTERACTIONS = 1006,
AcFINISHAFFINEINTERACTIONS = 1007,
AcTRANSLATEEND = 1008,
AcSCALEEND = 1009,
AcROTATEEND = 1010,
AcINITZOOM = 1011,
AcZOOM = 1012,
AcSCROLL = 1013,
AcLEVELWINDOW = 1014,
AcSCROLLMOUSEWHEEL = 1015,
AcSETSTARTPOINT = 1050,
AcMODEDESELECT = 1100, // set interactor in not selected mode
AcMODESELECT = 1101, // set interactor in selected mode
AcMODESUBSELECT = 1102, // set interacor in sub selected mode
AcINFORMLISTENERS = 1200, // GlobalInteraction
AcASKINTERACTORS = 1201, // GlobalInteraction
AcCHECKGREATERONE = 1500,
AcCHECKBOUNDINGBOX = 1510,
AcFORCESUBINTERACTORS = 1550,
AcSENDCOORDINATES = 1600,
AcTRANSMITEVENT = 2000, // to transmit an event to a lower Interactor/Statemachine
AcPERIPHERYSEARCH = 3000, // used in VesselGraphInteractor
AcROOTSEARCH = 3001, // used in VesselGraphInteractor
AcTHICKSTVESSELSEARCH = 3002, // used in VesselGraphInteractor
AcSHORTESTPATHSEARCH = 3003, // used in VesselGraphInteractor
AcSINGLE = 3004, // used in VesselGraphInteractor
AcATTRIBUTATION = 3005, // used in VesselGraphInteractor
AcDEFAULT = 3007, // used in VesselGraphInteractor
AcSETVESSELELEMENT = 3008, // used in VesselGraphInteractor
AcCHECKBARRIERSTATUS = 3010, // used in VesselGraphInteractor
AcUPDATEMESH = 1234, // For Shape Model Interaction
AcINCREASE = 49012,
AcDECREASE = 49013,
AcMODIFY = 49014,
AcUNDOUPDATE = 1236, // For restoring a mesh after an update
AcENTEROBJECT = 48000,
AcLEAVEOBJECT = 48001,
AcSWITCHOBJECT = 48002,
AcUPDATELINE = 48003,
AcINITLINE = 48004,
AcTERMINATELINE = 48005,
AcCREATEBOX = 48006,
AcCREATEOBJECTFROMLINE = 48007,
AcCANCEL = 48008,
AcACTIVATETOOL = 48009,
AcROTATEAROUNDPOINT1 = 49002,
AcROTATEAROUNDPOINT2 = 49003,
AcMOVEPOINT1 = 49004,
AcMOVEPOINT2 = 49005,
AcUPDATEPOINT = 49006,
AcUPDATERADIUSMOUSEWHEEL = 49007,
AcDISPLAYOPTIONS = 49009,
AcCYCLE = 49010,
AcACCEPT = 49011,
AcONSPACENAVIGATORMOUSEINPUT = 4001, // On input of 3D Mouse
AcONPACENAVIGATORKEYDOWN = 4002, // On input of 3D Mouse
AcONWIIMOTEINPUT = 4003, // used for wiimote to signal IR input
AcRESETVIEW = 4004, // used for wiimote to reset view
AcONWIIMOTEBUTTONRELEASED = 4005, // stops the surface interaction
AcCHECKPOSITION = 5000,
AcINITIALIZECONTOUR = 5001,
AcCALCULATENEWSEGMENTATION_SP= 5002,
AcINTERACTOR = 5003,
AcCALCULATENEWSEGMENTATION_BB= 5004
};
/*
//!!!!!!!!!!!!!!!!!!!!!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!
//EventMechanism:
//If you change anything from here on, then change in mitkEventMapper.cpp (Array of constants) as well.
//!!!!!!!!!!!!!!!!!!!!!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!
*/
//Type of an Event;
enum EEventType
{
Type_None = 0, // invalid event
Type_Timer = 1, // timer event
Type_MouseButtonPress = 2, // mouse button pressed
Type_MouseButtonRelease = 3, // mouse button released
Type_MouseButtonDblClick = 4, // mouse button double click
Type_MouseMove = 5, // mouse move
Type_KeyPress = 6, // key pressed
Type_KeyRelease = 7, // key released
Type_FocusIn = 8, // keyboard focus received
Type_FocusOut = 9, // keyboard focus lost
Type_Enter = 10, // mouse enters widget
Type_Leave = 11, // mouse leaves widget
Type_Paint = 12, // paint widget
Type_Move = 13, // move widget
Type_Resize = 14, // resize widget
Type_Create = 15, // after object creation
Type_Destroy = 16, // during object destruction
Type_Show = 17, // widget is shown
Type_Hide = 18, // widget is hidden
Type_Close = 19, // request to close widget
Type_Quit = 20, // request to quit application
Type_Reparent = 21, // widget has been reparented
Type_ShowMinimized = 22, // widget is shown minimized
Type_ShowNormal = 23, // widget is shown normal
Type_WindowActivate = 24, // window was activated
Type_WindowDeactivate = 25, // window was deactivated
Type_ShowToParent = 26, // widget is shown to parent
Type_HideToParent = 27, // widget is hidden to parent
Type_ShowMaximized = 28, // widget is shown maximized
Type_ShowFullScreen = 29, // widget is shown full-screen
Type_Accel = 30, // accelerator event
Type_Wheel = 31, // wheel event
Type_AccelAvailable = 32, // accelerator available event
Type_CaptionChange = 33, // caption changed
Type_IconChange = 34, // icon changed
Type_ParentFontChange = 35, // parent font changed
Type_ApplicationFontChange = 36, // application font changed
Type_ParentPaletteChange = 37, // parent palette changed
Type_ApplicationPaletteChange = 38, // application palette changed
Type_PaletteChange = 39, // widget palette changed
Type_Clipboard = 40, // internal clipboard event
Type_Speech = 42, // reserved for speech input
Type_SockAct = 50, // socket activation
Type_AccelOverride = 51, // accelerator override event
Type_DeferredDelete = 52, // deferred delete event
Type_DragEnter = 60, // drag moves into widget
Type_DragMove = 61, // drag moves in widget
Type_DragLeave = 62, // drag leaves or is cancelled
Type_Drop = 63, // actual drop
Type_DragResponse = 64, // drag accepted/rejected
Type_ChildInserted = 70, // new child widget
Type_ChildRemoved = 71, // deleted child widget
Type_LayoutHint = 72, // child min/max size changed
Type_ShowWindowRequest = 73, // widget's window should be mapped
Type_ActivateControl = 80, // ActiveX activation
Type_DeactivateControl = 81, // ActiveX deactivation
Type_ContextMenu = 82, // context popup menu
Type_IMStart = 83, // input method composition start
Type_IMCompose = 84, // input method composition
Type_IMEnd = 85, // input method composition end
Type_Accessibility = 86, // accessibility information is requested
Type_TabletMove = 87, // Wacom tablet event
Type_LocaleChange = 88, // the system locale changed
Type_LanguageChange = 89, // the application language changed
Type_LayoutDirectionChange = 90, // the layout direction changed
Type_Style = 91, // internal style event
Type_TabletPress = 92, // tablet press
Type_TabletRelease = 93, // tablet release
Type_User = 1000, // first user event id
Type_SpaceNavigatorInput = 1094, // 3D mouse input occured
Type_SpaceNavigatorKeyDown = 1095, // 3D mouse input occured
Type_WiiMoteInput = 1096, // WiiMote input occured
Type_WiiMoteButton= 1097, // WiiMote button pressed
Type_MaxUser = 65535
};
//##ButtonState
// mouse/keyboard state values
//QT combinations if MOUSEBUTTONRelease: left MouseButton + ControlButton: 0x201
enum EButtonStates
{
BS_NoButton = 0x0000,
BS_LeftButton = 0x0001,
BS_RightButton = 0x0002,
BS_MidButton = 0x0004,
BS_MouseButtonMask = 0x0007,
BS_ShiftButton = 0x0100,
BS_ControlButton = 0x0200,
BS_AltButton = 0x0400,
BS_MetaButton = 0x0800,
BS_KeyButtonMask = 0x0f00,
BS_Keypad = 0x4000
};
//##Key
enum EKeys
{
Key_Escape = 0x1000, // misc keys
Key_Tab = 0x1001,
Key_Backtab = 0x1002,
Key_BackTab = 0x1002, //= Key_Backtab
Key_Backspace = 0x1003,
Key_BackSpace = 0x1003, //= Key_Backspace
Key_Return = 0x1004,
Key_Enter = 0x1005,
Key_Insert = 0x1006,
Key_Delete = 0x1007,
Key_Pause = 0x1008,
Key_Print = 0x1009,
Key_SysReq = 0x100a,
Key_Home = 0x1010, // cursor movement
Key_End = 0x1011,
Key_Left = 0x1012,
Key_Up = 0x1013,
Key_Right = 0x1014,
Key_Down = 0x1015,
Key_Prior = 0x1016,
Key_PageUp = 0x1016, //=Key_Prior
Key_Next = 0x1017,
Key_PageDown = 0x1017, //=Key_Next
Key_Shift = 0x1020, // modifiers
Key_Control = 0x1021,
Key_Meta = 0x1022,
Key_Alt = 0x1023,
Key_CapsLock = 0x1024,
Key_NumLock = 0x1025,
Key_ScrollLock = 0x1026,
Key_F1 = 0x1030, // function keys
Key_F2 = 0x1031,
Key_F3 = 0x1032,
Key_F4 = 0x1033,
Key_F5 = 0x1034,
Key_F6 = 0x1035,
Key_F7 = 0x1036,
Key_F8 = 0x1037,
Key_F9 = 0x1038,
Key_F10 = 0x1039,
Key_F11 = 0x103a,
Key_F12 = 0x103b,
Key_F13 = 0x103c,
Key_F14 = 0x103d,
Key_F15 = 0x103e,
Key_F16 = 0x103f,
Key_F17 = 0x1040,
Key_F18 = 0x1041,
Key_F19 = 0x1042,
Key_F20 = 0x1043,
Key_F21 = 0x1044,
Key_F22 = 0x1045,
Key_F23 = 0x1046,
Key_F24 = 0x1047,
Key_F25 = 0x1048, // F25 .. F35 only on X11
Key_F26 = 0x1049,
Key_F27 = 0x104a,
Key_F28 = 0x104b,
Key_F29 = 0x104c,
Key_F30 = 0x104d,
Key_F31 = 0x104e,
Key_F32 = 0x104f,
Key_F33 = 0x1050,
Key_F34 = 0x1051,
Key_F35 = 0x1052,
Key_Super_L = 0x1053, // extra keys
Key_Super_R = 0x1054,
Key_Menu = 0x1055,
Key_Hyper_L = 0x1056,
Key_Hyper_R = 0x1057,
Key_Help = 0x1058,
// International input method support (X keycode - = 0xEE00)
// Only interesting if you are writing your own input method
Key_Muhenkan = 0x1122, // Cancel Conversion
Key_Henkan = 0x1123, // Start/Stop Conversion
Key_Hiragana_Katakana = 0x1127, // Hiragana/Katakana toggle
Key_Zenkaku_Hankaku = 0x112A, // Zenkaku/Hankaku toggle
Key_Space = 0x20, // 7 bit printable ASCII
Key_Any = 0x20, //= Key_Space
Key_Exclam = 0x21,
Key_QuoteDbl = 0x22,
Key_NumberSign = 0x23,
Key_Dollar = 0x24,
Key_Percent = 0x25,
Key_Ampersand = 0x26,
Key_Apostrophe = 0x27,
Key_ParenLeft = 0x28,
Key_ParenRight = 0x29,
Key_Asterisk = 0x2a,
Key_Plus = 0x2b,
Key_Comma = 0x2c,
Key_Minus = 0x2d,
Key_Period = 0x2e,
Key_Slash = 0x2f,
Key_0 = 0x30,
Key_1 = 0x31,
Key_2 = 0x32,
Key_3 = 0x33,
Key_4 = 0x34,
Key_5 = 0x35,
Key_6 = 0x36,
Key_7 = 0x37,
Key_8 = 0x38,
Key_9 = 0x39,
Key_Colon = 0x3a,
Key_Semicolon = 0x3b,
Key_Less = 0x3c,
Key_Equal = 0x3d,
Key_Greater = 0x3e,
Key_Question = 0x3f,
Key_At = 0x40,
Key_A = 0x41,
Key_B = 0x42,
Key_C = 0x43,
Key_D = 0x44,
Key_E = 0x45,
Key_F = 0x46,
Key_G = 0x47,
Key_H = 0x48,
Key_I = 0x49,
Key_J = 0x4a,
Key_K = 0x4b,
Key_L = 0x4c,
Key_M = 0x4d,
Key_N = 0x4e,
Key_O = 0x4f,
Key_P = 0x50,
Key_Q = 0x51,
Key_R = 0x52,
Key_S = 0x53,
Key_T = 0x54,
Key_U = 0x55,
Key_V = 0x56,
Key_W = 0x57,
Key_X = 0x58,
Key_Y = 0x59,
Key_Z = 0x5a,
Key_BracketLeft = 0x5b,
Key_Backslash = 0x5c,
Key_BracketRight = 0x5d,
Key_AsciiCircum = 0x5e,
Key_Underscore = 0x5f,
Key_QuoteLeft = 0x60,
Key_BraceLeft = 0x7b,
Key_Bar = 0x7c,
Key_BraceRight = 0x7d,
Key_AsciiTilde = 0x7e,
Key_nobreakspace = 0x0a0,
Key_exclamdown = 0x0a1,
Key_cent = 0x0a2,
Key_sterling = 0x0a3,
Key_currency = 0x0a4,
Key_yen = 0x0a5,
Key_brokenbar = 0x0a6,
Key_section = 0x0a7,
Key_diaeresis = 0x0a8,
Key_copyright = 0x0a9,
Key_ordfeminine = 0x0aa,
Key_guillemotleft = 0x0ab, // left angle quotation mark
Key_notsign = 0x0ac,
Key_hyphen = 0x0ad,
Key_registered = 0x0ae,
Key_macron = 0x0af,
Key_degree = 0x0b0,
Key_plusminus = 0x0b1,
Key_twosuperior = 0x0b2,
Key_threesuperior = 0x0b3,
Key_acute = 0x0b4,
Key_mu = 0x0b5,
Key_paragraph = 0x0b6,
Key_periodcentered = 0x0b7,
Key_cedilla = 0x0b8,
Key_onesuperior = 0x0b9,
Key_masculine = 0x0ba,
Key_guillemotright = 0x0bb, // right angle quotation mark
Key_onequarter = 0x0bc,
Key_onehalf = 0x0bd,
Key_threequarters = 0x0be,
Key_questiondown = 0x0bf,
Key_Agrave = 0x0c0,
Key_Aacute = 0x0c1,
Key_Acircumflex = 0x0c2,
Key_Atilde = 0x0c3,
Key_Adiaeresis = 0x0c4,
Key_Aring = 0x0c5,
Key_AE = 0x0c6,
Key_Ccedilla = 0x0c7,
Key_Egrave = 0x0c8,
Key_Eacute = 0x0c9,
Key_Ecircumflex = 0x0ca,
Key_Ediaeresis = 0x0cb,
Key_Igrave = 0x0cc,
Key_Iacute = 0x0cd,
Key_Icircumflex = 0x0ce,
Key_Idiaeresis = 0x0cf,
Key_ETH = 0x0d0,
Key_Ntilde = 0x0d1,
Key_Ograve = 0x0d2,
Key_Oacute = 0x0d3,
Key_Ocircumflex = 0x0d4,
Key_Otilde = 0x0d5,
Key_Odiaeresis = 0x0d6,
Key_multiply = 0x0d7,
Key_Ooblique = 0x0d8,
Key_Ugrave = 0x0d9,
Key_Uacute = 0x0da,
Key_Ucircumflex = 0x0db,
Key_Udiaeresis = 0x0dc,
Key_Yacute = 0x0dd,
Key_THORN = 0x0de,
Key_ssharp = 0x0df,
Key_agrave = 0x0e0,
Key_aacute = 0x0e1,
Key_acircumflex = 0x0e2,
Key_atilde = 0x0e3,
Key_adiaeresis = 0x0e4,
Key_aring = 0x0e5,
Key_ae = 0x0e6,
Key_ccedilla = 0x0e7,
Key_egrave = 0x0e8,
Key_eacute = 0x0e9,
Key_ecircumflex = 0x0ea,
Key_ediaeresis = 0x0eb,
Key_igrave = 0x0ec,
Key_iacute = 0x0ed,
Key_icircumflex = 0x0ee,
Key_idiaeresis = 0x0ef,
Key_eth = 0x0f0,
Key_ntilde = 0x0f1,
Key_ograve = 0x0f2,
Key_oacute = 0x0f3,
Key_ocircumflex = 0x0f4,
Key_otilde = 0x0f5,
Key_odiaeresis = 0x0f6,
Key_division = 0x0f7,
Key_oslash = 0x0f8,
Key_ugrave = 0x0f9,
Key_uacute = 0x0fa,
Key_ucircumflex = 0x0fb,
Key_udiaeresis = 0x0fc,
Key_yacute = 0x0fd,
Key_thorn = 0x0fe,
Key_ydiaeresis = 0x0ff,
Key_unknown = 0xffff,
Key_none = 0xffff//= Key_unknown
};
}//namespace mitk
#endif //ifndef MITKINTERACTCONST_H
diff --git a/Core/Code/Interactions/mitkInteractor.cpp b/Core/Code/Interactions/mitkInteractor.cpp
index 2d9217fa7e..80a3f9b06e 100755
--- a/Core/Code/Interactions/mitkInteractor.cpp
+++ b/Core/Code/Interactions/mitkInteractor.cpp
@@ -1,295 +1,294 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkInteractor.h"
#include <mitkDataNode.h>
#include <mitkDisplayPositionEvent.h>
#include <mitkPositionEvent.h>
#include <mitkGeometry3D.h>
#include <mitkAction.h>
#include <mitkOperationEvent.h>
#include <mitkStateEvent.h>
#include <mitkState.h>
#include <mitkUndoController.h>
//#include <mitkStatusBar.h>
#include <vtkCamera.h>
#include <vtkRenderer.h>
#include "mitkInteractionConst.h"
#include <vtkLinearTransform.h>
#include <itkVector.h>
#include <mitkModeOperation.h>
#include "mitkGlobalInteraction.h"
const std::string mitk::Interactor::XML_NODE_NAME = "interactor";
mitk::Interactor::Interactor(const char * type, DataNode* dataNode)
: StateMachine(type),
m_DataNode(dataNode),
m_Mode(SMDESELECTED)
{
if (m_DataNode != NULL)
m_DataNode->SetInteractor(this);
// handle these actions in those Methods
CONNECT_ACTION( AcMODEDESELECT, OnModeDeselect );
CONNECT_ACTION( AcMODESELECT, OnModeSelect );
CONNECT_ACTION( AcMODESUBSELECT, OnModeSubSelect );
}
mitk::BaseData* mitk::Interactor::GetData() const
{
if (m_DataNode != NULL)
return m_DataNode->GetData();
else
return NULL;
}
mitk::Interactor::SMMode mitk::Interactor::GetMode() const
{
return m_Mode;
}
bool mitk::Interactor::IsNotSelected() const
{
return (m_Mode==SMDESELECTED);
}
bool mitk::Interactor::IsSelected() const
{
return (m_Mode!=SMDESELECTED);
}
void mitk::Interactor::CreateModeOperation(ModeType mode)
{
ModeOperation* doOp = new ModeOperation(OpMODECHANGE, mode);
if (m_UndoEnabled)
{
ModeOperation* undoOp = new ModeOperation(OpMODECHANGE, this->GetMode());
OperationEvent *operationEvent = new OperationEvent(this, doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
this->ExecuteOperation(doOp);
}
bool mitk::Interactor::OnModeDeselect(Action* /*action*/, StateEvent const*)
{
GlobalInteraction* global = GlobalInteraction::GetInstance();
if (global == NULL)
itkWarningMacro("Message from Interactor.cpp: GlobalInteraction == NULL! Check use of Interactor!");
if( this->GetMode() != SMDESELECTED)
{
this->CreateModeOperation(SMDESELECTED);
global->RemoveFromSelectedInteractors(this);
}
return true;
}
bool mitk::Interactor::OnModeSelect(Action* /*action*/, StateEvent const*)
{
GlobalInteraction* global = GlobalInteraction::GetInstance();
if (global == NULL)
itkWarningMacro("Message from Interactor.cpp: GlobalInteraction == NULL! Check use of Interactor!");
if( this->GetMode() != SMSELECTED)
{
this->CreateModeOperation(SMSELECTED);
global->AddToSelectedInteractors(this);
}
return true;
}
bool mitk::Interactor::OnModeSubSelect(Action* /*action*/, StateEvent const*)
{
//StatusBar::GetInstance()->DisplayText("Error! in XML-Interaction: an simple Interactor can not set in sub selected", 1102);
return false;
}
float mitk::Interactor::CanHandleEvent(StateEvent const* stateEvent) const
{
//return value for boundingbox
float returnvalueBB = 0.0,
//return value for a existing transition
returnvalueTransition = 0.0,
//return value for an existing key transition
returnvalueKey = 0.0;
//if it is a key event that can be handled in the current state
DisplayPositionEvent const *disPosEvent = dynamic_cast <const DisplayPositionEvent *> (stateEvent->GetEvent());
//Key event handling:
if (disPosEvent == NULL)
{
//check, if the current state has a transition waiting for that key event.
if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
{
returnvalueKey = 0.5;
}
}
//Mouse event handling:
//on MouseMove do nothing! reimplement if needed differently
if (stateEvent->GetEvent()->GetType() == Type_MouseMove)
{
return 0;
}
//if the event can be understood and if there is a transition waiting for that event
if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
{
returnvalueTransition = 0.5;//it can be understood
}
//compute the center of the data taken care of if != NULL
if (GetData() != NULL)
{
const BoundingBox *bBox = GetData()->GetUpdatedTimeSlicedGeometry()->GetBoundingBox();
if (bBox == NULL)
return 0;
DisplayPositionEvent const *event = dynamic_cast <const DisplayPositionEvent *> (stateEvent->GetEvent());
if (event != NULL)
{
//transforming the world position to local coordinate system
Point3D point;
GetData()->GetTimeSlicedGeometry()->WorldToIndex(event->GetWorldPosition(), point);
//distance between center and point
BoundingBox::PointType center = bBox->GetCenter();
returnvalueBB = point.EuclideanDistanceTo(center);
// now check if object bounding box has a non-zero size
float bBoxSize = bBox->GetMaximum().EuclideanDistanceTo(bBox->GetMinimum() );
if( bBoxSize < 0.00001 ) return 0; // bounding box too small?
//now compared to size of bounding box to get value between 0 and 1;
returnvalueBB = returnvalueBB/bBoxSize;
//safety: if by now return value is not in [0,1], then return 0!
if (returnvalueBB>1 || returnvalueBB<0)
returnvalueBB = 0;
// A return value of 1 is good, 0 is bad -> reverse value
returnvalueBB = 1 - returnvalueBB;
//check if the given position lies inside the data object
if (bBox->IsInside(point))
{
//mapped between 0.5 and 1
returnvalueBB = 0.5 + (returnvalueBB/ 2);
}
else
{
//set it in range between 0 and 0.5
returnvalueBB = returnvalueBB / 2;
}
}
}
//else
// itkWarningMacro("Data of Interactor is NULL! Please check setup of Interactors!");
return std::max(returnvalueBB, std::max(returnvalueKey, returnvalueTransition));
}
void mitk::Interactor::ExecuteOperation(Operation* operation)
{
switch (operation->GetOperationType())
{
case OpMODECHANGE:
{
ModeOperation *modeOp = dynamic_cast<ModeOperation*>(operation);
if (modeOp)
{
m_Mode = modeOp->GetMode();
}
}
break;
default:
Superclass::ExecuteOperation(operation);
}
}
const std::string& mitk::Interactor::GetXMLNodeName() const
{
return XML_NODE_NAME;
}
void mitk::Interactor::SetDataNode( DataNode* dataNode )
{
m_DataNode = dataNode;
//check for the number of time steps and initialize the vector of CurrentStatePointer accordingly
if (m_DataNode != NULL)
{
mitk::BaseData* data = dataNode->GetData();
if (data != NULL)
{
unsigned int timeSteps = data->GetTimeSteps();
//expand the list of StartStates according to the number of timesteps in data
if (timeSteps > 1)
this->InitializeStartStates(timeSteps);
}
}
}
void mitk::Interactor::UpdateTimeStep(unsigned int timeStep)
{
//check if the vector of StartStates contains enough pointers to use timeStep
if (timeStep >= 1)
{
// Make sure that the data (if time-resolved) has enough entries;
// if not, create the required extra ones (empty)
if (m_DataNode!= NULL)
if (m_DataNode->GetData()!= NULL)
m_DataNode->GetData()->Expand(timeStep+1); //+1 becuase the vector starts with 0 and the timesteps with 1
//now check for this object
this->ExpandStartStateVector(timeStep+1); //nothing is changed if the number of timesteps in data equals the number of startstates held in statemachine
}
//set the time to the given time
Superclass::UpdateTimeStep(timeStep);
//time has to be up-to-date
//check and throw an exception if not so
if (timeStep != m_TimeStep)
itkExceptionMacro(<<"Time is invalid. Take care of synchonization!");
}
bool mitk::Interactor::HandleEvent(StateEvent const* stateEvent)
{
//update the Time and then call Superclass
if (stateEvent != NULL)
{
mitk::Event const* event = stateEvent->GetEvent();
if (event != NULL)
{
mitk::BaseRenderer* sender = event->GetSender();
if (sender != NULL)
{
//Get the TimeStep according to CurrentWorldGeometry2D
unsigned int currentTimeStep = sender->GetTimeStep();
if (currentTimeStep != m_TimeStep)
this->UpdateTimeStep(currentTimeStep);
}
}
}
return Superclass::HandleEvent(stateEvent);
}
diff --git a/Core/Code/Interactions/mitkInteractor.h b/Core/Code/Interactions/mitkInteractor.h
index ece08ffb6a..54f43c444a 100755
--- a/Core/Code/Interactions/mitkInteractor.h
+++ b/Core/Code/Interactions/mitkInteractor.h
@@ -1,171 +1,170 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 INTERACTOR_H_HEADER_INCLUDED
#define INTERACTOR_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkStateMachine.h"
#include "mitkGeometry3D.h"
#include <string>
namespace mitk {
class DataNode;
class BaseData;
//##Documentation
//## @brief Interface for an Interactor.
//##
//## The Interactor is held with a SmartPointer by a DataNode
//## and holds its Node with a Pointer. That way Smartpointer doesn't build a circle.
//## Different Modes: In order to not send Events to all StateMachines, a StateMachine can be
//## in three different modes:
//## DESELECTED: this statemachine doesn't wait for an event
//## SELECTED: this statemachine just has handled an event and waits for the next one
//## SUBSELECTED: depricate; was used for hierarchical statemachines before.
//## Guidelines for the modevalues: Selected if the coresponding data is selected, deselected if deselect of data.
//##
//## In moving the machine is selected. After a new insert the machine is selected, since the data is also selected
//## In method ExecuteAction(..) the different actions are divided up through switch/case statements. Each block has to check
//## the appropriate type of event to process the actions. Especially in guarding states (a state, that checks certain conditions (e.g. is picked)
//## the according Event must be called to continue in states. No return false here!
//## @ingroup Interaction
class MITK_CORE_EXPORT Interactor : public StateMachine
{
public:
mitkClassMacro(Interactor, StateMachine);
/**
* @brief NewMacro with two parameters for calling itk::Lightobject::New(..) method
**/
mitkNewMacro2Param(Self, const char*, DataNode*);
//##Documentation
//##@brief Enumeration of the different modes an Interactor can be into.
//## See class documentation for further details
enum SMMode
{
SMDESELECTED = 0,
SMSELECTED,
SMSUBSELECTED
};
typedef SMMode ModeType;
//##Documentation
//## @brief Get the Mode of the Interactor. Use enum SMMode for return parameter
SMMode GetMode() const;
//##Documentation
//## @brief Check the interaction mode
bool IsNotSelected() const;
//##Documentation
//## @brief Check the interaction mode
bool IsSelected() const;
//##Documentation
//## @brief calculates how good the data, this statemachine handles, is hit by the event.
//##
//## Returns a value between 0 and 1
//## where 0 represents not responsible and 1 represents definitive responsible!
//## Standard function to override if needed.
//## (Used by GlobalInteraction to decide which DESELECTED statemachine to send the event to.)
virtual float CanHandleEvent(StateEvent const* stateEvent) const;
/**
* @brief Updates the current TimeStep according to the associated data and calls Superclass::HandleEvent()
**/
bool HandleEvent(StateEvent const* stateEvent);
/**
* @brief Method to call if the associated data has changed by the user (loading of data)
* This method is called by DataNode::SetData() to tell the interactor to reinitialize.
* This method should be overwritten by specialized interactors.
* (e.g. PointSetInteractor: go to the right state according to number of loaded points)
* Note: It will not be called when the data gets modified (e.g. adding / removing points to a PointSet)
**/
virtual void DataChanged(){};
//##Documentation
//## @brief adds handling of operations used for mode change. Unrecognized Operations are send to Superclass.
//## *ATTENTION*: THIS METHOD SHOULD NOT BE CALLED FROM OTHER CLASSES DIRECTLY!
virtual void ExecuteOperation(Operation* operation);
static const std::string XML_NODE_NAME;
protected:
/**
* @brief Constructor
* @param dataNode is the node, this Interactor is connected to
* @param type is the type of StateMachine like declared in the XML-Configure-File
*
* Interactor connects itself to the DataNode-Interactor-pointer through call of SetInteractor(this)
**/
Interactor(const char * type, DataNode* dataNode);
/**
* @brief Destructor
**/
~Interactor(){}
bool OnModeSelect(Action* action, StateEvent const*);
bool OnModeDeselect(Action* action, StateEvent const*);
bool OnModeSubSelect(Action* action, StateEvent const*);
//##Documentation
virtual const std::string& GetXMLNodeName() const;
//##Documentation
//## @brief creates a ModeOperation with the transmitted mode and sends it to this. Undo supported!
void CreateModeOperation(ModeType mode);
//##Documentation
//## @brief convenience method for accessing the data contained in the
//## node to which this interactor is associated to
BaseData* GetData() const;
//##Documentation
//## @brief Used by friend class DataNode
virtual void SetDataNode( DataNode* dataNode );
/**
* @brief Derived from superclass to also check if enough timesteps are instantiated in m_CurrentStateVector
* The number of timesteps is read from the dedicated data.
* @param[in] timeStep The timeStep that the statemachine has to be set to
**/
virtual void UpdateTimeStep(unsigned int timeStep);
//##Documentation
//## @brief Pointer to the data, this object handles the Interaction for
DataNode* m_DataNode;
//##Documentation
//## @brief Mode of Selection
ModeType m_Mode;
friend class DataNode;
};
}//namespace mitk
#endif /* INTERACTOR_H_HEADER_INCLUDED */
diff --git a/Core/Code/Interactions/mitkKeyEvent.cpp b/Core/Code/Interactions/mitkKeyEvent.cpp
index 80af85fb2c..32cc8e4246 100644
--- a/Core/Code/Interactions/mitkKeyEvent.cpp
+++ b/Core/Code/Interactions/mitkKeyEvent.cpp
@@ -1,39 +1,38 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 21:01:03 +0200 (Di, 12 Mai 2009) $
-Version: $Revision: 17190 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkKeyEvent.h"
#include "mitkBaseRenderer.h"
mitk::KeyEvent::KeyEvent(mitk::BaseRenderer* sender, int type, int button, int buttonState, int key, std::string text, const mitk::Point2D& displPosition)
: Event(sender, type, button, buttonState, key)
, m_DisplayPosition(displPosition)
, m_Key(key)
, m_Text(text)
, m_WorldPositionIsSet(false)
{
}
const mitk::Point3D& mitk::KeyEvent::GetWorldPosition() const
{
if(m_WorldPositionIsSet)
return m_WorldPosition;
m_WorldPositionIsSet = true;
assert(m_Sender!=NULL);
m_Sender->PickWorldPoint(m_DisplayPosition, m_WorldPosition);
return m_WorldPosition;
}
diff --git a/Core/Code/Interactions/mitkKeyEvent.h b/Core/Code/Interactions/mitkKeyEvent.h
index 8107d0c8b2..941366813c 100644
--- a/Core/Code/Interactions/mitkKeyEvent.h
+++ b/Core/Code/Interactions/mitkKeyEvent.h
@@ -1,79 +1,78 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 21:01:03 +0200 (Di, 12 Mai 2009) $
-Version: $Revision: 17190 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 KeyEvent_H_HEADER_INCLUDED_C184F366
#define KeyEvent_H_HEADER_INCLUDED_C184F366
#include <MitkExports.h>
#include "mitkEvent.h"
#include "mitkVector.h"
namespace mitk {
//##Documentation
//## @brief Event that stores coordinates and the key which is pressed
//##
//## Stores display position of the mouse. If requested, the correspondent
//## 3D world position in mm is calculated via picking (delegated to the
//## BaseRenderer).
//## @ingroup Interaction
class MITK_CORE_EXPORT KeyEvent : public Event
{
public:
//##Documentation
//## @brief Constructor with all necessary arguments.
//##
//## @param sender is the renderer that caused that event
//## @param type, button, buttonState, key: information from the Event
//## @param displPosition is the 2D Position of the mouse
KeyEvent(BaseRenderer* sender, int type, int button, int buttonState, int key, std::string text, const Point2D& displPosition);
const Point2D& GetDisplayPosition() const
{
return m_DisplayPosition;
}
void SetDisplayPosition(const Point2D& displPosition) { m_DisplayPosition = displPosition; }
const Point3D& GetWorldPosition() const;
int GetKey() const
{
return m_Key;
}
const char* GetText() const {
return m_Text.c_str();
}
int GetType() const {
return m_Type;
}
protected:
Point2D m_DisplayPosition;
int m_Key;
std::string m_Text;
mutable Point3D m_WorldPosition;
mutable bool m_WorldPositionIsSet;
};
} // namespace mitk
#endif /* DISPLAYPOSITIONozsiEVENT_H_HEADER_INCLUDED_C184F366 */
diff --git a/Core/Code/Interactions/mitkMessage.h b/Core/Code/Interactions/mitkMessage.h
index 2fa399ffae..279519616f 100644
--- a/Core/Code/Interactions/mitkMessage.h
+++ b/Core/Code/Interactions/mitkMessage.h
@@ -1,802 +1,801 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 14123 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 mitkMessageHIncluded
#define mitkMessageHIncluded
#include <vector>
#include <functional>
#include <itkSimpleFastMutexLock.h>
/**
* Adds a Message<> variable and methods to add/remove message delegates to/from
* this variable.
*/
#define mitkNewMessageMacro(msgHandleObject) \
private: ::mitk::Message<> m_##msgHandleObject##Message; \
public: \
inline void Add##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate<>& delegate) \
{ m_##msgHandleObject##Message += delegate; } \
inline void Remove##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate<>& delegate) \
{ m_##msgHandleObject##Message -= delegate; } \
#define mitkNewMessageWithReturnMacro(msgHandleObject, returnType) \
private: ::mitk::Message<returnType> m_##msgHandleObject##Message; \
public: \
inline void Add##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate<returnType>& delegate) \
{ m_##msgHandleObject##Message += delegate; } \
inline void Remove##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate<returnType>& delegate) \
{ m_##msgHandleObject##Message -= delegate; } \
#define mitkNewMessage1Macro(msgHandleObject, type1) \
private: ::mitk::Message1< type1 > m_##msgHandleObject##Message; \
public: \
void Add##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate1< type1 >& delegate) \
{ m_##msgHandleObject##Message += delegate; } \
void Remove##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate1< type1 >& delegate) \
{ m_##msgHandleObject##Message -= delegate; }
#define mitkNewMessage2Macro(msgHandleObject, type1, type2) \
private: ::mitk::Message2< type1, type2 > m_##msgHandleObject##Message; \
public: \
void Add##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate2< type1, type2 >& delegate) \
{ m_##msgHandleObject##Message += delegate; } \
void Remove##msgHandleObject##Listener(const ::mitk::MessageAbstractDelegate2< type1, type2 >& delegate) \
{ m_##msgHandleObject##Message -= delegate; }
namespace mitk {
template<typename A = void>
class MessageAbstractDelegate
{
public:
virtual ~MessageAbstractDelegate()
{
}
virtual A Execute() const = 0;
virtual bool operator==(const MessageAbstractDelegate* cmd) const = 0;
virtual MessageAbstractDelegate* Clone() const = 0;
};
template <typename T, typename A = void>
class MessageAbstractDelegate1
{
public:
virtual ~MessageAbstractDelegate1()
{
}
virtual A Execute(T t) const = 0;
virtual bool operator==(const MessageAbstractDelegate1* cmd) const = 0;
virtual MessageAbstractDelegate1* Clone() const = 0;
};
template <typename T, typename U, typename A = void>
class MessageAbstractDelegate2
{
public:
virtual ~MessageAbstractDelegate2()
{
}
virtual A Execute(T t, U u) const = 0;
virtual bool operator==(const MessageAbstractDelegate2* cmd) const = 0;
virtual MessageAbstractDelegate2* Clone() const = 0;
};
template <typename T, typename U, typename V, typename A = void>
class MessageAbstractDelegate3
{
public:
virtual ~MessageAbstractDelegate3()
{
}
virtual A Execute(T t, U u, V v) const = 0;
virtual bool operator==(const MessageAbstractDelegate3* cmd) const = 0;
virtual MessageAbstractDelegate3* Clone() const = 0;
};
template <typename T, typename U, typename V, typename W, typename A = void>
class MessageAbstractDelegate4
{
public:
virtual ~MessageAbstractDelegate4()
{
}
virtual A Execute(T t, U u, V v, W w) const = 0;
virtual bool operator==(const MessageAbstractDelegate4* cmd) const = 0;
virtual MessageAbstractDelegate4* Clone() const = 0;
};
/**
* This class essentially wraps a function pointer with signature
* A(R::*function)(). A is the return type of your callback function
* and R the type of the class implementing the function.
*
* Use this class to add a callback function to
* messages without parameters.
*/
template <class R, typename A = void>
class MessageDelegate : public MessageAbstractDelegate<A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate(R* object, A(R::*memberFunctionPointer)())
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate()
{
}
// override function "Call"
virtual A Execute() const
{
return (m_Object->*m_MemberFunctionPointer)(); // execute member function
}
bool operator==(const MessageAbstractDelegate<A>* c) const
{
const MessageDelegate<R,A>* cmd = dynamic_cast<const MessageDelegate<R,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate<A>* Clone() const
{
return new MessageDelegate(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(); // pointer to member function
};
/**
* This class essentially wraps a function pointer with signature
* A(R::*function)(T). A is the return type of your callback function,
* R the type of the class implementing the function and T the type
* of the argument.
*
* Use this class to add a callback function to
* messages with one parameter.
*
* If you need more parameters, use MessageDelegate2 etc.
*/
template <class R, typename T, typename A = void>
class MessageDelegate1 : public MessageAbstractDelegate1<T,A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate1(R* object, A(R::*memberFunctionPointer)(T))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate1()
{
}
// override function "Call"
virtual A Execute(T t) const
{
return (m_Object->*m_MemberFunctionPointer)(t); // execute member function
}
bool operator==(const MessageAbstractDelegate1<T,A>* c) const
{
const MessageDelegate1<R,T,A>* cmd = dynamic_cast<const MessageDelegate1<R,T,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate1<T,A>* Clone() const
{
return new MessageDelegate1(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(T); // pointer to member function
};
template <class R, typename T, typename U, typename A = void>
class MessageDelegate2 : public MessageAbstractDelegate2<T,U,A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate2(R* object, A(R::*memberFunctionPointer)(T, U))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate2()
{
}
// override function "Call"
virtual A Execute(T t, U u) const
{
return (m_Object->*m_MemberFunctionPointer)(t,u); // execute member function
}
bool operator==(const MessageAbstractDelegate2<T,U,A>* c) const
{
const MessageDelegate2<R,T,U,A>* cmd = dynamic_cast<const MessageDelegate2<R,T,U,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate2<T,U,A>* Clone() const
{
return new MessageDelegate2(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(T, U); // pointer to member function
};
template <class R, typename T, typename U, typename V, typename A = void>
class MessageDelegate3 : public MessageAbstractDelegate3<T,U,V,A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate3(R* object, A(R::*memberFunctionPointer)(T, U, V))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate3()
{
}
// override function "Call"
virtual A Execute(T t, U u, V v) const
{
return (m_Object->*m_MemberFunctionPointer)(t,u,v); // execute member function
}
bool operator==(const MessageAbstractDelegate3<T,U,V,A>* c) const
{
const MessageDelegate3<R,T,U,V,A>* cmd = dynamic_cast<const MessageDelegate3<R,T,U,V,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate3<T,U,V,A>* Clone() const
{
return new MessageDelegate3(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(T, U, V); // pointer to member function
};
template <class R, typename T, typename U, typename V, typename W, typename A = void>
class MessageDelegate4 : public MessageAbstractDelegate4<T,U,V,W,A>
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
MessageDelegate4(R* object, A(R::*memberFunctionPointer)(T, U, V, W))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~MessageDelegate4()
{
}
// override function "Call"
virtual A Execute(T t, U u, V v, W w) const
{
return (m_Object->*m_MemberFunctionPointer)(t,u,v,w); // execute member function
}
bool operator==(const MessageAbstractDelegate4<T,U,V,W,A>* c) const
{
const MessageDelegate4<R,T,U,V,W,A>* cmd = dynamic_cast<const MessageDelegate4<R,T,U,V,W,A>* >(c);
if (!cmd) return false;
if ((void*)this->m_Object != (void*)cmd->m_Object) return false;
if (this->m_MemberFunctionPointer != cmd->m_MemberFunctionPointer) return false;
return true;
}
MessageAbstractDelegate4<T,U,V,W,A>* Clone() const
{
return new MessageDelegate4(m_Object, m_MemberFunctionPointer);
}
private:
R* m_Object; // pointer to object
A (R::*m_MemberFunctionPointer)(T, U, V, W); // pointer to member function
};
template<typename AbstractDelegate>
class MessageBase
{
public:
typedef std::vector<AbstractDelegate* > ListenerList;
virtual ~MessageBase() {
for (typename ListenerList::iterator iter = m_Listeners.begin();
iter != m_Listeners.end(); ++iter )
{
delete *iter;
}
}
MessageBase() {}
MessageBase(const MessageBase& o)
{
for (typename ListenerList::iterator iter = o.m_Listeners.begin();
iter != o.m_Listeners.end(); ++iter )
{
m_Listeners.push_back((*iter)->Clone());
}
}
MessageBase& operator=(const MessageBase& o)
{
MessageBase tmp(o);
std::swap(tmp.m_Listeners, this->m_Listeners);
}
void AddListener( const AbstractDelegate& delegate ) const
{
AbstractDelegate* msgCmd = delegate.Clone();
m_Mutex.Lock();
for (typename ListenerList::iterator iter = m_Listeners.begin();
iter != m_Listeners.end();
++iter )
{
if ((*iter)->operator==(msgCmd)) {
delete msgCmd;
m_Mutex.Unlock();
return;
}
}
m_Listeners.push_back(msgCmd);
m_Mutex.Unlock();
}
void operator += ( const AbstractDelegate& delegate ) const
{
this->AddListener(delegate);
}
void RemoveListener( const AbstractDelegate& delegate ) const
{
m_Mutex.Lock();
for (typename ListenerList::iterator iter = m_Listeners.begin();
iter != m_Listeners.end();
++iter )
{
if ((*iter)->operator==(&delegate))
{
delete *iter;
m_Listeners.erase( iter );
m_Mutex.Unlock();
return;
}
}
m_Mutex.Unlock();
}
void operator -= ( const AbstractDelegate& delegate) const
{
this->RemoveListener(delegate);
}
const ListenerList& GetListeners() const
{
return m_Listeners;
}
bool HasListeners() const
{
return !m_Listeners.empty();
}
bool IsEmpty() const
{
return m_Listeners.empty();
}
protected:
/**
* \brief List of listeners.
*
* This is declared mutable for a reason: Imagine an object that sends out notifications, e.g.
*
* \code
class Database {
public:
Message Modified;
};
* \endcode
*
* Now imaginge someone gets a <tt>const Database</tt> object, because he/she should not write to the
* database. He/she should anyway be able to register for notifications about changes in the database
* -- this is why AddListener and RemoveListener are declared <tt>const</tt>. m_Listeners must be
* mutable so that AddListener and RemoveListener can modify it regardless of the object's constness.
*/
mutable ListenerList m_Listeners;
mutable itk::SimpleFastMutexLock m_Mutex;
};
/**
* \brief Event/message/notification class.
*
* \sa mitk::BinaryThresholdTool
* \sa QmitkBinaryThresholdToolGUI
*
* This totally ITK, Qt, VTK, whatever toolkit independent class
* allows one class to send out messages and another class to
* receive these message. This class is templated over the
* return type (A) of the callback functions.
* There are variations of this class
* (Message1, Message2, etc.) for sending
* one, two or more parameters along with the messages.
*
* This is an implementation of the Observer pattern.
*
* \li There is no guarantee about the order of which observer is notified first. At the moment the observers which register first will be notified first.
* \li Notifications are <b>synchronous</b>, by direct method calls. There is no support for asynchronous messages.
*
* To conveniently add methods for registering/unregistering observers
* to Message variables of your class, you can use the mitkNewMessageMacro
* macros.
*
* Here is an example how to use the macros and templates:
*
* \code
*
* // An object to be send around
* class Law
* {
* private:
* std::string m_Description;
*
* public:
*
* Law(const std::string law) : m_Description(law)
* { }
*
* std::string GetDescription() const
* {
* return m_Description;
* }
* };
*
* // The NewtonMachine will issue specific events
* class NewtonMachine
* {
* mitkNewMessageMacro(AnalysisStarted);
* mitkNewMessage1Macro(AnalysisStopped, bool);
* mitkNewMessage1Macro(LawDiscovered, const Law&);
*
* public:
*
* void StartAnalysis()
* {
* // send the "started" signal
* m_AnalysisStartedMessage();
*
* // we found a new law of nature by creating one :-)
* Law massLaw("F=ma");
* m_LawDiscoveredMessage(massLaw);
* }
*
* void StopAnalysis()
* {
* // send the "stop" message with false, indicating
* // that no error occured
* m_AnalysisStoppedMessage(false);
* }
* };
*
* class Observer
* {
* private:
*
* NewtonMachine* m_Machine;
*
* public:
*
* Observer(NewtonMachine* machine) : m_Machine(machine)
* {
* // Add "observers", i.e. function pointers to the machine
* m_Machine->AddAnalysisStartedListener(
* ::mitk::MessageDelegate<Observer>(this, &Observer::MachineStarted));
* m_Machine->AddAnalysisStoppedListener(
* ::mitk::MessageDelegate1<Observer, bool>(this, &Observer::MachineStopped));
* m_Machine->AddLawDiscoveredListener(
* ::mitk::MessageDelegate1<Observer, const Law&>(this, &Observer::LawDiscovered));
* }
*
* ~Observer()
* {
* // Always remove your observers when finished
* m_Machine->RemoveAnalysisStartedListener(
* ::mitk::MessagDelegate<Observer>(this, &Observer::MachineStarted));
* m_Machine->RemoveAnalysisStoppedListener(
* ::mitk::MessageDelegate1<Observer, bool>(this, &Observer::MachineStopped));
* m_Machine->RemoveLawDiscoveredListener(
* ::mitk::MessageDelegate1<Observer, const Law&>(this, &Observer::LawDiscovered));
* }
*
* void MachineStarted()
* {
* std::cout << "Observed machine has started" << std::endl;
* }
*
* void MachineStopped(bool error)
* {
* std::cout << "Observed machine stopped " << (error ? "with an error" : "") << std::endl;
* }
*
* void LawDiscovered(const Law& law)
* {
* std::cout << "New law of nature discovered: " << law.GetDescription() << std::endl;
* }
* };
*
* NewtonMachine newtonMachine;
* Observer observer(&newtonMachine);
*
* // This will send two events to registered observers
* newtonMachine.StartAnalysis();
* // This will send one event to registered observers
* newtonMachine.StopAnalysis();
*
* \endcode
*
* Another example of how to use these message classes can be
* found in the directory Testing, file mitkMessageTest.cpp
*
*/
template<typename A = void>
class Message : public MessageBase< MessageAbstractDelegate<A> >
{
public:
typedef MessageBase< MessageAbstractDelegate<A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send()
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for (typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute();
}
}
void operator()()
{
this->Send();
}
};
// message with 1 parameter and return type
template <typename T, typename A = void>
class Message1 : public MessageBase< MessageAbstractDelegate1<T,A> >
{
public:
typedef MessageBase< MessageAbstractDelegate1<T,A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send(T t)
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for ( typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute(t);
}
}
void operator()(T t)
{
this->Send(t);
}
};
// message with 2 parameters and return type
template <typename T, typename U, typename A = void>
class Message2 : public MessageBase< MessageAbstractDelegate2<T,U,A> >
{
public:
typedef MessageBase< MessageAbstractDelegate2<T,U,A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send(T t, U u)
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for ( typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute(t,u);
}
}
void operator()(T t, U u)
{
this->Send(t, u);
}
};
// message with 3 parameters and return type
template <typename T, typename U, typename V, typename A = void>
class Message3 : public MessageBase< MessageAbstractDelegate3<T,U,V,A> >
{
public:
typedef MessageBase< MessageAbstractDelegate3<T,U,V,A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send(T t, U u, V v)
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for ( typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute(t,u,v);
}
}
void operator()(T t, U u, V v)
{
this->Send(t, u, v);
}
};
// message with 4 parameters and return type
template <typename T, typename U, typename V, typename W, typename A = void>
class Message4 : public MessageBase< MessageAbstractDelegate4<T,U,V,W> >
{
public:
typedef MessageBase< MessageAbstractDelegate4<T,U,V,W,A> > Super;
typedef typename Super::ListenerList ListenerList;
void Send(T t, U u, V v, W w)
{
ListenerList listeners;
{
this->m_Mutex.Lock();
listeners.assign(this->m_Listeners.begin(), this->m_Listeners.end());
this->m_Mutex.Unlock();
}
for ( typename ListenerList::iterator iter = listeners.begin();
iter != listeners.end();
++iter )
{
// notify each listener
(*iter)->Execute(t,u,v,w);
}
}
void operator()(T t, U u, V v, W w)
{
this->Send(t, u, v, w);
}
};
} // namespace
#endif
diff --git a/Core/Code/Interactions/mitkMouseModeSwitcher.cpp b/Core/Code/Interactions/mitkMouseModeSwitcher.cpp
index 2a2638d5be..8f989c952c 100644
--- a/Core/Code/Interactions/mitkMouseModeSwitcher.cpp
+++ b/Core/Code/Interactions/mitkMouseModeSwitcher.cpp
@@ -1,192 +1,191 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-01-14 14:20:26 +0100 (Thu, 14 Jan 2010) $
-Version: $Revision: 21047 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkMouseModeSwitcher.h"
#include "mitkDisplayInteractor.h"
#include "mitkDisplayVectorInteractor.h"
#include "mitkDisplayVectorInteractorLevelWindow.h"
#include "mitkDisplayVectorInteractorScroll.h"
mitk::MouseModeSwitcher::MouseModeSwitcher( mitk::GlobalInteraction* gi )
: m_GlobalInteraction( gi )
, m_ActiveInteractionScheme( MITK )
, m_ActiveMouseMode( MousePointer )
, m_LeftMouseButtonHandler( NULL )
{
assert(gi);
this->InitializeListeners();
this->SetInteractionScheme( m_ActiveInteractionScheme );
}
mitk::MouseModeSwitcher::~MouseModeSwitcher()
{
}
void mitk::MouseModeSwitcher::InitializeListeners()
{
mitk::DisplayVectorInteractor::Pointer moveAndZoomInteractor = mitk::DisplayVectorInteractor::New(
"moveNzoom", new mitk::DisplayInteractor() );
mitk::StateMachine::Pointer listener = moveAndZoomInteractor.GetPointer();
m_ListenersForMITK.push_back( listener );
mitk::DisplayVectorInteractorScroll::Pointer scrollInteractor = mitk::DisplayVectorInteractorScroll::New(
"MiddleClickScroll", new mitk::DisplayInteractor() );
listener = scrollInteractor;
m_ListenersForPACS.push_back( listener );
mitk::DisplayVectorInteractorLevelWindow::Pointer lwInteractor = mitk::DisplayVectorInteractorLevelWindow::New("RightClickLevelWindow");
listener = lwInteractor;
m_ListenersForPACS.push_back( listener );
mitk::DisplayVectorInteractor::Pointer panInteractor = mitk::DisplayVectorInteractor::New(
"ShiftClickPan", new mitk::DisplayInteractor() );
listener = panInteractor;
m_ListenersForPACS.push_back( listener );
mitk::DisplayVectorInteractor::Pointer crtlZoomInteractor = mitk::DisplayVectorInteractor::New(
"CtrlZoom", new mitk::DisplayInteractor() );
listener = crtlZoomInteractor;
m_ListenersForPACS.push_back( listener );
}
void mitk::MouseModeSwitcher::SetInteractionScheme( InteractionScheme scheme )
{
switch ( scheme )
{
case MITK :
{
ListenerList::iterator iter;
for ( iter=m_ListenersForPACS.begin(); iter!=m_ListenersForPACS.end(); iter++ )
{
m_GlobalInteraction->RemoveListener( (*iter) );
}
for ( iter=m_ListenersForMITK.begin(); iter!=m_ListenersForMITK.end(); iter++ )
{
m_GlobalInteraction->AddListener( (*iter) );
}
break;
} // case MITK
case PACS :
{
ListenerList::iterator iter;
for ( iter=m_ListenersForMITK.begin(); iter!=m_ListenersForMITK.end(); iter++ )
{
m_GlobalInteraction->RemoveListener( (*iter) );
}
for ( iter=m_ListenersForPACS.begin(); iter!=m_ListenersForPACS.end(); iter++ )
{
m_GlobalInteraction->AddListener( (*iter) );
}
this->SelectMouseMode( MousePointer );
break;
} // case PACS
} // switch
m_ActiveInteractionScheme = scheme;
}
void mitk::MouseModeSwitcher::SelectMouseMode( MouseMode mode )
{
if ( m_ActiveInteractionScheme != PACS )
return;
switch ( mode )
{
case MousePointer :
{
m_GlobalInteraction->RemoveListener( m_LeftMouseButtonHandler );
break;
} // case 0
case Scroll :
{
m_GlobalInteraction->RemoveListener( m_LeftMouseButtonHandler );
mitk::DisplayVectorInteractorScroll::Pointer scrollInteractor = mitk::DisplayVectorInteractorScroll::New(
"LeftClickScroll", new mitk::DisplayInteractor() );
m_LeftMouseButtonHandler = scrollInteractor;
m_GlobalInteraction->AddListener( m_LeftMouseButtonHandler );
break;
} // case 1
case LevelWindow :
{
m_GlobalInteraction->RemoveListener( m_LeftMouseButtonHandler );
mitk::DisplayVectorInteractorLevelWindow::Pointer lwInteractor = mitk::DisplayVectorInteractorLevelWindow::New(
"LeftClickLevelWindow" );
m_LeftMouseButtonHandler = lwInteractor;
m_GlobalInteraction->AddListener( m_LeftMouseButtonHandler );
break;
} // case 2
case Zoom :
{
m_GlobalInteraction->RemoveListener( m_LeftMouseButtonHandler );
mitk::DisplayVectorInteractor::Pointer zoomInteractor = mitk::DisplayVectorInteractor::New(
"Zoom", new mitk::DisplayInteractor() );
m_LeftMouseButtonHandler = zoomInteractor;
m_GlobalInteraction->AddListener( m_LeftMouseButtonHandler );
break;
} // case 3
case Pan :
{
m_GlobalInteraction->RemoveListener( m_LeftMouseButtonHandler );
mitk::DisplayVectorInteractor::Pointer panInteractor = mitk::DisplayVectorInteractor::New(
"Pan", new mitk::DisplayInteractor() );
m_LeftMouseButtonHandler = panInteractor;
m_GlobalInteraction->AddListener( m_LeftMouseButtonHandler );
break;
} // case 4
} // switch (mode)
m_ActiveMouseMode = mode;
this->InvokeEvent( MouseModeChangedEvent() );
}
mitk::MouseModeSwitcher::MouseMode mitk::MouseModeSwitcher::GetCurrentMouseMode() const
{
return m_ActiveMouseMode;
}
diff --git a/Core/Code/Interactions/mitkMouseModeSwitcher.h b/Core/Code/Interactions/mitkMouseModeSwitcher.h
index 919b2f113a..0bcc2ddcdc 100644
--- a/Core/Code/Interactions/mitkMouseModeSwitcher.h
+++ b/Core/Code/Interactions/mitkMouseModeSwitcher.h
@@ -1,149 +1,148 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-28 17:19:30 +0200 (Thu, 28 May 2009) $
-Version: $Revision: 17495 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKMouseModeSwitcher_H_HEADER_INCLUDED_C10DC4EB
#define MITKMouseModeSwitcher_H_HEADER_INCLUDED_C10DC4EB
#include "MitkExports.h"
#include "mitkGlobalInteraction.h"
#include <itkObject.h>
namespace mitk {
/***********************************************************************
*
* \brief Class that offers a convenient way to switch between different
* interaction schemes
*
* This class offers the possibility to swtch between the two different
* interaction schemes that are available:
* - MITK : The original interaction scheme
* - left mouse button : setting the cross position in the MPR view
* - middle mouse button : panning
* - right mouse button : zooming
*
*
* - PACS : an alternative interaction scheme that behaves more like a
* PACS workstation
* - left mouse button : behaviour depends on current MouseMode
* - middle mouse button : fast scrolling
* - right mouse button : level-window
* - ctrl + right button : zooming
* - shift+ right button : panning
*
* There are 5 different MouseModes that are available in the PACS scheme.
* Each MouseMode defines the interaction that is performed on a left
* mouse button click:
* - Pointer : sets the cross position for the MPR
* - Scroll
* - Level-Window
* - Zoom
* - Pan
*
* When the interaction scheme or the MouseMode is changed, this class
* manages the adding and removing of the relevant listeners offering
* a convenient way to modify the interaction behaviour.
*
***********************************************************************/
class MITK_CORE_EXPORT MouseModeSwitcher : public itk::Object
{
public:
#pragma GCC visibility push(default)
/**
\brief Can be observed by GUI class to update button states when mode is changed programatically.
*/
itkEventMacro( MouseModeChangedEvent, itk::AnyEvent );
#pragma GCC visibility pop
mitkClassMacro( MouseModeSwitcher, itk::Object );
mitkNewMacro1Param( Self, GlobalInteraction* );
// enum of the different interaction schemes that are available
enum InteractionScheme
{
PACS = 0,
MITK = 1
};
// enum of available mouse modes for PACS interaction scheme
enum MouseMode
{
MousePointer = 0,
Scroll,
LevelWindow,
Zoom,
Pan
};
/**
* \brief Setter for interaction scheme
*/
void SetInteractionScheme( InteractionScheme );
/**
* \brief Setter for mouse mode
*/
void SelectMouseMode( MouseMode mode );
/**
* \brief Returns the current mouse mode
*/
MouseMode GetCurrentMouseMode() const;
protected:
/**
* \brief Constructor takes GlobalInteraction, MUST NOT be NULL.
**/
MouseModeSwitcher( GlobalInteraction* );
virtual ~MouseModeSwitcher();
private:
/**
* \brief Initializes the listeners for the different interaction schemes
*
* This method creates all listeners that are required for the different
* interaction schemes. These are stored in two lists.
*/
void InitializeListeners();
GlobalInteraction::Pointer m_GlobalInteraction;
InteractionScheme m_ActiveInteractionScheme;
MouseMode m_ActiveMouseMode;
typedef std::vector<StateMachine::Pointer> ListenerList;
ListenerList m_ListenersForMITK;
ListenerList m_ListenersForPACS;
StateMachine::Pointer m_LeftMouseButtonHandler;
};
} // namespace mitk
#endif /* MITKMouseModeSwitcher_H_HEADER_INCLUDED_C10DC4EB */
diff --git a/Core/Code/Interactions/mitkMouseMovePointSetInteractor.cpp b/Core/Code/Interactions/mitkMouseMovePointSetInteractor.cpp
index 9b5dba7737..a84eb4aa34 100644
--- a/Core/Code/Interactions/mitkMouseMovePointSetInteractor.cpp
+++ b/Core/Code/Interactions/mitkMouseMovePointSetInteractor.cpp
@@ -1,71 +1,70 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 17194 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkMouseMovePointSetInteractor.h"
#include "mitkPositionEvent.h"
#include "mitkStateEvent.h"
#include "mitkBaseRenderer.h"
mitk::MouseMovePointSetInteractor
::MouseMovePointSetInteractor(const char * type, DataNode* dataNode, int n)
:PointSetInteractor(type, dataNode, n)
{
}
mitk::MouseMovePointSetInteractor::~MouseMovePointSetInteractor()
{
}
//##Documentation
//## overwritten cause this class can handle mouse move events!
float mitk::MouseMovePointSetInteractor::CanHandleEvent(StateEvent const* stateEvent) const
{
float returnValue = 0.0;
//if it is a key event that can be handled in the current state, then return 0.5
mitk::DisplayPositionEvent const *disPosEvent =
dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
//Key event handling:
if (disPosEvent == NULL)
{
//check, if the current state has a transition waiting for that key event.
if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
{
return 0.5;
}
else
{
return 0;
}
}
//get the time of the sender to look for the right transition.
mitk::BaseRenderer* sender = stateEvent->GetEvent()->GetSender();
if (sender != NULL)
{
unsigned int timeStep = sender->GetTimeStep(m_DataNode->GetData());
//if the event can be understood and if there is a transition waiting for that event
mitk::State const* state = this->GetCurrentState(timeStep);
if (state!= NULL)
if (state->GetTransition(stateEvent->GetId())!=NULL)
returnValue = 0.5;//it can be understood
}
return returnValue;
}
diff --git a/Core/Code/Interactions/mitkMouseMovePointSetInteractor.h b/Core/Code/Interactions/mitkMouseMovePointSetInteractor.h
index 9f7aa6dec6..f698051d9c 100644
--- a/Core/Code/Interactions/mitkMouseMovePointSetInteractor.h
+++ b/Core/Code/Interactions/mitkMouseMovePointSetInteractor.h
@@ -1,70 +1,69 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 17179 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKMOUSEMOVEPOINTSETINTERACTOR_H_HEADER_INCLUDED_C11202FF
#define MITKMOUSEMOVEPOINTSETINTERACTOR_H_HEADER_INCLUDED_C11202FF
#include <MitkExports.h>
#include "mitkVector.h"
#include <mitkPointSetInteractor.h>
namespace mitk
{
class DataNode;
/**
* \brief Interaction with a single point by mouse movement.
*
* A new point is added by mouse movement, an existing point will be removed before adding a new one.
* \ingroup Interaction
*/
class MITK_CORE_EXPORT MouseMovePointSetInteractor : public PointSetInteractor
{
public:
mitkClassMacro(MouseMovePointSetInteractor, Interactor);
mitkNewMacro3Param(Self, const char*, DataNode*, int);
mitkNewMacro2Param(Self, const char*, DataNode*);
/**
* \brief calculates how good the data, this statemachine handles, is hit
* by the event.
*
* overwritten, cause we don't look at the boundingbox, we look at each point
* and want to accept mouse movement for setting points
*/
virtual float CanHandleEvent(StateEvent const* stateEvent) const;
protected:
/**
* \brief Constructor with Param n for limited Set of Points
*
* if no n is set, then the number of points is unlimited*
*/
MouseMovePointSetInteractor(const char * type, DataNode* dataNode, int n = -1);
/**
* \brief Default Destructor
**/
virtual ~MouseMovePointSetInteractor();
private:
};
}
#endif /* MITKMOUSEMOVEPOINTSETINTERACTOR_H_HEADER_INCLUDED_C11202FF */
diff --git a/Core/Code/Interactions/mitkMoveSurfaceInteractor.cpp b/Core/Code/Interactions/mitkMoveSurfaceInteractor.cpp
index e03d265435..cec1f3edd5 100644
--- a/Core/Code/Interactions/mitkMoveSurfaceInteractor.cpp
+++ b/Core/Code/Interactions/mitkMoveSurfaceInteractor.cpp
@@ -1,181 +1,180 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-09-14 09:48:51 +0200 (Di, 14 Sep 2010) $
-Version: $Revision: 26074 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkMoveSurfaceInteractor.h"
#include "mitkSurface.h"
#include "mitkInteractionConst.h"
#include <mitkDataNode.h>
#include "mitkDisplayPositionEvent.h"
#include "mitkStateEvent.h"
#include "mitkProperties.h"
//for an temporary update
#include "mitkRenderingManager.h"
//## Default Constructor
mitk::MoveSurfaceInteractor
::MoveSurfaceInteractor(const char * type, DataNode* dataNode)
:Interactor(type, dataNode)
{
}
mitk::MoveSurfaceInteractor::~MoveSurfaceInteractor()
{
}
bool mitk::MoveSurfaceInteractor::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent )
{
bool ok = false;
/*Each case must watch the type of the event!*/
switch (action->GetActionId())
{
case AcDONOTHING:
ok = true;
break;
case AcCHECKELEMENT:
/*
* picking: Answer the question if the given position within stateEvent is close enough to select an object
* send yes if close enough and no if not picked
*/
{
mitk::DisplayPositionEvent const *posEvent = dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
if (posEvent == NULL)
{
MITK_WARN<<"Wrong usage of mitkMoveSurfaceInteractor! Aborting interaction!\n";
return false;
}
mitk::Point3D worldPoint = posEvent->GetWorldPosition();
/* now we have a worldpoint. check if it is inside our object and select/deselect it accordingly */
mitk::StateEvent* newStateEvent = NULL;
const Geometry3D* geometry = GetData()->GetUpdatedTimeSlicedGeometry()->GetGeometry3D( m_TimeStep );
if (geometry->IsInside(worldPoint))
newStateEvent = new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
else
newStateEvent = new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
/* write new state (selected/not selected) to the property */
this->HandleEvent( newStateEvent );
ok = true;
break;
}
case AcSELECT:
// select the data
{
mitk::BoolProperty::Pointer selected = dynamic_cast<mitk::BoolProperty*>(m_DataNode->GetProperty("selected"));
if ( selected.IsNull() )
{
selected = mitk::BoolProperty::New();
m_DataNode->GetPropertyList()->SetProperty("selected", selected);
}
mitk::ColorProperty::Pointer color = dynamic_cast<mitk::ColorProperty*>(m_DataNode->GetProperty("color"));
if ( color.IsNull() )
{
color = mitk::ColorProperty::New();
m_DataNode->GetPropertyList()->SetProperty("color", color);
}
selected->SetValue(true);
color->SetColor(1.0, 1.0, 0.0);
//update rendering
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
ok = true;
break;
}
case AcDESELECT:
//deselect the data
{
mitk::BoolProperty::Pointer selected = dynamic_cast<mitk::BoolProperty*>(m_DataNode->GetProperty("selected"));
if ( selected.IsNull() )
{
selected = mitk::BoolProperty::New();
m_DataNode->GetPropertyList()->SetProperty("selected", selected);
}
mitk::ColorProperty::Pointer color = dynamic_cast<mitk::ColorProperty*>(m_DataNode->GetProperty("color"));
if ( color.IsNull() )
{
color = mitk::ColorProperty::New();
m_DataNode->GetPropertyList()->SetProperty("color", color);
}
selected = mitk::BoolProperty::New(false);
color->SetColor(0.0, 0.0, 1.0);
//update rendering
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
ok = true;
break;
}
case AcMOVE:
{
//modify Geometry from data as given in parameters or in event
mitk::IntProperty* xP = dynamic_cast<mitk::IntProperty*>(action->GetProperty("DIRECTION_X"));
mitk::IntProperty* yP = dynamic_cast<mitk::IntProperty*>(action->GetProperty("DIRECTION_Y"));
mitk::IntProperty* zP = dynamic_cast<mitk::IntProperty*>(action->GetProperty("DIRECTION_Z"));
if (xP == NULL || yP == NULL || zP == NULL)
{
MITK_WARN<<"No properties returned\n!";
return false;
}
mitk::Vector3D movementVector;
movementVector.SetElement(0, (float) xP->GetValue());
movementVector.SetElement(1, (float) yP->GetValue());
movementVector.SetElement(2, (float) zP->GetValue());
//checking corresponding Data; has to be a surface or a subclass
mitk::Surface* surface = dynamic_cast<mitk::Surface*>(m_DataNode->GetData());
if ( surface == NULL )
{
MITK_WARN<<"MoveSurfaceInteractor got wrong type of data! Aborting interaction!\n";
return false;
}
Geometry3D* geometry = surface->GetUpdatedTimeSlicedGeometry()->GetGeometry3D( m_TimeStep );
geometry->Translate(movementVector);
// indicate modification of data tree node
m_DataNode->Modified();
//update rendering
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
ok = true;
break;
}
default:
return Superclass::ExecuteAction( action, stateEvent );
}
return ok;
}
/**
\example mitkMoveSurfaceInteractor.cpp
* This is an example of how to implement a new Interactor.
* See more details about this example in tutorial Step10.
*/
diff --git a/Core/Code/Interactions/mitkMoveSurfaceInteractor.h b/Core/Code/Interactions/mitkMoveSurfaceInteractor.h
index cf1355d31f..07ca0bcfb4 100644
--- a/Core/Code/Interactions/mitkMoveSurfaceInteractor.h
+++ b/Core/Code/Interactions/mitkMoveSurfaceInteractor.h
@@ -1,77 +1,76 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-08-25 13:01:29 +0200 (Mi, 25 Aug 2010) $
-Version: $Revision: 25766 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKMOVESURFACEINTERACTOR_H_HEADER_INCLUDED
#define MITKMOVESURFACEINTERACTOR_H_HEADER_INCLUDED
#include <mitkInteractor.h>
namespace mitk
{
class DataNode;
/**
* \brief Interaction to move a surface by the arrow keys. See tutorial step 10 for explanation
*
* \ingroup Interaction
*/
class MITK_CORE_EXPORT MoveSurfaceInteractor : public Interactor
{
public:
mitkClassMacro(MoveSurfaceInteractor, Interactor);
mitkNewMacro2Param(Self, const char*, DataNode*);
/**
* \brief check how good an event can be handled
*/
//virtual float CanHandleEvent(StateEvent const* stateEvent) const;
//used from mitkInteractor
/**
*@brief Gets called when mitk::DataNode::SetData() is called
*
* No need to use it here, because the pattern won't be complex
* and we can take care of unexpected data change
**/
//virtual void DataChanged(){};
protected:
/**
* \brief Constructor
*/
MoveSurfaceInteractor(const char * type, DataNode* dataNode);
/**
* \brief Default Destructor
**/
virtual ~MoveSurfaceInteractor();
/**
* @brief Convert the given Actions to Operations and send to data and UndoController
**/
virtual bool ExecuteAction( Action* action, mitk::StateEvent const* stateEvent );
};
}
/**
\example mitkMoveSurfaceInteractor.h
* This is an example of how to implement a new Interactor.
* See more details about this example in tutorial Step10.
*/
#endif /* MITKMOVESURFACEINTERACTOR_H_HEADER_INCLUDED */
diff --git a/Core/Code/Interactions/mitkNodeDepententPointSetInteractor.cpp b/Core/Code/Interactions/mitkNodeDepententPointSetInteractor.cpp
index 5fb8a11afb..f5b1cbbbde 100644
--- a/Core/Code/Interactions/mitkNodeDepententPointSetInteractor.cpp
+++ b/Core/Code/Interactions/mitkNodeDepententPointSetInteractor.cpp
@@ -1,54 +1,53 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-09-14 09:48:51 +0200 (Di, 14 Sep 2010) $
-Version: $Revision: 26074 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodeDepententPointSetInteractor.h"
#include "mitkStateEvent.h"
#include "mitkEvent.h"
mitk::NodeDepententPointSetInteractor
::NodeDepententPointSetInteractor(const char * type, DataNode* dataNode, DataNode* dependentDataNode, int n)
:PointSetInteractor(type, dataNode, n), m_DependentDataNode(dependentDataNode)
{
}
mitk::NodeDepententPointSetInteractor::~NodeDepententPointSetInteractor()
{
}
float mitk::NodeDepententPointSetInteractor::CanHandleEvent(StateEvent const* stateEvent) const
{
if (m_DependentDataNode.IsNull())
return 0;
// use sender to check if the specified dependentDataNode is visible there
mitk::BaseRenderer* sender = stateEvent->GetEvent()->GetSender();
if (sender == NULL)
return 0;
bool value = false;
if ( m_DependentDataNode->GetPropertyList(sender)->GetBoolProperty("visible", value) == false)//property doesn't exist
return 0;
if (value == false) //the dependent node is invisible
return 0;
//ok, it is visible, so check the standard way.
return Superclass::CanHandleEvent(stateEvent);
}
diff --git a/Core/Code/Interactions/mitkNodeDepententPointSetInteractor.h b/Core/Code/Interactions/mitkNodeDepententPointSetInteractor.h
index f69784922e..7fcfe1003e 100644
--- a/Core/Code/Interactions/mitkNodeDepententPointSetInteractor.h
+++ b/Core/Code/Interactions/mitkNodeDepententPointSetInteractor.h
@@ -1,78 +1,77 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-10-04 14:49:09 +0200 (Mo, 04 Okt 2010) $
-Version: $Revision: 26576 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKNodeDepententPointSetInteractor_H_HEADER_INCLUDED
#define MITKNodeDepententPointSetInteractor_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkVector.h"
#include <mitkInteractor.h>
#include <mitkDataNode.h>
#include <mitkPointSetInteractor.h>
namespace mitk
{
/**
* \brief PointSetInteraction that is dependent on the visibility property of a data node.
*
* The interactor checks if the renderwindow specific property "visible" of a different node (e.g. image)
* specified by @param dependentDataNode is true. The specific renderwindow is specified by the sender of the event.
* If the property is true the the object behaves as described by PointSetInteractor.
* If not, interaction is blocked.
*
* This class shows how to write an interactor, that is dependent on a special property of the associated node.
* See bug #6047 for further information and a patch to test this class embedded in tutorial Step 5.
* \ingroup Interaction
*/
class MITK_CORE_EXPORT NodeDepententPointSetInteractor : public PointSetInteractor
{
public:
mitkClassMacro(NodeDepententPointSetInteractor, PointSetInteractor);
mitkNewMacro4Param(Self, const char*, DataNode*, DataNode*, int);
mitkNewMacro3Param(Self, const char*, DataNode*, DataNode*);
/**
* \brief Checks visibility of the specified node (e.g. image),
* returns 0 if node is not visible in sending render window
* If Sender within stateEvent is NULL a value of 0 is returned.
*/
virtual float CanHandleEvent(StateEvent const* stateEvent) const;
protected:
/**
* \brief Constructor with Param n for limited Set of Points
*
* If no n is set, then the number of points is unlimited
* n=0 is not supported. In this case, n is set to 1.
*/
NodeDepententPointSetInteractor(const char * type, DataNode* dataNode, DataNode* dependentDataNode, int n = -1);
/**
* \brief Default Destructor
**/
virtual ~NodeDepententPointSetInteractor();
public:
mitk::DataNode::Pointer m_DependentDataNode;
};
}
#endif /* MITKNodeDepententPointSetInteractor_H_HEADER_INCLUDED */
diff --git a/Core/Code/Interactions/mitkPointSetInteractor.cpp b/Core/Code/Interactions/mitkPointSetInteractor.cpp
index b726c279a2..3f993c0695 100644
--- a/Core/Code/Interactions/mitkPointSetInteractor.cpp
+++ b/Core/Code/Interactions/mitkPointSetInteractor.cpp
@@ -1,1182 +1,1181 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetInteractor.h"
#include "mitkPointOperation.h"
#include "mitkPositionEvent.h"
#include "mitkPointSet.h"
//#include "mitkStatusBar.h"
#include "mitkDataNode.h"
#include "mitkInteractionConst.h"
#include "mitkAction.h"
#include "mitkStateEvent.h"
#include "mitkOperationEvent.h"
#include "mitkUndoController.h"
#include "mitkStateMachineFactory.h"
#include "mitkStateTransitionOperation.h"
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
//how precise must the user pick the point
//default value
const int PRECISION = 5;
mitk::PointSetInteractor
::PointSetInteractor(const char * type, DataNode* dataNode, int n)
:Interactor(type, dataNode), m_Precision(PRECISION), m_N(n)
{
if (m_N==0)
{
STATEMACHINE_WARN<<"Instanciation of PointSetInteractor which takes care of 0 points does't make sense!\n";
STATEMACHINE_WARN<<"Setting number of points to 1!\n";
m_N = 1;
}
m_LastPoint.Fill(0);
m_SumVec.Fill(0);
this->InitAccordingToNumberOfPoints();
}
mitk::PointSetInteractor::~PointSetInteractor()
{
}
//##Documentation
//## overwritten cause this class can handle it better!
float mitk::PointSetInteractor::CanHandleEvent(StateEvent const* stateEvent) const
{
float returnValue = 0.0;
//if it is a key event that can be handled in the current state, then return 0.5
mitk::DisplayPositionEvent const *disPosEvent =
dynamic_cast <const mitk::DisplayPositionEvent *> (stateEvent->GetEvent());
//Key event handling:
if (disPosEvent == NULL)
{
//check, if the current state has a transition waiting for that key event.
if (this->GetCurrentState()->GetTransition(stateEvent->GetId())!=NULL)
{
return 0.5;
}
else
{
return 0;
}
}
//on MouseMove do nothing!
if (stateEvent->GetEvent()->GetType() == mitk::Type_MouseMove)
{
return 0;
}
//get the time of the sender to look for the right transition.
mitk::BaseRenderer* sender = stateEvent->GetEvent()->GetSender();
if (sender != NULL)
{
unsigned int timeStep = sender->GetTimeStep(m_DataNode->GetData());
//if the event can be understood and if there is a transition waiting for that event
mitk::State const* state = this->GetCurrentState(timeStep);
if (state!= NULL)
if (state->GetTransition(stateEvent->GetId())!=NULL)
returnValue = 0.5;//it can be understood
mitk::PointSet *pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
if ( pointSet != NULL )
{
//if we have one point or more, then check if the have been picked
if ( (pointSet->GetSize( timeStep ) > 0)
&& (pointSet->SearchPoint(
disPosEvent->GetWorldPosition(), m_Precision, timeStep) > -1) )
{
returnValue = 1.0;
}
}
}
return returnValue;
}
//TODO: add a new calculation of precision here! Input: StateEvent and Precision
//the method does a 2D picking with display coordinates and display geometry.
//Here the distance between the mouse position and the point is not as relative anymore!
//float mitk::PointSetInteractor::CalculatePrecision(float precision, mitk::StateEvent stateEvent)
//{
// mitk::BaseRenderer *renderer = stateEvent->GetEvent()->GetSender();
// if (renderer != NULL)
// {
// const mitk::DisplayGeometry* displayGeometry = renderer->GetDisplayGeometry();
// if (displayGeometry != NULL)
// displayGeometry->WorldToDisplay(, lineFrom);
// precision =
// }
//
// return precision;
//
//}
void mitk::PointSetInteractor::UnselectAll( unsigned int timeStep, ScalarType timeInMS )
{
mitk::PointSet *pointSet =
dynamic_cast<mitk::PointSet*>( m_DataNode->GetData() );
if ( pointSet == NULL )
{
return;
}
mitk::PointSet::DataType *itkPointSet = pointSet->GetPointSet( timeStep );
if ( itkPointSet == NULL )
{
return;
}
mitk::PointSet::PointsContainer::Iterator it, end;
end = itkPointSet->GetPoints()->End();
for (it = itkPointSet->GetPoints()->Begin(); it != end; it++)
{
int position = it->Index();
PointSet::PointDataType pointData = {0, false, PTUNDEFINED};
itkPointSet->GetPointData( position, &pointData );
//then declare an operation which unselects this point;
//UndoOperation as well!
if ( pointData.selected )
{
mitk::Point3D noPoint;
noPoint.Fill( 0 );
mitk::PointOperation *doOp = new mitk::PointOperation(
OpDESELECTPOINT, timeInMS, noPoint, position);
if ( m_UndoEnabled )
{
mitk::PointOperation *undoOp =
new mitk::PointOperation(OpSELECTPOINT, timeInMS, noPoint, position);
OperationEvent *operationEvent =
new OperationEvent( pointSet, doOp, undoOp );
m_UndoController->SetOperationEvent( operationEvent );
}
pointSet->ExecuteOperation( doOp );
if ( !m_UndoEnabled )
delete doOp;
}
}
}
void mitk::PointSetInteractor::SelectPoint( int position, unsigned int timeStep, ScalarType timeInMS )
{
mitk::PointSet *pointSet = dynamic_cast< mitk::PointSet * >(
m_DataNode->GetData() );
//if List is empty, then no select of a point can be done!
if ( (pointSet == NULL) || (pointSet->GetSize( timeStep ) <= 0) )
{
return;
}
//dummyPoint... not needed anyway
mitk::Point3D noPoint;
noPoint.Fill(0);
mitk::PointOperation *doOp = new mitk::PointOperation(
OpSELECTPOINT, timeInMS, noPoint, position);
if ( m_UndoEnabled )
{
mitk::PointOperation* undoOp = new mitk::PointOperation(
OpDESELECTPOINT, timeInMS, noPoint, position);
OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
pointSet->ExecuteOperation( doOp );
if ( !m_UndoEnabled )
delete doOp;
}
bool mitk::PointSetInteractor::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent )
{
bool ok = false;//for return type bool
//checking corresponding Data; has to be a PointSet or a subclass
mitk::PointSet* pointSet =
dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
if ( pointSet == NULL )
{
return false;
}
//get the timestep to support 3D+T
const mitk::Event *theEvent = stateEvent->GetEvent();
mitk::ScalarType timeInMS = 0.0;
//check if the current timestep has to be changed
if ( theEvent )
{
if (theEvent->GetSender() != NULL)
{
//additionaly to m_TimeStep we need timeInMS to satisfy the execution of the operations
timeInMS = theEvent->GetSender()->GetTime();
}
}
//for reading on the points, Id's etc
mitk::PointSet::DataType *itkPointSet = pointSet->GetPointSet( m_TimeStep );
if ( itkPointSet == NULL )
{
return false;
}
mitk::PointSet::PointsContainer *points = itkPointSet->GetPoints();
/*Each case must watch the type of the event!*/
switch (action->GetActionId())
{
case AcDONOTHING:
ok = true;
break;
case AcCHECKOPERATION:
//to check if the given Event is a DisplayPositionEvent.
{
mitk::DisplayPositionEvent const *dispPosEvent =
dynamic_cast <const mitk::DisplayPositionEvent *> (
stateEvent->GetEvent());
if (dispPosEvent != NULL)
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
this->HandleEvent( newStateEvent );
delete newStateEvent;
}
else
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
this->HandleEvent( newStateEvent );
delete newStateEvent;
}
ok = true;
break;
}
case AcADDPOINT:
// Declare two operations: one for the selected state: deselect the last
// one selected and select the new one the other operation is the add
// operation: There the first empty place have to be found and the new
// point inserted into that space
{
mitk::DisplayPositionEvent const *posEvent =
dynamic_cast < const mitk::DisplayPositionEvent * >
(stateEvent->GetEvent());
// Check if it is a DisplayEvent thrown in a 3D window. Then the
// z-information is missing. Returning false might end in the state
// full, but the last point couldn't be added, so the set wouldn't be
// full. So a extra Action that checks the operationtype has been added.
if ( posEvent == NULL )
{
return false;
}
mitk::Point3D itkPoint;
itkPoint = posEvent->GetWorldPosition();
// undo-supported deselect of all points in the DataList; if List is
// empty, then nothing will be unselected
this->UnselectAll( m_TimeStep, timeInMS );
// find the position, the point is to be added to: first entry with
// empty index. If the Set is empty, then start with 0. if not empty,
// then take the first index not occupied
int lastPosition = 0;
if (!points->empty())
{
mitk::PointSet::PointsIterator it, end;
it = points->Begin();
end = points->End();
while( it != end )
{
if (!points->IndexExists(lastPosition))
break;
++it;
++lastPosition;
}
}
PointOperation* doOp = new mitk::PointOperation(
OpINSERT, timeInMS, itkPoint, lastPosition);
if (m_UndoEnabled)
{
// difference between OpDELETE and OpREMOVE is, that OpDELETE deletes
// a point at the end, and OpREMOVE deletes it from the given position
// remove is better, cause we need the position to add or remove the
// point anyway. We can get the last position from size()
PointOperation *undoOp = new mitk::PointOperation(
OpREMOVE, timeInMS, itkPoint, lastPosition);
OperationEvent *operationEvent =
new OperationEvent(pointSet, doOp, undoOp, "Add point");
m_UndoController->SetOperationEvent(operationEvent);
}
//execute the Operation
pointSet->ExecuteOperation(doOp);
if ( !m_UndoEnabled )
delete doOp;
//the point is added and directly selected in PintSet. So no need to call OpSELECTPOINT
ok = true;
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
}
case AcINITMOVEMENT:
{
mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
if (posEvent == NULL)
return false;
// start of the Movement is stored to calculate the undoKoordinate
// in FinishMovement
m_LastPoint = posEvent->GetWorldPosition();
// initialize a value to calculate the movement through all
// MouseMoveEvents from MouseClick to MouseRelease
m_SumVec.Fill(0);
ok = true;
break;
}
case AcMOVESELECTED://moves all selected Elements
{
mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
if (posEvent == NULL)
return false;
mitk::Point3D newPoint, resultPoint;
newPoint = posEvent->GetWorldPosition();
// search the elements in the list that are selected then calculate the
// vector, because only with the vector we can move several elements in
// the same direction
// newPoint - lastPoint = vector
// then move all selected and set the lastPoint = newPoint.
// then add all vectors to a summeryVector (to be able to calculate the
// startpoint for undoOperation)
mitk::Vector3D dirVector = newPoint - m_LastPoint;
//sum up all Movement for Undo in FinishMovement
m_SumVec = m_SumVec + dirVector;
mitk::PointSet::PointsIterator it, end;
it = points->Begin();
end = points->End();
while( it != end )
{
int position = it->Index();
if ( pointSet->GetSelectInfo(position, m_TimeStep) )//if selected
{
PointSet::PointType pt = pointSet->GetPoint(position, m_TimeStep);
mitk::Point3D sumVec;
sumVec[0] = pt[0];
sumVec[1] = pt[1];
sumVec[2] = pt[2];
resultPoint = sumVec + dirVector;
PointOperation* doOp = new mitk::PointOperation(OpMOVE, timeInMS,
resultPoint, position);
//execute the Operation
//here no undo is stored, because the movement-steps aren't interesting.
// only the start and the end is interisting to store for undo.
pointSet->ExecuteOperation(doOp);
delete doOp;
}
++it;
}
m_LastPoint = newPoint;//for calculation of the direction vector
ok = true;
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
}
case AcREMOVEPOINT://remove the given Point from the list
{
//if the point to be removed is given by the positionEvent:
mitk::PositionEvent const *posEvent =
dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
if (posEvent != NULL)
{
mitk::Point3D itkPoint;
itkPoint = posEvent->GetWorldPosition();
//search the point in the list
int position = pointSet->SearchPoint(itkPoint, 0.0, m_TimeStep);
//distance set to 0, cause we already got the exact point from last
//State checkpointbut we also need the position in the list to remove it
if (position>=0)//found a point
{
PointSet::PointType pt = pointSet->GetPoint(position, m_TimeStep);
itkPoint[0] = pt[0];
itkPoint[1] = pt[1];
itkPoint[2] = pt[2];
//Undo
PointOperation* doOp = new mitk::PointOperation(OpREMOVE,
timeInMS, itkPoint, position);
if (m_UndoEnabled) //write to UndoMechanism
{
PointOperation* undoOp = new mitk::PointOperation(OpINSERT,
timeInMS, itkPoint, position);
OperationEvent *operationEvent = new OperationEvent(pointSet,
doOp, undoOp, "Remove point");
m_UndoController->SetOperationEvent(operationEvent);
}
//execute the Operation
pointSet->ExecuteOperation(doOp);
if ( !m_UndoEnabled )
delete doOp;
/*now select the point "position-1",
and if it is the first in list,
then contine at the last in list*/
//only then a select of a point is possible!
if (pointSet->GetSize( m_TimeStep ) > 0)
{
if (position>0)//not the first in list
{
this->SelectPoint( position-1, m_TimeStep, timeInMS );
}
//it was the first point in list, that was removed, so select
//the last in list
else
{
position = pointSet->GetSize( m_TimeStep ) - 1; //last in list
this->SelectPoint( position, m_TimeStep, timeInMS );
}//else
}//if
ok = true;
}
}
else //no position is given so remove all selected elements
{
//delete all selected points
//search for the selected one and then declare the operations!
mitk::PointSet::PointsContainer::Iterator it, end;
it = points->Begin();
end = points->End();
int position = 0;
int previousExistingPosition = -1;//to recognize the last existing position; needed because the iterator gets invalid if the point is deleted!
int lastDelPrevExistPosition = -1; //the previous position of the last deleted point
while (it != end)
{
if (points->IndexExists(it->Index()))
{
//if point is selected
if ( pointSet->GetSelectInfo(it->Index(), m_TimeStep) )
{
//get the coordinates of that point to be undoable
PointSet::PointType selectedPoint = it->Value();
mitk::Point3D itkPoint;
itkPoint[0] = selectedPoint[0];
itkPoint[1] = selectedPoint[1];
itkPoint[2] = selectedPoint[2];
position = it->Index();
PointOperation* doOp = new mitk::PointOperation(OpREMOVE,
timeInMS, itkPoint, position);
//Undo
if (m_UndoEnabled) //write to UndoMechanism
{
PointOperation* undoOp = new mitk::PointOperation(OpINSERT,
timeInMS, itkPoint, position);
OperationEvent *operationEvent = new OperationEvent(pointSet,
doOp, undoOp, "Remove point");
m_UndoController->SetOperationEvent(operationEvent);
}
pointSet->ExecuteOperation(doOp);
if ( !m_UndoEnabled )
delete doOp;
//after delete the iterator is undefined, so start again
//count to the last existing entry
if (points->Size()>1 && points->IndexExists(previousExistingPosition))
{
for (it = points->Begin(); it != points->End(); it++)
{
if (it->Index() == (unsigned int) previousExistingPosition)
{
lastDelPrevExistPosition = previousExistingPosition;
break; //return if the iterator on the last existing position is found
}
}
}
else // size <= 1 or no previous existing position set
{
//search for the first existing position
for (it = points->Begin(); it != points->End(); it++)
if (points->IndexExists(it->Index()))
{
previousExistingPosition = it->Index();
break;
}
}
//now that we have set the iterator, lets get sure, that the next it++ will not crash!
if (it == end) { break; }
}//if
else
{
previousExistingPosition = it->Index();
}
}//if index exists
it++;
}//while
if (lastDelPrevExistPosition < 0)//the var has not been set because the first element was deleted and there was no prev position
lastDelPrevExistPosition = previousExistingPosition; //go to the end
/*
* now select the point before the point/points that was/were deleted
*/
if (pointSet->GetSize( m_TimeStep ) > 0) //only then a select of a point is possible!
{
if (points->IndexExists(lastDelPrevExistPosition))
{
this->SelectPoint( lastDelPrevExistPosition, m_TimeStep, timeInMS );
}
else
{
//select the first existing element
for (mitk::PointSet::PointsContainer::Iterator it = points->Begin(); it != points->End(); it++)
if (points->IndexExists(it->Index()))
{
this->SelectPoint( it->Index(), m_TimeStep, timeInMS );
break;
}
}
}//if
ok = true;
}//else
}//case
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
// Remove all Points that have been set at once.
// TODO: Undo function not supported yet.
case AcREMOVEALL:
{
if ( !points->empty() )
{
PointSet::PointType pt;
mitk::PointSet::PointsContainer::Iterator it, end;
it = points->Begin();
end = points->End();
int position = 0;
while ( it != end )
{
position = it->Index();
if ( points->IndexExists( position ) )
{
pt = pointSet->GetPoint( position, m_TimeStep );
PointOperation* doOp =
new mitk::PointOperation( OpREMOVE, timeInMS, pt, position );
++it;
pointSet->ExecuteOperation( doOp );
delete doOp;
}
else it++;
}
}
ok = true;
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
}
//Checking if the Point transmitted is close enough to one point. Then
//generate a new event with the point and let this statemaschine
//handle the event.
case AcCHECKELEMENT:
{
mitk::PositionEvent const *posEvent =
dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
if (posEvent != NULL)
{
mitk::Point3D worldPoint = posEvent->GetWorldPosition();
int position = pointSet->SearchPoint( worldPoint, m_Precision, m_TimeStep );
if (position>=0)//found a point near enough to the given point
{
//get that point, the one meant by the user!
PointSet::PointType pt = pointSet->GetPoint(position, m_TimeStep);
mitk::Point2D displPoint;
displPoint[0] = worldPoint[0]; displPoint[1] = worldPoint[1];
//new Event with information YES and with the correct point
mitk::PositionEvent const* newPosEvent =
new mitk::PositionEvent(posEvent->GetSender(), Type_None,
BS_NoButton, BS_NoButton, Key_none, displPoint, pt);
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDYES, newPosEvent);
//call HandleEvent to leave the guard-state
this->HandleEvent( newStateEvent );
delete newStateEvent;
delete newPosEvent;
ok = true;
}
else
{
//new Event with information NO
mitk::StateEvent* newStateEvent = new mitk::StateEvent(EIDNO, posEvent);
this->HandleEvent(newStateEvent );
delete newStateEvent;
ok = true;
}
}
else
{
MITK_DEBUG("OperationError")<<this->GetType()<<" AcCHECKELEMENT expected PointOperation.";
mitk::DisplayPositionEvent const *disPosEvent =
dynamic_cast <const mitk::DisplayPositionEvent *> (
stateEvent->GetEvent());
if (disPosEvent != NULL)
{ //2d Koordinates for 3D Interaction; return false to redo
//the last statechange
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDNO, disPosEvent);
this->HandleEvent(newStateEvent );
delete newStateEvent;
ok = true;
}
}
break;
}
case AcCHECKONESELECTED:
//check if there is a point that is selected
{
if (pointSet->GetNumberOfSelected(m_TimeStep)>0)
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent( EIDYES, theEvent);
this->HandleEvent( newStateEvent );
delete newStateEvent;
}
else //not selected then call event EIDNO
{
//new Event with information NO
mitk::StateEvent* newStateEvent =
new mitk::StateEvent( EIDNO, theEvent);
this->HandleEvent( newStateEvent );
delete newStateEvent;
}
ok = true;
break;
}
case AcCHECKSELECTED:
/*check, if the given point is selected:
if no, then send EIDNO
if yes, then send EIDYES*/
// check, if: because of the need to look up the point again, it is
// possible, that we grab the wrong point in case there are two same points
// so maybe we do have to set a global index for further computation,
// as long, as the mouse is moved...
{
int position = -1;
mitk::PositionEvent const *posEvent =
dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
if (posEvent == NULL)
return false;
mitk::Point3D worldPoint = posEvent->GetWorldPosition();
position = pointSet->SearchPoint(worldPoint, m_Precision, m_TimeStep);
if (position>=0)
{
mitk::PositionEvent const *newPosEvent =
new mitk::PositionEvent(posEvent->GetSender(),
posEvent->GetType(), posEvent->GetButton(),
posEvent->GetButtonState(), posEvent->GetKey(),
posEvent->GetDisplayPosition(), posEvent->GetWorldPosition());
//if selected on true, then call Event EIDYES
if (pointSet->GetSelectInfo(position, m_TimeStep))
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent( EIDYES, newPosEvent );
this->HandleEvent( newStateEvent );
delete newStateEvent;
ok = true;
//saving the spot for calculating the direction vector in moving
m_LastPoint = posEvent->GetWorldPosition();
}
else //not selected then call event EIDNO
{
//new Event with information NO
mitk::StateEvent* newStateEvent =
new mitk::StateEvent( EIDNO, newPosEvent );
this->HandleEvent( newStateEvent );
delete newStateEvent;
ok = true;
}
delete newPosEvent;
}
//the position wasn't set properly. If necessary: search the given
//point in list and set var position
else
{
/*
mitk::StatusBar::GetInstance()->DisplayText(
"Message from mitkPointSetInteractor: Error in Actions! Check Config XML-file",
10000);
*/
ok = false;
}
break;
}
//generate Events if the set will be full after the addition of the
// point or not.
case AcCHECKNMINUS1:
{
// number of points not limited->pass on
// "Amount of points in Set is smaller then N-1"
if (m_N<0)
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent());
this->HandleEvent( newStateEvent );
delete newStateEvent;
ok = true;
}
else
{
if (pointSet->GetSize( m_TimeStep ) < m_N-1 )
//pointset after addition won't be full
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent());
this->HandleEvent( newStateEvent );
delete newStateEvent;
ok = true;
}
else
//after the addition of a point, the container will be full
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDSTLARGERNMINUS1, stateEvent->GetEvent());
this->HandleEvent(newStateEvent );
delete newStateEvent;
ok = true;
}//else
}//else
}
break;
case AcCHECKEQUALS1:
{
//the number of points in the list is 1 (or smaler)
if (pointSet->GetSize( m_TimeStep ) <= 1)
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDYES, stateEvent->GetEvent());
this->HandleEvent( newStateEvent );
delete newStateEvent;
ok = true;
}
else //more than 1 points in list, so stay in the state!
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDNO, stateEvent->GetEvent());
this->HandleEvent(newStateEvent );
delete newStateEvent;
ok = true;
}
}
break;
case AcCHECKNUMBEROFPOINTS:
{
//the number of points in the list is 1 (or smaler), so will be empty after delete
if (pointSet->GetSize( m_TimeStep ) <= 1)
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDEMPTY, stateEvent->GetEvent());
this->HandleEvent( newStateEvent );
delete newStateEvent;
ok = true;
}
else if (pointSet->GetSize( m_TimeStep ) <= m_N || m_N <= -1)
//m_N is set to unlimited points allowed or more than 1 points in list, but not full, so stay in the state!
{
// if the number of points equals m_N and no point of the point set is selected switch to state EIDEQUALSN
if ((pointSet->GetSize( m_TimeStep ) == m_N)&&(pointSet->GetNumberOfSelected()==0))
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDEQUALSN, stateEvent->GetEvent());
this->HandleEvent(newStateEvent );
delete newStateEvent;
ok = true;
}
// if the number of points is small than or equal m_N and point(s) are selected stay in state
else
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDSMALLERN, stateEvent->GetEvent());
this->HandleEvent(newStateEvent );
delete newStateEvent;
ok = true;
}
}
else
//pointSet->GetSize( m_TimeStep ) >=m_N.
// This can happen if the points were not added
// by interaction but by loading a .mps file
{
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDEQUALSN, stateEvent->GetEvent());
this->HandleEvent(newStateEvent );
delete newStateEvent;
ok = true;
}
}
break;
case AcSELECTPICKEDOBJECT://and deselect others
{
mitk::PositionEvent const *posEvent =
dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
if (posEvent == NULL) return false;
mitk::Point3D itkPoint;
itkPoint = posEvent->GetWorldPosition();
//search the point in the list
int position = pointSet->SearchPoint(itkPoint, 0.0, m_TimeStep);
//distance set to 0, cause we already got the exact point from last
//State checkpoint but we also need the position in the list to move it
if (position>=0)//found a point
{
//first deselect the other points
//undoable deselect of all points in the DataList
this->UnselectAll( m_TimeStep, timeInMS);
PointOperation* doOp = new mitk::PointOperation(OpSELECTPOINT,
timeInMS, itkPoint, position);
//Undo
if (m_UndoEnabled) //write to UndoMechanism
{
PointOperation* undoOp = new mitk::PointOperation(OpDESELECTPOINT,
timeInMS, itkPoint, position);
OperationEvent *operationEvent =
new OperationEvent(pointSet, doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
//execute the Operation
pointSet->ExecuteOperation(doOp);
if ( !m_UndoEnabled )
delete doOp;
ok = true;
}
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
}
case AcDESELECTOBJECT:
{
mitk::PositionEvent const *posEvent =
dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
if (posEvent == NULL)
return false;
mitk::Point3D itkPoint;
itkPoint = posEvent->GetWorldPosition();
//search the point in the list
int position = pointSet->SearchPoint(itkPoint, 0.0, m_TimeStep);
//distance set to 0, cause we already got the exact point from last
// State checkpoint but we also need the position in the list to move it
if (position>=0)//found a point
{
//Undo
PointOperation* doOp = new mitk::PointOperation(OpDESELECTPOINT,
timeInMS, itkPoint, position);
if (m_UndoEnabled) //write to UndoMechanism
{
PointOperation* undoOp = new mitk::PointOperation(OpSELECTPOINT,
timeInMS, itkPoint, position);
OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
//execute the Operation
pointSet->ExecuteOperation(doOp);
if ( !m_UndoEnabled )
delete doOp;
ok = true;
}
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
}
case AcDESELECTALL:
{
//undo-supported able deselect of all points in the DataList
this->UnselectAll( m_TimeStep, timeInMS );
ok = true;
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
}
case AcFINISHMOVEMENT:
{
mitk::PositionEvent const *posEvent =
dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
if (posEvent == NULL)
return false;
//finish the movement:
//the final point is m_LastPoint
//m_SumVec stores the movement in a vector
//the operation would not be necessary, but we need it for the undo Operation.
//m_LastPoint is for the Operation
//the point for undoOperation calculates from all selected
//elements (point) - m_SumVec
//search all selected elements and move them with undo-functionality.
mitk::PointSet::PointsIterator it, end;
it = points->Begin();
end = points->End();
while( it != end )
{
int position = it->Index();
if ( pointSet->GetSelectInfo(position, m_TimeStep) )//if selected
{
PointSet::PointType pt = pointSet->GetPoint(position, m_TimeStep);
Point3D itkPoint;
itkPoint[0] = pt[0];
itkPoint[1] = pt[1];
itkPoint[2] = pt[2];
PointOperation* doOp = new mitk::PointOperation(OpMOVE,
timeInMS, itkPoint, position);
if ( m_UndoEnabled )//&& (posEvent->GetType() == mitk::Type_MouseButtonRelease)
{
//set the undo-operation, so the final position is undo-able
//calculate the old Position from the already moved position - m_SumVec
mitk::Point3D undoPoint = ( itkPoint - m_SumVec );
PointOperation* undoOp =
new mitk::PointOperation(OpMOVE, timeInMS, undoPoint, position);
OperationEvent *operationEvent =
new OperationEvent(pointSet, doOp, undoOp, "Move point");
m_UndoController->SetOperationEvent(operationEvent);
}
//execute the Operation
pointSet->ExecuteOperation(doOp);
if ( !m_UndoEnabled )
delete doOp;
}
++it;
}
//set every variable for movement calculation to zero
// commented out: increases usebility in derived classes.
/*m_LastPoint.Fill(0);
m_SumVec.Fill(0);*/
//increase the GroupEventId, so that the Undo goes to here
this->IncCurrGroupEventId();
ok = true;
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
}
case AcCLEAR:
{
this->Clear( m_TimeStep, timeInMS );
// Update the display
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
break;
}
default:
return Superclass::ExecuteAction( action, stateEvent );
}
// indicate modification of data tree node
m_DataNode->Modified();
return ok;
}
void mitk::PointSetInteractor::Clear( unsigned int timeStep, ScalarType timeInMS )
{
mitk::Point3D point;
point.Fill(0);
mitk::PointSet *pointSet =
dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
if ( pointSet == NULL )
{
return;
}
mitk::PointSet::DataType *itkPointSet = pointSet->GetPointSet( timeStep );
if ( itkPointSet == NULL )
{
return;
}
//for reading on the points, Id's etc
mitk::PointSet::PointsContainer *points = itkPointSet->GetPoints();
mitk::PointSet::PointsIterator it, end;
it = points->Begin();
end = points->End();
while( (it != end) && (pointSet->GetSize( timeStep ) > 0) )
{
point = pointSet->GetPoint( it->Index(), timeStep );
PointOperation *doOp = new mitk::PointOperation(
OpREMOVE, timeInMS, point, it->Index());
//write to UndoMechanism
if ( m_UndoEnabled )
{
PointOperation *undoOp = new mitk::PointOperation(
OpINSERT, timeInMS, point, it->Index());
OperationEvent *operationEvent =
new OperationEvent( pointSet, doOp, undoOp );
m_UndoController->SetOperationEvent( operationEvent );
}
//execute the Operation
++it;
pointSet->ExecuteOperation( doOp );
if ( !m_UndoEnabled )
delete doOp;
}
//reset the statemachine
this->ResetStatemachineToStartState(timeStep);
}
void mitk::PointSetInteractor::InitAccordingToNumberOfPoints()
{
if (m_DataNode == NULL)
return;
mitk::PointSet *pointSet = dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
if ( pointSet != NULL )
{
//resize the CurrentStateVector
this->ExpandStartStateVector(pointSet->GetPointSetSeriesSize());
for (unsigned int timestep = 0; timestep < pointSet->GetPointSetSeriesSize(); timestep++)
{
//go to new timestep
this->UpdateTimeStep(timestep);
int numberOfPoints = pointSet->GetSize( timestep );
if (numberOfPoints == 0)
continue; //pointset is empty
else
{
//we have a set of loaded points. Deselect all points, because they are all set to selected when added!
this->UnselectAll(timestep);
if (numberOfPoints<m_N || m_N <= -1)//if less than specified or specified as unlimited
{
//get the currentState to state "SpaceLeft"
const mitk::Event* nullEvent = new mitk::Event(NULL, Type_User, BS_NoButton, BS_NoButton, Key_none);
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDSMALLERN, nullEvent);
this->HandleEvent( newStateEvent );
delete newStateEvent;
delete nullEvent;
}
else if (numberOfPoints>=m_N)
{
if (numberOfPoints>m_N)
{
STATEMACHINE_WARN<<"Point Set contains more points than needed!\n";//display a warning that there are too many points
}
//get the currentState to state "Set full"
const mitk::Event* nullEvent = new mitk::Event(NULL, Type_User, BS_NoButton, BS_NoButton, Key_none);
mitk::StateEvent* newStateEvent =
new mitk::StateEvent(EIDEQUALSN, nullEvent);
this->HandleEvent( newStateEvent );
delete newStateEvent;
delete nullEvent;
}
}
}
}
return;
}
void mitk::PointSetInteractor::DataChanged()
{
this->InitAccordingToNumberOfPoints();
return;
}
diff --git a/Core/Code/Interactions/mitkPointSetInteractor.h b/Core/Code/Interactions/mitkPointSetInteractor.h
index 371653e85b..8c564199d9 100644
--- a/Core/Code/Interactions/mitkPointSetInteractor.h
+++ b/Core/Code/Interactions/mitkPointSetInteractor.h
@@ -1,129 +1,128 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPOINTSETINTERACTOR_H_HEADER_INCLUDED_C11202FF
#define MITKPOINTSETINTERACTOR_H_HEADER_INCLUDED_C11202FF
#include <MitkExports.h>
#include "mitkVector.h"
#include <mitkInteractor.h>
namespace mitk
{
class DataNode;
/**
* \brief Interaction with a set of points.
*
* Points can be added, removed and moved.
* In case the interaction shall be done on a
* loaded set of points, the associated data
* object (mitkPointSet) needs to be loaded
* prior to the instanciation of this object.
* The number of points are checked and the internal
* statemachine set to the apropriate state.
* The management of 0 points is not supported.
* In this case, the amount of managed points is set to 1.
* \ingroup Interaction
*/
class MITK_CORE_EXPORT PointSetInteractor : public Interactor
{
public:
mitkClassMacro(PointSetInteractor, Interactor);
mitkNewMacro3Param(Self, const char*, DataNode*, int);
mitkNewMacro2Param(Self, const char*, DataNode*);
/**
* @brief Clears all the elements from the given timeStep in the list with undo-functionality and
* resets the statemachine
*/
void Clear( unsigned int timeStep = 0, ScalarType timeInMS = 0.0 );
itkGetMacro( Precision, unsigned int );
itkSetMacro( Precision, unsigned int );
/**
* \brief calculates how good the data, this statemachine handles, is hit
* by the event.
*
* overwritten, cause we don't look at the boundingbox, we look at each point
*/
virtual float CanHandleEvent(StateEvent const* stateEvent) const;
/**
*@brief If data changed then initialize according to numbers of loaded points
**/
virtual void DataChanged();
protected:
/**
* \brief Constructor with Param n for limited Set of Points
*
* If no n is set, then the number of points is unlimited
* n=0 is not supported. In this case, n is set to 1.
*/
PointSetInteractor(const char * type, DataNode* dataNode, int n = -1);
/**
* \brief Default Destructor
**/
virtual ~PointSetInteractor();
/**
* @brief Convert the given Actions to Operations and send to data and UndoController
*/
virtual bool ExecuteAction( Action* action, mitk::StateEvent const* stateEvent );
/** \brief Deselects the Points in the PointSet.
* supports Undo if enabled
*/
void UnselectAll( unsigned int timeStep = 0, ScalarType timeInMS = 0.0 );
/**
* \brief Selects the point.
* supports Undo if enabled.
* \param position Needed for declaring operations
*/
void SelectPoint( int position, unsigned int timeStep = 0, ScalarType timeInMS = 0.0 );
/** \brief to calculate a direction vector from last point and actual
* point
*/
Point3D m_LastPoint;
/** \brief summ-vector for Movement */
Vector3D m_SumVec;
/** \brief to store the value of precision to pick a point */
unsigned int m_Precision;
private:
/**
* \brief the number of possible points in this object
*
* if -1, then no limit set
*/
int m_N;
/**
* @brief Init the StatateMachine according to the current number of points in case of a loaded pointset.
**/
void InitAccordingToNumberOfPoints();
};
}
#endif /* MITKPOINTSETINTERACTOR_H_HEADER_INCLUDED_C11202FF */
diff --git a/Core/Code/Interactions/mitkPositionEvent.cpp b/Core/Code/Interactions/mitkPositionEvent.cpp
index b08666a7fd..1241020c6d 100644
--- a/Core/Code/Interactions/mitkPositionEvent.cpp
+++ b/Core/Code/Interactions/mitkPositionEvent.cpp
@@ -1,27 +1,26 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPositionEvent.h"
#include "mitkVector.h"
mitk::PositionEvent::PositionEvent(mitk::BaseRenderer* sender, int type, int button, int buttonState, int key, const mitk::Point2D& displPosition, const mitk::Point3D& worldPosition)
: DisplayPositionEvent(sender, type, button, buttonState, key, displPosition)
{
m_WorldPosition = worldPosition;
m_WorldPositionIsSet = true;
}
diff --git a/Core/Code/Interactions/mitkPositionEvent.h b/Core/Code/Interactions/mitkPositionEvent.h
index 19d08ef702..5e57cea3fc 100644
--- a/Core/Code/Interactions/mitkPositionEvent.h
+++ b/Core/Code/Interactions/mitkPositionEvent.h
@@ -1,51 +1,50 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 POSITIONEVENT_H_HEADER_INCLUDED_C184F366
#define POSITIONEVENT_H_HEADER_INCLUDED_C184F366
#include <MitkExports.h>
#include "mitkDisplayPositionEvent.h"
#include "mitkVector.h"
namespace mitk {
//##Documentation
//## @brief Event that stores coordinates
//##
//## Stores display position of the mouse and 3D world position in mm.
//## @ingroup Interaction
class MITK_CORE_EXPORT PositionEvent : public DisplayPositionEvent
{
public:
//##Documentation
//## @brief Constructor with all necessary arguments.
//##
//## @param sender: the widget, that caused that event, so that it can be asked for worldCoordinates. changed later to a focus
//## @param type, button, buttonState, key: information from the Event
//## @param displPosition: the 2D Position e.g. from the mouse
//## @param worldPosition: the 3D position e.g. from a picking
PositionEvent(BaseRenderer* sender, int type, int button, int buttonState, int key, const Point2D& displPosition, const Point3D& worldPosition);
};
} // namespace mitk
#endif /* POSITIONEVENT_H_HEADER_INCLUDED_C184F366 */
diff --git a/Core/Code/Interactions/mitkPositionTracker.cpp b/Core/Code/Interactions/mitkPositionTracker.cpp
index 41657b4d14..525653b7ce 100755
--- a/Core/Code/Interactions/mitkPositionTracker.cpp
+++ b/Core/Code/Interactions/mitkPositionTracker.cpp
@@ -1,85 +1,84 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include <mitkPositionTracker.h>
#include <mitkBaseRenderer.h>
#include <mitkDataStorage.h>
#include <mitkNodePredicateProperty.h>
#include <mitkDisplayPositionEvent.h>
#include <mitkAction.h>
#include <mitkStateEvent.h>
#include <mitkUndoController.h>
#include <mitkInteractionConst.h>
#include <mitkPointSet.h>
#include <mitkRenderingManager.h>
#include <mitkVector.h> // for PointDataType
#include <mitkProperties.h>
mitk::PositionTracker::PositionTracker(const char * type, mitk::OperationActor* /*operationActor*/)
: mitk::StateMachine(type)
{}
bool mitk::PositionTracker::ExecuteAction(Action* /*action*/, mitk::StateEvent const* stateEvent)
{
bool ok = false;
const DisplayPositionEvent* displayPositionEvent = dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
mitk::DataNode::Pointer dtnode;
mitk::DataStorage* ds = NULL;
if (displayPositionEvent == NULL)
return false;
if (stateEvent->GetEvent()->GetSender()!=NULL)
{
ds = stateEvent->GetEvent()->GetSender()->GetDataStorage();
}
else
{
itkWarningMacro(<<"StateEvent::GetSender()==NULL - setting timeInMS to 0");
return false;
}
if (ds == NULL)
return false;
// looking for desired point set
dtnode = ds->GetNode(mitk::NodePredicateProperty::New("inputdevice", mitk::BoolProperty::New(true)));
if (dtnode.IsNull())
return false;
dtnode->SetIntProperty("BaseRendererMapperID", stateEvent->GetEvent()->GetSender()->GetMapperID());
mitk::PointSet* ps = dynamic_cast<mitk::PointSet*>(dtnode->GetData());
if (ps == NULL)
return false;
int position = 0;
if( ps->GetPointSet()->GetPoints()->IndexExists( position )) //first element
{
ps->GetPointSet()->GetPoints()->SetElement( position, displayPositionEvent->GetWorldPosition());
}
else
{
mitk::PointSet::PointDataType pointData = {position , false /*selected*/, mitk::PTUNDEFINED};
ps->GetPointSet()->GetPointData()->InsertElement(position, pointData);
ps->GetPointSet()->GetPoints()->InsertElement(position, displayPositionEvent->GetWorldPosition());
}
ps->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return ok;
}
diff --git a/Core/Code/Interactions/mitkPositionTracker.h b/Core/Code/Interactions/mitkPositionTracker.h
index a796c89e5e..670e03056a 100755
--- a/Core/Code/Interactions/mitkPositionTracker.h
+++ b/Core/Code/Interactions/mitkPositionTracker.h
@@ -1,54 +1,53 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 MITKPositionTracker_H
#define MITKPositionTracker_H
#include <MitkExports.h>
#include "mitkStateMachine.h"
namespace mitk
{
class Operation;
class OperationActor;
//##Documentation
//## @brief Interactor for Mouse Tracking
//##
//## Tracks a Point from an input device (usaly mouse pointer)
//## @ingroup Interaction
class MITK_CORE_EXPORT PositionTracker : public StateMachine
{
public:
mitkClassMacro(PositionTracker, StateMachine);
mitkNewMacro2Param(Self, const char*, OperationActor*);
protected:
//##Documentation
//## @brief Constructor with needed arguments
//## @param type: string, that describes the StateMachine-Scheme to take from all SM (see XML-File)
//## @param operationActor: the Data, operations (+ points) are send to
PositionTracker(const char * type, OperationActor* operationActor);
//##Documentation
//## @brief executes the actions that are sent to this statemachine
//## derived from StateMachine
virtual bool ExecuteAction(Action* action, mitk::StateEvent const* stateEvent);
};
} // namespace mitk
#endif /* MITKPositionTracker_H */
diff --git a/Core/Code/Interactions/mitkState.cpp b/Core/Code/Interactions/mitkState.cpp
index cea1c927b2..cf936ab5f7 100755
--- a/Core/Code/Interactions/mitkState.cpp
+++ b/Core/Code/Interactions/mitkState.cpp
@@ -1,116 +1,115 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkState.h"
mitk::State::State(std::string stateName, int stateId)
: m_Name(stateName), m_Id(stateId)
{
}
mitk::State::~State()
{
//delete all transitions
while (!m_Transitions.empty())
{
//copy first
mitk::Transition* tempTransition = m_Transitions.begin()->second;
//deleting it from map
m_Transitions.erase(m_Transitions.begin());
//deleting transition
delete tempTransition;
}
}
bool mitk::State::AddTransition( Transition* transition )
{
std::pair<TransMapIter,bool> ok = m_Transitions.insert(TransitionMap::value_type( transition->GetEventId(), transition ));
return (bool) ok.second;
}
const mitk::Transition* mitk::State::GetTransition(int eventId) const
{
TransitionMap::const_iterator tempTrans = m_Transitions.find(eventId);
if( tempTrans != m_Transitions.end() )
return (*tempTrans).second;
else //can a Transition with ID 0 be found?
{
tempTrans = m_Transitions.find(0);
if ( tempTrans != m_Transitions.end() )//found transition 0 (= transmitt all events to other local StateMachines)
{
return (*tempTrans).second.GetPointer();
}
else
return NULL;
}
}
std::string mitk::State::GetName() const
{
return m_Name;
}
int mitk::State::GetId() const
{
return m_Id;
}
//##Documentation
//## gives all next States back. To parse through all States.
std::set<int> mitk::State::GetAllNextStates() const
{
std::set<int> tempset;
for (TransMapConstIter i= m_Transitions.begin(); i != m_Transitions.end(); i++)
{
tempset.insert( (i->second)->GetNextStateId() );
}
return tempset;
}
//##Documentation
//## to check, if this Event has a Transition.
//## for menu Behavior e.g.
bool mitk::State::IsValidEvent(int eventId) const
{
if( m_Transitions.find(eventId) != m_Transitions.end() )
return true;
else
return false;
}
//##Documentation
//## searches dedicated States of all Transitions and
//## sets *nextState of these Transitions.
//## allStates is a List of all build States of that StateMachine
bool mitk::State::ConnectTransitions(StateMap *allStates)
{
for (TransMapIter i= m_Transitions.begin(); i != m_Transitions.end(); i++)
{
StateMapIter sIter = allStates->find(((*i).second)->GetNextStateId());
if( sIter != allStates->end() )
((*i).second)->SetNextState((*sIter).second);
else
return false;//State not found!
}
return true;
}
diff --git a/Core/Code/Interactions/mitkState.h b/Core/Code/Interactions/mitkState.h
index d9dd25a159..1bd5a20881 100755
--- a/Core/Code/Interactions/mitkState.h
+++ b/Core/Code/Interactions/mitkState.h
@@ -1,134 +1,133 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 STATE_H_HEADER_INCLUDED_C19A8A5D
#define STATE_H_HEADER_INCLUDED_C19A8A5D
#include <MitkExports.h>
#include <string>
#include <map>
#include <set>
#include <itkObject.h>
#include <itkWeakPointer.h>
#include <itkObjectFactory.h>
#include "mitkTransition.h"
namespace mitk {
/**
* @brief represents one state with all its necessary information
*
* Name and ID are stored. Also methods for building up, connecting and
* parsing for well formed statemachines are present.
* This class holds a map of transitions to next States.
* @ingroup Interaction
**/
class MITK_CORE_EXPORT State : public itk::Object
{
public:
mitkClassMacro(State, itk::Object);
/**
* @brief static New method to use SmartPointer
**/
mitkNewMacro2Param(Self, std::string, int);
typedef std::map<int, mitk::State::Pointer> StateMap;
typedef std::map<int, itk::WeakPointer<mitk::Transition> > TransitionMap;
typedef StateMap::iterator StateMapIter;
typedef TransitionMap::iterator TransMapIter;
typedef TransitionMap::const_iterator TransMapConstIter;
/**
* @brief Add a transition to the map of transitions.
*
* Instances of all added transitions are freed in destructor of this class.
**/
bool AddTransition( Transition* transition );
/**
* @brief hashmap-lookup and returning the Transition. Returns NULL Pointer if not located
**/
const Transition* GetTransition(int eventId) const;
/**
* @brief Returns the name.
**/
std::string GetName() const;
/**
* @brief Returns the Id.
**/
int GetId() const;
/**
* @brief Returns a set of all next States. E.g. to parse through all States.
**/
std::set<int> GetAllNextStates() const;
/**
* @brief Check, if this event (eventId) leads to a state.
**/
bool IsValidEvent(int eventId) const;
/**
* @brief Searches dedicated States of all Transitions and sets *nextState of these Transitions.
* Required for this is a List of all build States of that StateMachine (allStates). This way the StateMachine can be build up.
**/
bool ConnectTransitions(StateMap* allStates);
protected:
/**
* @brief Default Constructor. Use ::New instead!
* Set the name and the Id of the state.
* Name is to maintain readability during debug and Id is to identify this state inside the StateMachinePattern
**/
State(std::string name, int id);
/**
* @brief Default Destructor
**/
~State();
private:
/**
* @brief Name of this State to support readability during debug
**/
std::string m_Name;
/**
* @brief Id of this State important for interaction mechanism in StateMachinePattern
*
* All states inside a StateMachinePattern (construct of several states connected with transitions and actions) have to have an own id with which it is identifyable.
**/
int m_Id;
/**
* @brief map of transitions that lead from this state to the next state
**/
TransitionMap m_Transitions;
};
} // namespace mitk
#endif /* STATE_H_HEADER_INCLUDED_C19A8A5D */
diff --git a/Core/Code/Interactions/mitkStateEvent.cpp b/Core/Code/Interactions/mitkStateEvent.cpp
index 8a5a17d6a6..3afc051ff5 100644
--- a/Core/Code/Interactions/mitkStateEvent.cpp
+++ b/Core/Code/Interactions/mitkStateEvent.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStateEvent.h"
#include "mitkEvent.h"
mitk::StateEvent::StateEvent(int id, Event const* event)
:m_Id(id), m_Event(event)
{
}
mitk::StateEvent::StateEvent()
:m_Id(0), m_Event(0)
{
}
mitk::StateEvent::~StateEvent()
{
}
void mitk::StateEvent::Set(int id, Event const* event)
{
m_Id = id;
m_Event = event;
}
int mitk::StateEvent::GetId() const
{
return m_Id;
}
mitk::Event const* mitk::StateEvent::GetEvent() const
{
return m_Event;
}
diff --git a/Core/Code/Interactions/mitkStateEvent.h b/Core/Code/Interactions/mitkStateEvent.h
index a9d5b18568..62051d3d2f 100644
--- a/Core/Code/Interactions/mitkStateEvent.h
+++ b/Core/Code/Interactions/mitkStateEvent.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 STATEEVENT_H_HEADER_INCLUDED_C188E5BF
#define STATEEVENT_H_HEADER_INCLUDED_C188E5BF
#include <MitkExports.h>
namespace mitk {
class Event;
//##Documentation
//## @brief Class holding an mitk-event and the mitk-event-number for a statechange
//##
//## Holds an event, with which a statechange of a statemachine shall be
//## done. iD represents the mitk-event-number, event all further necessary information like
//## the MousePosition or a key.
//## Not derived from event to hold only one object stateevent, pass it to the statemachines,
//## set the next event and reuse this object
//## @ingroup Interaction
class MITK_CORE_EXPORT StateEvent
{
public:
StateEvent();
//##Documentation
//## @brief Constructor
//## @param id: mitk internal EventID
//## @param event: the information about the appeared event
StateEvent(int id, Event const* event = 0 );
~StateEvent();
//##Documentation
//## @brief to set the params and reuse an object
void Set(int id, Event const* event);
int GetId() const;
mitk::Event const* GetEvent() const;
private:
int m_Id;
mitk::Event const* m_Event;
};
} // namespace mitk
#endif /* STATEEVENT_H_HEADER_INCLUDED_C188E5BF */
diff --git a/Core/Code/Interactions/mitkStateMachine.cpp b/Core/Code/Interactions/mitkStateMachine.cpp
index bbc70b4857..f9bdf67199 100644
--- a/Core/Code/Interactions/mitkStateMachine.cpp
+++ b/Core/Code/Interactions/mitkStateMachine.cpp
@@ -1,316 +1,315 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStateMachine.h"
#include "mitkStateTransitionOperation.h"
#include "mitkInteractionConst.h"
#include "mitkInteractor.h"
#include "mitkTransition.h"
#include "mitkOperationEvent.h"
#include "mitkStateEvent.h"
#include "mitkAction.h"
#include "mitkUndoController.h"
#include <itkMacro.h>
#include "mitkGlobalInteraction.h"
#include <mbilog.h>
/**
* @brief Constructor
* daclares a new StateMachine and connects
* it to a StateMachine of Type type;
* Also the undo mechanism is instanciated and enabled/disabled
**/
mitk::StateMachine::StateMachine(const char * type)
: m_UndoController(NULL), m_Type("")
{
if(type!=NULL) //no need to throw a warning here, because the statemachine yet here doesn't have to be set up.
{
m_Type = type;
//the statemachine doesn't know yet anything about the number of timesteps of the data. So we initialize it with one element.
this->InitializeStartStates(1);
}
if (!m_UndoController)
{
m_UndoController = new UndoController(UndoController::VERBOSE_LIMITEDLINEARUNDO);//switch to LLU or add LLU
/**
* here the Undo mechanism is enabled / disabled for all interactors.
**/
m_UndoEnabled = true;
}
m_TimeStep = 0;
}
mitk::StateMachine::~StateMachine()
{
//clean up map using deletes
for ( mitk::StateMachine::ActionFunctionsMapType::iterator iter = m_ActionFunctionsMap.begin();
iter != m_ActionFunctionsMap.end();
++iter )
{
delete iter->second;
}
delete m_UndoController;
}
std::string mitk::StateMachine::GetType() const
{
return m_Type;
}
const mitk::State* mitk::StateMachine::GetCurrentState(unsigned int timeStep) const
{
if (m_CurrentStateVector.size() > timeStep) //the size of the vector has to be one integer higher than the timeStep.
return m_CurrentStateVector[timeStep].GetPointer();
return NULL;
}
void mitk::StateMachine::ResetStatemachineToStartState(unsigned int timeStep)
{
mitk::State* startState = mitk::GlobalInteraction::GetInstance()->GetStartState((const char *)(&m_Type[0]));
if ( m_UndoEnabled ) //write to UndoMechanism if Undo is enabled
{
//UNDO for this statechange;
StateTransitionOperation* doOp = new StateTransitionOperation(OpSTATECHANGE, startState, timeStep);
StateTransitionOperation* undoOp = new StateTransitionOperation(OpSTATECHANGE, m_CurrentStateVector[timeStep], timeStep);
OperationEvent *operationEvent = new OperationEvent(((mitk::OperationActor*)(this)), doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
//can be done without calling this->ExecuteOperation()
m_CurrentStateVector[timeStep] = startState;
}
bool mitk::StateMachine::HandleEvent(StateEvent const* stateEvent)
{
if (stateEvent == NULL)
return false;
if (m_CurrentStateVector.empty())
{
STATEMACHINE_ERROR << "Error in mitkStateMachine.cpp: StateMachine not initialized!\n";
return false;//m_CurrentStateVector needs to be initialized!
}
if (m_TimeStep >= m_CurrentStateVector.size())
{
STATEMACHINE_ERROR << "Error in mitkStateMachine.cpp: StateMachine not initialized for this time step!\n";
return false;
}
if (m_CurrentStateVector[m_TimeStep].IsNull())
{
STATEMACHINE_ERROR << "Error in mitkStateMachine.cpp: StateMachine not initialized with the right temporal information!\n";
return false;//m_CurrentState needs to be initialized!
}
//get the Transition from m_CurrentState which waits for this EventId
const Transition *tempTransition = m_CurrentStateVector[m_TimeStep]->GetTransition(stateEvent->GetId());
if (tempTransition == NULL) //no transition in this state for that EventId
{
return false;
}
//get next State
State *tempNextState = tempTransition->GetNextState();
if (tempNextState == NULL) //wrong built up statemachine!
{
STATEMACHINE_ERROR << "Error in mitkStateMachine.cpp: StateMachinePattern not defined correctly!\n";
return false;
}
//and ActionId to execute later on
if ( m_CurrentStateVector[m_TimeStep]->GetId() != tempNextState->GetId() )//statechange only if there is a real statechange
{
if ( m_UndoEnabled ) //write to UndoMechanism if Undo is enabled
{
//UNDO for this statechange; since we directly change the state, we don't need the do-Operation in case m_UndoEnables == false
StateTransitionOperation* doOp = new StateTransitionOperation(OpSTATECHANGE, tempNextState, m_TimeStep);
StateTransitionOperation* undoOp = new StateTransitionOperation(OpSTATECHANGE, m_CurrentStateVector[m_TimeStep], m_TimeStep);
OperationEvent *operationEvent = new OperationEvent(((mitk::OperationActor*)(this)), doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
STATEMACHINE_DEBUG << "from " << m_CurrentStateVector[m_TimeStep]->GetId()
<< " " << m_CurrentStateVector[m_TimeStep]->GetName()
<< " to " << tempNextState->GetId() <<" "<<tempNextState->GetName();
//first following StateChange(or calling ExecuteOperation(tempNextStateOp)), then operation(action)
m_CurrentStateVector[m_TimeStep] = tempNextState;
}
mitk::Transition::ActionVectorIterator actionIdIterator = tempTransition->GetActionBeginIterator();
mitk::Transition::ActionVectorConstIterator actionIdIteratorEnd = tempTransition->GetActionEndIterator();
bool ok = true;
while ( actionIdIterator != actionIdIteratorEnd )
{
if ( !ExecuteAction(*actionIdIterator, stateEvent) )
{
ok = false;
}
actionIdIterator++;
}
return ok;
}
void mitk::StateMachine::EnableUndo(bool enable)
{
m_UndoEnabled = enable;
}
void mitk::StateMachine::IncCurrGroupEventId()
{
mitk::OperationEvent::IncCurrGroupEventId();
}
/// look up which object method is associated to the given action and call the method
bool mitk::StateMachine::ExecuteAction(Action* action, StateEvent const* stateEvent)
{
if (!action) return false;
int actionId = action->GetActionId();
TStateMachineFunctor* actionFunction = m_ActionFunctionsMap[actionId];
if (!actionFunction) return false;
bool retVal = actionFunction->DoAction(action, stateEvent);
return retVal;
}
void mitk::StateMachine::AddActionFunction(int action, mitk::TStateMachineFunctor* functor)
{
if (!functor) return;
// make sure double calls for same action won't cause memory leaks
delete m_ActionFunctionsMap[action]; // delete NULL does no harm
m_ActionFunctionsMap[action] = functor;
}
void mitk::StateMachine::ExecuteOperation(Operation* operation)
{
switch (operation->GetOperationType())
{
case OpNOTHING:
break;
case OpSTATECHANGE:
{
mitk::StateTransitionOperation* stateTransOp = dynamic_cast<mitk::StateTransitionOperation *>(operation);
if (stateTransOp == NULL)
{
STATEMACHINE_WARN<<"Error! see mitkStateMachine.cpp";
return;
}
unsigned int time = stateTransOp->GetTime();
m_CurrentStateVector[time] = stateTransOp->GetState();
}
break;
case OpTIMECHANGE:
{
mitk::StateTransitionOperation* stateTransOp = dynamic_cast<mitk::StateTransitionOperation *>(operation);
if (stateTransOp == NULL)
{
STATEMACHINE_WARN<<"Error! see mitkStateMachine.cpp";
return;
}
m_TimeStep = stateTransOp->GetTime();
}
break;
case OpDELETE:
{
//delete this!
//before all lower statemachines has to be deleted in a action
//this->Delete();//might not work!!!check itk!
}
case OpUNDELETE:
{
//now the m_CurrentState has to be set on a special State
//that way a delete of a StateMachine can be undone
//IMPORTANT: The type has to be the same!!!Done by a higher instance, that creates this!
mitk::StateTransitionOperation* stateTransOp = dynamic_cast<mitk::StateTransitionOperation *>(operation);
if (stateTransOp != NULL)
{
unsigned int time = stateTransOp->GetTime();
m_CurrentStateVector[time] = stateTransOp->GetState();
}
}
default:
;
}
}
void mitk::StateMachine::InitializeStartStates(unsigned int timeSteps)
{
//get the startstate of the pattern
State::Pointer startState = mitk::GlobalInteraction::GetInstance()->GetStartState(m_Type.c_str());
if (startState.IsNull())
{
STATEMACHINE_FATAL << "Fatal Error in mitkStateMachine.cpp: Initialization of statemachine unsuccessfull! Initialize GlobalInteraction!\n";
}
//clear the vector
m_CurrentStateVector.clear();
//add n=timesteps pointers pointing to to the startstate
for (unsigned int i = 0; i < timeSteps; i++)
m_CurrentStateVector.push_back(startState);
}
// Check if the vector is long enough to contain the new element
// at the given position. If not, expand it with sufficient pre-initialized
// elements.
//
// NOTE: This method will never REDUCE the vector size; it should only
// be used to make sure that the vector has enough elements to include the
// specified time step.
void mitk::StateMachine::ExpandStartStateVector(unsigned int timeSteps)
{
unsigned int oldSize = m_CurrentStateVector.size();
if ( timeSteps > oldSize )
{
State::Pointer startState = mitk::GlobalInteraction::GetInstance()->GetStartState(m_Type.c_str());
for ( unsigned int i = oldSize; i < timeSteps; ++i )
m_CurrentStateVector.insert(m_CurrentStateVector.end(), startState);
}
}
void mitk::StateMachine::UpdateTimeStep(unsigned int timeStep)
{
//don't need to fill up the memory if the time is uptodate
if (timeStep == m_TimeStep)
return;
//create an operation that changes the time and send it to undocontroller
StateTransitionOperation* doOp = new StateTransitionOperation(OpTIMECHANGE, NULL, timeStep);
if ( m_UndoEnabled ) //write to UndoMechanism if Undo is enabled
{
StateTransitionOperation* undoOp = new StateTransitionOperation(OpTIMECHANGE, NULL, m_TimeStep);
OperationEvent *operationEvent = new OperationEvent(((mitk::OperationActor*)(this)), doOp, undoOp);
m_UndoController->SetOperationEvent(operationEvent);
}
this->ExecuteOperation(doOp);
}
diff --git a/Core/Code/Interactions/mitkStateMachine.h b/Core/Code/Interactions/mitkStateMachine.h
index 3099c399b5..3816ecdfb6 100644
--- a/Core/Code/Interactions/mitkStateMachine.h
+++ b/Core/Code/Interactions/mitkStateMachine.h
@@ -1,292 +1,291 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 STATEMACHINE_H_HEADER_INCLUDED_C18896BD
#define STATEMACHINE_H_HEADER_INCLUDED_C18896BD
#include <MitkExports.h>
#include <itkObject.h>
#include "mitkOperationActor.h"
#include <string>
#include "mitkState.h"
#include "mitkUndoModel.h"
namespace mitk {
class Action;
class StateEvent;
class UndoController;
// base class of statem machine functors
class MITK_CORE_EXPORT TStateMachineFunctor
{
public:
virtual bool DoAction(Action*, const StateEvent*)=0; // call using function
virtual ~TStateMachineFunctor() {}
};
// the template functor for arbitrary StateMachine derivations
template <class T>
class TSpecificStateMachineFunctor : public TStateMachineFunctor
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
TSpecificStateMachineFunctor(T* object, bool(T::*memberFunctionPointer)(Action*, const StateEvent*))
:m_Object(object),
m_MemberFunctionPointer(memberFunctionPointer)
{
}
virtual ~TSpecificStateMachineFunctor() {} // virtual destructor
// override function "Call"
virtual bool DoAction(Action* action, const StateEvent* stateEvent)
{
return (*m_Object.*m_MemberFunctionPointer)(action, stateEvent); // execute member function
}
private:
T* m_Object; // pointer to object
bool (T::*m_MemberFunctionPointer)(Action*, const StateEvent*); // pointer to member function
};
/// Can be uses by derived classes of StateMachine to connect action IDs to methods
/// Assumes that there is a typedef Classname Self in classes that use this macro
#define CONNECT_ACTION(a, f) \
StateMachine::AddActionFunction(a, new TSpecificStateMachineFunctor<Self>(this, &Self::f));
#define STATEMACHINE_INFO MITK_INFO("StateMachine") << "[type: " << GetType() << "] "
#define STATEMACHINE_WARN MITK_WARN("StateMachine") << "[type: " << GetType() << "] "
#define STATEMACHINE_FATAL MITK_FATAL("StateMachine") << "[type: " << GetType() << "] "
#define STATEMACHINE_ERROR MITK_ERROR("StateMachine") << "[type: " << GetType() << "] "
#define STATEMACHINE_DEBUG MITK_DEBUG("StateMachine") << "[type: " << GetType() << "] "
/**
@brief Superior statemachine
@ingroup Interaction
Realizes the methods, that every statemachine has to have.
Undo can be enabled and disabled through EnableUndo.
To implement your own state machine, you have to derive a class from mitk::StateMachine and either
- override ExecuteAction()
or
- Write bool methods that take (Action*, const StateEvent*) as parameter and use the CONNECT_ACTION macro in your constructor
The second version is recommended, since it provides more structured code. The following piece of code demonstrates how to
use the CONNECT_ACTION macro. The important detail is to provide a <i>typedef classname Self</i>
\code
class LightSwitch : public StateMachine
{
public:
mitkClassMacro(LightSwitch, StateMachine); // this creates the Self typedef
LightSwitch(const char*);
bool DoSwitchOn(Action*, const StateEvent*);
bool DoSwitchOff(Action*, const StateEvent*);
}
LightSwitch::LightSwitch(const char* type)
:StateMachine(type)
{
// make sure that AcSWITCHON and AcSWITCHOFF are defined int constants somewhere (e.g. mitkInteractionConst.h)
CONNECT_ACTION( AcSWITCHON, DoSwitchOn );
CONNECT_ACTION( AcSWITCHOFF, DoSwitchOff );
}
bool LightSwitch::DoSwitchOn(Action*, const StateEvent*)
{
std::cout << "Enlightenment" << std::endl;
}
bool LightSwitch::DoSwitchOff(Action*, const StateEvent*)
{
std::cout << "Confusion" << std::endl;
}
\endcode
What CONNECT_ACTION does, is call StateMachine::AddActionFunction(...) to add some function pointer wrapping class (functor) to
a std::map of StateMachine. Whenever StateMachines ExecuteAction is called, StateMachine will lookup the desired Action in its
map and call the appropriate method in your derived class.
**/
class MITK_CORE_EXPORT StateMachine : public itk::Object, public mitk::OperationActor
{
public:
mitkClassMacro(StateMachine,itk::Object);
/**
* @brief New Macro with one parameter for creating this object with static New(..) method
**/
mitkNewMacro1Param(Self, const char*);
/**
* @brief Map to connect action IDs with method calls. Use AddActionFunction or (even better) the CONNECT_ACTION macro to fill the map.
**/
typedef std::map<int, TStateMachineFunctor*> ActionFunctionsMapType;
/**
* @brief Type for a vector of StartStatePointers
**/
typedef std::vector<State::Pointer> StartStateVectorType;
/**
* @brief Get the name and with this the type of the StateMachine
**/
std::string GetType() const;
/**
* @brief handles an Event accordingly to its current State
*
* Statechange with Undo functionality;
* EventMapper gives each event a new objectEventId
* and a StateMachine::ExecuteAction can descide weather it gets a
* new GroupEventId or not, depending on its state (e.g. finishedNewObject then new GroupEventId).
* Object- and group-EventId can also be accessed through static methods from OperationEvent
**/
virtual bool HandleEvent(StateEvent const* stateEvent);
/**
* @brief Enables or disabled Undo.
**/
void EnableUndo(bool enable);
/**
* @brief A statemachine is also an OperationActor due to the UndoMechanism.
*
* The statechange is done in ExecuteOperation, so that the statechange can be undone by UndoMechanism.
* Is set private here and in superclass it is set public, so UndoController
* can reach ist, but it can't be overwritten by a subclass
* *ATTENTION*: THIS METHOD SHOULD NOT BE CALLED FROM OTHER CLASSES DIRECTLY!
**/
virtual void ExecuteOperation(Operation* operation);
/**
* @brief Friend so that UndoModel can call ExecuteOperation for Undo.
**/
friend class UndoModel;
friend class GlobalInteraction;
protected:
/**
* @brief Default Constructor. Obsolete to instanciate it with this method! Use ::New(..) method instead. Set the "type" and with this the pattern of the StateMachine
**/
StateMachine(const char * type);
/**
* @brief Default Destructor
**/
~StateMachine();
/**
* @brief Adds the Function to ActionList.
**/
void AddActionFunction(int action, TStateMachineFunctor* functor);
/**
* @brief Method called in HandleEvent after Statechange.
*
* Each statechange has actions, which can be assigned by it's number.
* If you are developing a new statemachine, declare all your operations here and send them to Undo-Controller and to the Data.
* Object- and group-EventId can also be accessed through static methods from OperationEvent
**/
virtual bool ExecuteAction(Action* action, StateEvent const* stateEvent);
/**
* @brief returns the current state
**/
const State* GetCurrentState(unsigned int timeStep = 0) const;
/**
* @brief if true, then UndoFunctionality is enabled
*
* Default value is true;
**/
bool m_UndoEnabled;
/**
* @brief Friend protected function of OperationEvent; that way all StateMachines can set GroupEventId to be incremented!
**/
void IncCurrGroupEventId();
/**
* @brief holds an UndoController, that can be accessed from all StateMachines. For ExecuteAction
**/
UndoController* m_UndoController;
/**
* @brief Resets the current state from the given timeStep to the StartState with undo functionality! Use carefully!
* @param[in] timeStep If the statemachine has several timesteps to take care of, specify the according timestep
**/
void ResetStatemachineToStartState(unsigned int timeStep = 0);
/**
* @brief Check if the number of timeSteps is equal to the number of stored StartStates. Nothing is changed if the number is equal.
**/
void ExpandStartStateVector(unsigned int timeSteps);
/**
* @brief initializes m_CurrentStateVector
**/
void InitializeStartStates(unsigned int timeSteps);
/**
* @brief Update the TimeStep of the statemachine with undo-support if undo enabled
**/
virtual void UpdateTimeStep(unsigned int timeStep);
/**
* @brief Current TimeStep if the data which is to be interacted on, has more than 1 TimeStep
**/
unsigned int m_TimeStep;
private:
/**
* @brief The type of the StateMachine. This string specifies the StateMachinePattern that is loaded from the StateMachineFactory.
**/
std::string m_Type;
/**
* @brief Points to the current state.
**/
StartStateVectorType m_CurrentStateVector;
/**
* @brief Map of the added Functions
**/
ActionFunctionsMapType m_ActionFunctionsMap;
};
} // namespace mitk
#endif /* STATEMACHINE_H_HEADER_INCLUDED_C18896BD */
diff --git a/Core/Code/Interactions/mitkStateMachineFactory.cpp b/Core/Code/Interactions/mitkStateMachineFactory.cpp
index 324474cf03..75f009e09f 100755
--- a/Core/Code/Interactions/mitkStateMachineFactory.cpp
+++ b/Core/Code/Interactions/mitkStateMachineFactory.cpp
@@ -1,462 +1,461 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStateMachineFactory.h"
#include "mitkGlobalInteraction.h"
#include <vtkXMLDataElement.h>
#include <mitkProperties.h>
#include <mitkStringProperty.h>
#include <mitkConfig.h>
#include <mitkStandardFileLocations.h>
/**
* @brief This class builds up all the necessary structures for a statemachine.
* and stores one start-state for all built statemachines.
**/
//mitk::StateMachineFactory::StartStateMap mitk::StateMachineFactory::m_StartStates;
//mitk::StateMachineFactory::AllStateMachineMapType mitk::StateMachineFactory::m_AllStateMachineMap;
//std::string mitk::StateMachineFactory::s_LastLoadedBehavior;
//XML StateMachine
const std::string STYLE = "STYLE";
const std::string NAME = "NAME";
const std::string ID = "ID";
const std::string START_STATE = "START_STATE";
const std::string NEXT_STATE_ID = "NEXT_STATE_ID";
const std::string EVENT_ID = "EVENT_ID";
const std::string SIDE_EFFECT_ID = "SIDE_EFFECT_ID";
const std::string ISTRUE = "TRUE";
const std::string ISFALSE = "FALSE";
const std::string STATE_MACHINE = "stateMachine";
const std::string STATE = "state";
const std::string TRANSITION = "transition";
const std::string STATE_MACHINE_NAME = "stateMachine";
const std::string ACTION = "action";
const std::string BOOL_PARAMETER = "boolParameter";
const std::string INT_PARAMETER = "intParameter";
const std::string FLOAT_PARAMETER = "floatParameter";
const std::string DOUBLE_PARAMETER = "doubleParameter";
const std::string STRING_PARAMETER = "stringParameter";
const std::string VALUE = "VALUE";
#include <vtkObjectFactory.h>
namespace mitk
{
vtkStandardNewMacro(StateMachineFactory);
}
mitk::StateMachineFactory::StateMachineFactory()
: m_AktStateMachineName(""), m_SkipStateMachine(false)
{}
mitk::StateMachineFactory::~StateMachineFactory()
{
//free memory
while (!m_AllStateMachineMap.empty())
{
StateMachineMapType* temp = m_AllStateMachineMap.begin()->second;
m_AllStateMachineMap.erase(m_AllStateMachineMap.begin());
delete temp;
}
//should not be necessary due to SmartPointers
m_StartStates.clear();
//delete WeakPointer
if (m_AktTransition)
delete m_AktTransition;
}
/**
* @brief Returns NULL if no entry with string type is found.
**/
mitk::State* mitk::StateMachineFactory::GetStartState(const char * type)
{
StartStateMapIter tempState = m_StartStates.find(type);
if( tempState != m_StartStates.end() )
return (tempState)->second.GetPointer();
MITK_ERROR << "Error in StateMachineFactory: StartState for pattern \""<< type<< "\"not found! StateMachine might not work!\n";
return NULL;
}
/**
* @brief Loads the xml file filename and generates the necessary instances.
**/
bool mitk::StateMachineFactory::LoadBehavior(std::string fileName)
{
if ( fileName.empty() )
return false;
m_LastLoadedBehavior = fileName;
this->SetFileName(fileName.c_str());
return this->Parse();
}
/**
* @brief Loads the xml string and generates the necessary instances.
**/
bool mitk::StateMachineFactory::LoadBehaviorString(std::string xmlString)
{
if ( xmlString.empty() )
return false;
m_LastLoadedBehavior = "String";
return ( this->Parse(xmlString.c_str(), xmlString.length()) );
}
bool mitk::StateMachineFactory::LoadStandardBehavior()
{
std::string xmlFileName( mitk::StandardFileLocations::GetInstance()->FindFile("StateMachine.xml", "Core/Code/Interactions") );
if (!xmlFileName.empty())
return this->LoadBehavior(xmlFileName);
else
return false;
}
/**
* @brief Recursive method, that parses this brand of
* the stateMachine; if the history has the same
* size at the end, then the StateMachine is correct
**/
bool mitk::StateMachineFactory::RParse(mitk::State::StateMap* states, mitk::State::StateMapIter thisState, HistorySet *history)
{
history->insert((thisState->second)->GetId());//log our path //or thisState->first. but this seems safer
std::set<int> nextStatesSet = (thisState->second)->GetAllNextStates();
//remove loops in nextStatesSet;
//nether do we have to go there, nor will it clear a deadlock
std::set<int>::iterator position = nextStatesSet.find((thisState->second)->GetId());//look for the same state in nextStateSet
if (position != nextStatesSet.end())
{//found the same state we are in!
nextStatesSet.erase(position);//delete it, cause, we don't have to go there a second time!
}
//nextStatesSet is empty, so deadlock!
if ( nextStatesSet.empty() )
{
MITK_INFO<<std::endl<<"Warning! An inconsistent state or a dead end was produced. Check pattern "<< m_AktStateMachineName<<". Continuing anyway."<<std::endl;
return true;//but it is allowed as an end-state
}
bool ok = true;
//go through all Transitions of thisState and look if we have allready been in this state
for (std::set<int>::iterator i = nextStatesSet.begin(); i != nextStatesSet.end(); i++)
{
if ( history->find(*i) == history->end() )//if we haven't been in this nextstate
{
mitk::State::StateMapIter nextState = states->find(*i);//search the iterator for our nextState
if (nextState == states->end())
{
MITK_INFO<<std::endl<<"Didn't find a state in StateMap! Check pattern "<< m_AktStateMachineName<<"!"<<std::endl;
ok = false;
}
else
ok = RParse( states, nextState, history);//recusive path into the next state
}
}
return ok;
}
/**
* @brief sets the pointers in Transition (setNextState(..)) according to the extracted xml-file content
**/
bool mitk::StateMachineFactory::ConnectStates(mitk::State::StateMap *states)
{
if (states->size() > 1)//only one state; don't have to be parsed for deadlocks!
{
//parse all the given states an check for deadlock or not connected states
HistorySet *history = new HistorySet;
mitk::State::StateMapIter firstState = states->begin();
//parse through all the given states, log the parsed elements in history
bool ok = RParse( states, firstState, history);
if ( (states->size() == history->size()) && ok )
{
delete history;
}
else //ether !ok or sizeA!=sizeB
{
delete history;
MITK_INFO<<std::endl;
MITK_INFO<<"Warning: An unreachable state was produced! Please check pattern "<< m_AktStateMachineName<<" inside StateMachinePattern-File. Continuing anyway!"<<std::endl;
//return false;//better go on and build/ connect the states than quit
}
}
//connect all the states
for (mitk::State::StateMapIter tempState = states->begin(); tempState != states->end(); tempState++)
{
//searched through the States and Connects all Transitions
bool tempbool = ( ( tempState->second )->ConnectTransitions( states ) );
if ( tempbool == false )
{
MITK_INFO<<std::endl;
MITK_INFO<<"Warning: Connection of states was not successful in pattern "<< m_AktStateMachineName<<"!"<<std::endl;
return false;//abort!
}
}
return true;
}
void mitk::StateMachineFactory::StartElement (const char* elementName, const char **atts)
{
//skip the state machine pattern because the name was not unique!
if (m_SkipStateMachine)
return;
std::string name(elementName);
if ( name == STATE_MACHINE )
{
std::string tempStateMachineName = ReadXMLStringAttribut( NAME, atts );
if (m_AllStateMachineMap.find(tempStateMachineName) != m_AllStateMachineMap.end())
{
//warning: Statemachine tempStateMachineName already exists!
MITK_FATAL << "State machine pattern " << tempStateMachineName << " already exists! Skipping state machine pattern";
m_SkipStateMachine = true;
}
else //tempStateMachineName is unique, so add it
{
m_AktStateMachineName = tempStateMachineName;
m_AllStateMachineMap[ m_AktStateMachineName ] = new StateMachineMapType;
}
}
else if ( name == STATE )
{
std::string stateMachinName = ReadXMLStringAttribut( NAME, atts ) ;
int id = ReadXMLIntegerAttribut( ID, atts );
//create a new instance
m_AktState = mitk::State::New(stateMachinName , id);
// store all states to be able to access a specific state (for persistence)
StateMachineMapType* stateMachine = m_AllStateMachineMap[ m_AktStateMachineName ];
(*stateMachine)[id] = m_AktState;
std::pair<mitk::State::StateMapIter,bool> ok = m_AllStatesOfOneStateMachine.insert(mitk::State::StateMap::value_type(id , m_AktState));
if ( ok.second == false )
{
MITK_INFO<<std::endl;
MITK_INFO<<"Warning from StateMachineFactory: STATE_ID was not unique in pattern "<< m_AktStateMachineName<<"!"<<std::endl;
return; //STATE_ID was not unique or something else didn't work in insert! EXITS the process
}
if ( ReadXMLBooleanAttribut( START_STATE, atts ) )
m_StartStates.insert(StartStateMap::value_type(m_AktStateMachineName, m_AktState));
}
else if ( name == TRANSITION )
{
std::string transitionName = ReadXMLStringAttribut( NAME, atts ) ;
int nextStateId = ReadXMLIntegerAttribut( NEXT_STATE_ID, atts );
int eventId = ReadXMLIntegerAttribut( EVENT_ID, atts );
m_AktTransition = new Transition(transitionName, nextStateId, eventId);
if ( m_AktState )
m_AktState->AddTransition( m_AktTransition );
}
else if ( name == ACTION )
{
int actionId = ReadXMLIntegerAttribut( ID, atts );
m_AktAction = Action::New( actionId );
m_AktTransition->AddAction( m_AktAction );
}
else if ( name == BOOL_PARAMETER )
{
if ( !m_AktAction )
return;
bool value = ReadXMLBooleanAttribut( VALUE, atts );
std::string name = ReadXMLStringAttribut( NAME, atts );
m_AktAction->AddProperty( name.c_str(), BoolProperty::New( value ) );
}
else if ( name == INT_PARAMETER )
{
if ( !m_AktAction )
return;
int value = ReadXMLIntegerAttribut( VALUE, atts );
std::string name = ReadXMLStringAttribut( NAME, atts );
m_AktAction->AddProperty( name.c_str(), IntProperty::New( value ) );
}
else if ( name == FLOAT_PARAMETER )
{
if ( !m_AktAction )
return;
float value = ReadXMLIntegerAttribut( VALUE, atts );
std::string name = ReadXMLStringAttribut( NAME, atts );
m_AktAction->AddProperty( name.c_str(), FloatProperty::New( value ) );
}
else if ( name == DOUBLE_PARAMETER )
{
if ( !m_AktAction )
return;
double value = ReadXMLDoubleAttribut( VALUE, atts );
std::string name = ReadXMLStringAttribut( NAME, atts );
m_AktAction->AddProperty( name.c_str(), DoubleProperty::New( value ) );
}
else if ( name == STRING_PARAMETER )
{
if ( !m_AktAction )
return;
std::string value = ReadXMLStringAttribut( VALUE, atts );
std::string name = ReadXMLStringAttribut( NAME, atts );
m_AktAction->AddProperty( name.c_str(), StringProperty::New( value ) );
}
}
void mitk::StateMachineFactory::EndElement (const char* elementName)
{
//bool ok = true;
std::string name(elementName);
//skip the state machine pattern because the name was not unique!
if (m_SkipStateMachine && (name != STATE_MACHINE) )
return;
if ( name == STATE_MACHINE_NAME )
{
if (m_SkipStateMachine)
{
m_SkipStateMachine = false;
return;
}
/*ok =*/ ConnectStates(&m_AllStatesOfOneStateMachine);
m_AllStatesOfOneStateMachine.clear();
}
else if ( name == STATE_MACHINE )
{
//doesn't have to be done
}
else if ( name == TRANSITION )
{
m_AktTransition = NULL; //pointer stored in its state. memory will be freed in destructor of class state
}
else if ( name == ACTION )
{
m_AktAction = NULL;
}
else if ( name == STATE )
{
m_AktState = NULL;
}
}
std::string mitk::StateMachineFactory::ReadXMLStringAttribut( std::string name, const char** atts )
{
if(atts)
{
const char** attsIter = atts;
while(*attsIter)
{
if ( name == *attsIter )
{
attsIter++;
return *attsIter;
}
attsIter++;
attsIter++;
}
}
return std::string();
}
int mitk::StateMachineFactory::ReadXMLIntegerAttribut( std::string name, const char** atts )
{
std::string s = ReadXMLStringAttribut( name, atts );
return atoi( s.c_str() );
}
float mitk::StateMachineFactory::ReadXMLFloatAttribut( std::string name, const char** atts )
{
std::string s = ReadXMLStringAttribut( name, atts );
return (float) atof( s.c_str() );
}
double mitk::StateMachineFactory::ReadXMLDoubleAttribut( std::string name, const char** atts )
{
std::string s = ReadXMLStringAttribut( name, atts );
return atof( s.c_str() );
}
bool mitk::StateMachineFactory::ReadXMLBooleanAttribut( std::string name, const char** atts )
{
std::string s = ReadXMLStringAttribut( name, atts );
if ( s == ISTRUE )
return true;
else
return false;
}
mitk::State* mitk::StateMachineFactory::GetState( const char * type, int StateId )
{
//check if the state exists
AllStateMachineMapType::iterator i = m_AllStateMachineMap.find( type );
if ( i == m_AllStateMachineMap.end() )
return NULL;
//get the statemachine of the state
StateMachineMapType* sm = m_AllStateMachineMap[type];
//get the state from its statemachine
if ( sm != NULL )
return (*sm)[StateId].GetPointer();
else
return NULL;
}
bool mitk::StateMachineFactory::AddStateMachinePattern(const char * type, mitk::State* startState, mitk::StateMachineFactory::StateMachineMapType* allStatesOfStateMachine)
{
if (startState == NULL || allStatesOfStateMachine == NULL)
return false;
//check if the pattern has already been added
StartStateMapIter tempState = m_StartStates.find(type);
if( tempState != m_StartStates.end() )
{
MITK_WARN << "Pattern " << type << " has already been added!\n";
return false;
}
//add the start state
m_StartStates.insert(StartStateMap::value_type(type, startState));
//add all states of the new pattern to hold their references
m_AllStateMachineMap.insert(AllStateMachineMapType::value_type(type, allStatesOfStateMachine));
return true;
}
diff --git a/Core/Code/Interactions/mitkStateMachineFactory.h b/Core/Code/Interactions/mitkStateMachineFactory.h
index 991e5cea5a..f8db366336 100755
--- a/Core/Code/Interactions/mitkStateMachineFactory.h
+++ b/Core/Code/Interactions/mitkStateMachineFactory.h
@@ -1,228 +1,227 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD
#define STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD
#include <MitkExports.h>
#include "mitkState.h"
#include "mitkTransition.h"
#include "mitkAction.h"
#include <vtkXMLParser.h>
#include <iostream>
#include <set>
namespace mitk {
/**
*@brief builds up all specifiyed statemachines and hold them for later access
*
* According to the XML-File every different statemachine is build up. A new
* instance of a new StateMachine grabs a StartState of one certain
* state machine. Two instances of one kind of state machine share that
* state machine.
* During buildprocess at runtime each state machine is parsed for well formed style.
* Currently different interaction styles are not yet supported.
* To add individual state machine patterns, call LoadBehavior(...)
* and it will be parsed added to the internal list of patterns
*
* @ingroup Interaction
**/
class MITK_CORE_EXPORT StateMachineFactory : public vtkXMLParser
{
public:
static StateMachineFactory *New();
vtkTypeMacro(StateMachineFactory,vtkXMLParser);
/**
* @brief Typedef for all states that are defined as start-states
**/
typedef std::map<std::string, mitk::State::Pointer> StartStateMap;
typedef StartStateMap::iterator StartStateMapIter;
/**
* @brief Typedef to be used for parsing all states of one statemachine
**/
typedef std::set<int> HistorySet;
typedef HistorySet::iterator HistorySetIter;
/**
* @brief This type holds all states of one statemachine.
**/
typedef std::map<int,State::Pointer> StateMachineMapType;
/**
* @brief this type holds all states of all statemachines so that a specific state can be accessed for persistence
**/
typedef std::map<std::string, StateMachineMapType* > AllStateMachineMapType;
/**
* @brief Returns the StartState of the StateMachine with the name type;
*
* Returns NULL if no entry with name type is found.
* Here a Smartpointer is returned to ensure, that StateMachines are also considered during reference counting.
**/
State* GetStartState(const char* type);
/**
* @brief loads the xml file filename and generates the necessary instances
**/
bool LoadBehavior(std::string fileName);
/**
* @brief loads the xml string and generates the necessary instances
**/
bool LoadBehaviorString(std::string xmlString);
/**
* @brief Try to load standard behavior file "StateMachine.xml"
*
* Search strategy:
* \li try environment variable "MITKCONF" (path to "StateMachine.xml")
* \li try "./StateMachine.xml"
* \li try via source directory (using MITKROOT from cmake-created
* mitkConfig.h) "MITKROOT/Interactions/mitkBaseInteraction/StateMachine.xml"
**/
bool LoadStandardBehavior();
const std::string& GetLastLoadedBehavior()
{
return m_LastLoadedBehavior;
}
/**
* @brief Adds the given pattern to the internal list of patterns
*
* Method to support addition of externaly loaded patterns.
* Instances of states, transitions and actions are maintained within this class and freed on destruction.
* The states already have to be connected by transitions and actions and checked for errors.
* @params type name of the pattern to add. Will be used during initialization of a new interactor.
* @params startState the start state of this pattern.
* @params allStatesOfStateMachine a map of state ids and its states to hold their reference and delete them in destructor
**/
bool AddStateMachinePattern(const char * type, mitk::State* startState, StateMachineMapType* allStatesOfStateMachine);
/**
* brief To enable StateMachine to access states
**/
friend class StateMachine;
protected:
/**
* @brief Default Constructor
**/
StateMachineFactory();
/**
* @brief Default Destructor
**/
~StateMachineFactory();
/**
* @brief Derived from XMLReader
**/
void StartElement (const char* elementName, const char **atts);
/**
* @brief Derived from XMLReader
**/
void EndElement (const char* elementName);
private:
/**
* @brief Derived from XMLReader
**/
std::string ReadXMLStringAttribut( std::string name, const char** atts);
/**
* @brief Derived from XMLReader
**/
float ReadXMLFloatAttribut( std::string name, const char** atts );
/**
* @brief Derived from XMLReader
**/
double ReadXMLDoubleAttribut( std::string name, const char** atts );
/**
* @brief Derived from XMLReader
**/
int ReadXMLIntegerAttribut( std::string name, const char** atts );
/**
* @brief Derived from XMLReader
**/
bool ReadXMLBooleanAttribut( std::string name, const char** atts );
/**
* @brief Returns a Pointer to the desired state if found.
**/
mitk::State* GetState( const char* type, int StateId );
/**
* @brief Sets the pointers in Transition (setNextState(..)) according to the extracted xml-file content
**/
bool ConnectStates(mitk::State::StateMap* states);
/**
* @brief Recusive method, that parses this pattern of the stateMachine and returns true if correct
**/
bool RParse(mitk::State::StateMap* states, mitk::State::StateMapIter thisState, HistorySet *history);
/**
* @brief Holds all created States that are defined as StartState
**/
StartStateMap m_StartStates;
/**
* @brief Holds all States of one StateMachine to build up the pattern.
**/
mitk::State::StateMap m_AllStatesOfOneStateMachine;
/**
* @brief A pointer to a State to help building up the pattern
**/
State::Pointer m_AktState;
/**
* @brief A pointer to a Transition to help building up the pattern
**/
itk::WeakPointer<Transition> m_AktTransition;
/**
* @brief A pointer to an Action to help building up the pattern
**/
Action::Pointer m_AktAction;
/**
* @brief map to hold all statemachines to call GetState for friends
**/
AllStateMachineMapType m_AllStateMachineMap;
std::string m_LastLoadedBehavior;
std::string m_AktStateMachineName;
/**
* @brief Variable to skip a state machine pattern if the state machine name is not unique
**/
bool m_SkipStateMachine;
};
} // namespace mitk
#endif /* STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD */
diff --git a/Core/Code/Interactions/mitkTransition.cpp b/Core/Code/Interactions/mitkTransition.cpp
index f962b80d18..cf3215b260 100755
--- a/Core/Code/Interactions/mitkTransition.cpp
+++ b/Core/Code/Interactions/mitkTransition.cpp
@@ -1,83 +1,82 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTransition.h"
#include "mitkState.h"
mitk::Transition::Transition(std::string name, int nextStateId, int eventId )
: m_Name(name), m_NextState(NULL), m_NextStateId(nextStateId), m_EventId(eventId)
{}
mitk::Transition::~Transition()
{
//needed for correct reference counting of mitkState
m_NextState = NULL;
m_Actions.clear();
}
void mitk::Transition::AddAction( Action* action )
{
m_Actions.push_back( action );
}
std::string mitk::Transition::GetName() const
{
return m_Name;
}
mitk::State* mitk::Transition::GetNextState() const
{
return m_NextState.GetPointer();
}
int mitk::Transition::GetNextStateId() const
{
return m_NextStateId;
}
int mitk::Transition::GetEventId() const
{
return m_EventId;
}
unsigned int mitk::Transition::GetActionCount() const
{
return static_cast<unsigned int>(m_Actions.size());
}
mitk::Transition::ActionVectorIterator mitk::Transition::GetActionBeginIterator() const
{
return m_Actions.begin();
}
mitk::Transition::ActionVectorConstIterator mitk::Transition::GetActionEndIterator() const
{
return m_Actions.end();
}
bool mitk::Transition::IsEvent(int eventId) const
{
return (eventId == m_EventId);
}
void mitk::Transition::SetNextState(State* state)
{
m_NextState = state;
}
diff --git a/Core/Code/Interactions/mitkTransition.h b/Core/Code/Interactions/mitkTransition.h
index cec6b4ccac..b1e9cc37d9 100755
--- a/Core/Code/Interactions/mitkTransition.h
+++ b/Core/Code/Interactions/mitkTransition.h
@@ -1,141 +1,140 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 TRANSITION_H_HEADER_INCLUDED_C19AE06B
#define TRANSITION_H_HEADER_INCLUDED_C19AE06B
#include <MitkExports.h>
#include <string>
#include <vector>
#include <itkWeakPointer.h>
#include "mitkAction.h"
namespace mitk {
class State;
/**
* @brief Connection of two states
*
* A transition connects two states.
* Several actions are stored, that have to be executed after the statechange.
* @ingroup Interaction
**/
class MITK_CORE_EXPORT Transition
{
public:
typedef std::vector< mitk::Action::Pointer > ActionVectorType;
typedef ActionVectorType::iterator ActionVectorIterator;
typedef const ActionVectorIterator ActionVectorConstIterator;
/**
* @brief Add the action to this object.
**/
void AddAction( Action* action );
/**
* @brief Return the name of this object.
**/
std::string GetName() const;
/**
* @brief Get the next state of this object.
**/
State* GetNextState() const;
/**
* @brief Get the Id of the next state of this object.
**/
int GetNextStateId() const;
/**
* @brief Get the eventId of this object.
**/
int GetEventId() const;
/**
* @brief Get the number of actions.
**/
unsigned int GetActionCount() const;
/**
* @brief Get an interator on the first action in list.
**/
ActionVectorIterator GetActionBeginIterator() const;
/**
* @brief Get an interator behind the last action in list.
**/
ActionVectorConstIterator GetActionEndIterator() const;
/**
* @brief Returns true if the given eventId is equal to this eventId.
**/
bool IsEvent(int eventId) const;
/**
* @brief Set the next state of this object.
**/
void SetNextState(State* state);
/**
* @brief Default Constructor
* Sets the necessary informations name (to enhance readability during debug),
* nextStateId (the Id of the next state) and eventId (the Id of the event that causes the statechange).
**/
Transition(std::string name, int nextStateId, int eventId);
/**
* @brief Default Denstructor
**/
~Transition();
private:
/**
* @brief For better debugging and reading it stores the name of this.
**/
std::string m_Name;
/**
* @brief a Pointer to the next state of this object.
**/
itk::WeakPointer<mitk::State> m_NextState;
/**
* @brief The Id of the next state.
**/
int m_NextStateId;
/**
* @brief The eventId which is associated to this object.
**/
int m_EventId;
/**
* @brief The list of actions, that are executed if this transition is done.
**/
mutable std::vector<Action::Pointer> m_Actions;
};
} // namespace mitk
#endif /* TRANSITION_H_HEADER_INCLUDED_C19AE06B */
diff --git a/Core/Code/Interactions/mitkVtkEventAdapter.cpp b/Core/Code/Interactions/mitkVtkEventAdapter.cpp
index 774cdc6f12..c1bc2f94aa 100644
--- a/Core/Code/Interactions/mitkVtkEventAdapter.cpp
+++ b/Core/Code/Interactions/mitkVtkEventAdapter.cpp
@@ -1,208 +1,207 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-08-20 14:31:52 +0200 (Do, 20 Aug 2009) $
-Version: $Revision: 18670 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkEventAdapter.h"
#include <mitkInteractionConst.h>
#include <mitkWheelEvent.h>
#include "vtkCommand.h"
namespace mitk
{
std::map<BaseRenderer* ,int> VtkEventAdapter::buttonStateMap;
}
mitk::MouseEvent
mitk::VtkEventAdapter::AdaptMouseEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi)
{
mitk::Point2D p;
p[0] = rwi->GetEventPosition()[0];
p[1] = rwi->GetEventPosition()[1];
p[1] = rwi->GetSize()[1] - p[1]; // flip y axis
// http://doc.trolltech.com/4.6/qt.html#MouseButton-enum
int button = 0;
int type = 0;
int state = 0;
// vtkRenderWindowInteractor does not provide information about mouse buttons during
// mouse move events...
// some button action might be going on during mouse move events
// that needs to be temp. saved in our buttonStateMap
int tmpstate = 0;
if(buttonStateMap.find(sender) != buttonStateMap.end())
tmpstate = buttonStateMap.find(sender)->second;
if(tmpstate != 0 && vtkCommandEventId != vtkCommand::MouseMoveEvent)
buttonStateMap.erase(buttonStateMap.find(sender)); //press or release event with active map caching
switch(vtkCommandEventId)
{
case vtkCommand::MouseMoveEvent:
type = 5;
button = mitk::BS_NoButton;
if(tmpstate != 0)
{
state = tmpstate;
/*
// debug output
static char tmp;
sprintf(&tmp,"%d",tmpstate);
std::cout << tmp << std::endl;
*/
}
break;
case vtkCommand::LeftButtonReleaseEvent:
type = 3;
button = mitk::BS_LeftButton;
state = tmpstate;
buttonStateMap[sender] = (tmpstate - button);
break;
case vtkCommand::MiddleButtonReleaseEvent:
type = 3;
button = mitk::BS_MidButton;
state = tmpstate;
buttonStateMap[sender] = (tmpstate - button);
break;
case vtkCommand::RightButtonReleaseEvent:
type = 3;
button = mitk::BS_RightButton;
state = tmpstate;
buttonStateMap[sender] = (tmpstate - button);
break;
case vtkCommand::LeftButtonPressEvent:
type = 2;
button = mitk::BS_LeftButton;
tmpstate |= button;
buttonStateMap[sender] = tmpstate;
break;
case vtkCommand::MiddleButtonPressEvent:
type = 2;
button = mitk::BS_MidButton;
tmpstate |= button;
buttonStateMap[sender] = tmpstate;
break;
case vtkCommand::RightButtonPressEvent:
type = 2;
button = mitk::BS_RightButton;
tmpstate |= button;
buttonStateMap[sender] = tmpstate;
break;
}
if(rwi->GetShiftKey())
{
state |= mitk::BS_ShiftButton;
}
if(rwi->GetControlKey())
{
state |= mitk::BS_ControlButton;
}
if(rwi->GetAltKey())
{
state |= mitk::BS_AltButton;
}
mitk::MouseEvent mitkEvent(sender, type, button, state, mitk::Key_none, p);
return mitkEvent;
}
mitk::WheelEvent
//mitk::VtkEventAdapter::AdaptWheelEvent(mitk::BaseRenderer* sender, QWheelEvent* wheelEvent)
mitk::VtkEventAdapter::AdaptWheelEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi)
{
mitk::Point2D p;
p[0] = rwi->GetEventPosition()[0];
p[1] = rwi->GetEventPosition()[1];
// http://doc.trolltech.com/4.6/qt.html#MouseButton-enum
int button = 0;
int type = 0;
int state = 0;
int delta = 0;
switch(vtkCommandEventId)
{
case vtkCommand::MouseWheelForwardEvent:
type = 31; // wheel event, // see qcoreevent enum "type"
button = 0x00000000;
delta = +120; //http://doc.trolltech.com/3.3/qwheelevent.html#delta
break;
case vtkCommand::MouseWheelBackwardEvent:
type = 31; // wheel event, // see qcoreevent enum "type"
button = 0x00000000;
delta = -120; //http://doc.trolltech.com/3.3/qwheelevent.html#delta
break;
}
if(rwi->GetShiftKey())
state |= mitk::BS_ShiftButton;
if(rwi->GetControlKey())
state |= mitk::BS_ControlButton;
if(rwi->GetAltKey())
state |= mitk::BS_AltButton;
mitk::WheelEvent mitkEvent(sender, type, button,state, mitk::Key_none, p, delta);
return mitkEvent;
}
mitk::KeyEvent
//mitk::VtkEventAdapter::AdaptKeyEvent(mitk::BaseRenderer* sender, QKeyEvent* keyEvent, const QPoint& cp)
mitk::VtkEventAdapter::AdaptKeyEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi)
{
// TODO: is this viable?
int key = (int)rwi->GetKeyCode();
// Those keycodes changed in Qt 4
if (key >= 0x01000000 && key <= 0x01000060)
key -= (0x01000000 - 0x1000);
else if(key >= 0x01001120 && key <= 0x01001262)
key -= 0x01000000;
mitk::Point2D p;
p[0] = rwi->GetEventPosition()[0];
p[1] = rwi->GetEventPosition()[1];
int type = 0;
if(vtkCommandEventId == vtkCommand::KeyPressEvent)
type = 6; // http://doc.trolltech.com/4.6/qevent.html#Type-enum
int state = 0;
if(rwi->GetShiftKey())
state |= mitk::BS_ShiftButton;
if(rwi->GetControlKey())
state |= mitk::BS_ControlButton;
if(rwi->GetAltKey())
state |= mitk::BS_AltButton;
mitk::KeyEvent mke(sender, type, mitk::BS_NoButton, state, key, std::string(rwi->GetKeySym()), p);
return mke;
}
diff --git a/Core/Code/Interactions/mitkVtkEventAdapter.h b/Core/Code/Interactions/mitkVtkEventAdapter.h
index c2f2099d40..8d07c2dfe8 100644
--- a/Core/Code/Interactions/mitkVtkEventAdapter.h
+++ b/Core/Code/Interactions/mitkVtkEventAdapter.h
@@ -1,52 +1,51 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-08-20 14:31:52 +0200 (Do, 20 Aug 2009) $
-Version: $Revision: 18670 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKVTKEVENTADAPTER_H_
#define MITKVTKEVENTADAPTER_H_
#include <mitkKeyEvent.h>
#include <mitkWheelEvent.h>
#include <mitkDisplayPositionEvent.h>
#include "vtkRenderWindowInteractor.h"
//##Documentation
//## @brief Generates MITK events from VTK
//##
//## This class is the NON-QT dependent pandon to QmitkEventAdapter.
//## It provides static functions to set up MITK events from VTK source data
//## @ingroup Interaction
namespace mitk
{
class BaseRenderer;
class MITK_EXPORT VtkEventAdapter
{
public:
static mitk::MouseEvent AdaptMouseEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi);
static mitk::WheelEvent AdaptWheelEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi);
static mitk::KeyEvent AdaptKeyEvent(mitk::BaseRenderer* sender, unsigned long vtkCommandEventId,vtkRenderWindowInteractor* rwi);
static std::map<BaseRenderer* ,int> buttonStateMap;
};
}
#endif /*QMITKEVENTADAPTER_H_*/
diff --git a/Core/Code/Interactions/mitkVtkInteractorStyle.cxx b/Core/Code/Interactions/mitkVtkInteractorStyle.cxx
index 54d0fc34b6..a3f980482c 100644
--- a/Core/Code/Interactions/mitkVtkInteractorStyle.cxx
+++ b/Core/Code/Interactions/mitkVtkInteractorStyle.cxx
@@ -1,51 +1,50 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-07-22 16:41:18 +0200 (Fr, 17 Aug 2007) $
-Version: $Revision: 11618 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkInteractorStyle.h"
#include <vtkObjectFactory.h>
#include <vtkCommand.h>
vtkCxxRevisionMacro(mitkVtkInteractorStyle, "$Revision: 1.35 $");
vtkStandardNewMacro(mitkVtkInteractorStyle);
mitkVtkInteractorStyle::mitkVtkInteractorStyle()
: vtkInteractorStyleUser()
{
}
mitkVtkInteractorStyle::~mitkVtkInteractorStyle()
{
}
void mitkVtkInteractorStyle::OnMouseWheelForward()
{
if (this->HasObserver(vtkCommand::MouseWheelForwardEvent))
{
this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
}
}
void mitkVtkInteractorStyle::OnMouseWheelBackward()
{
if (this->HasObserver(vtkCommand::MouseWheelBackwardEvent))
{
this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
}
}
diff --git a/Core/Code/Interactions/mitkVtkInteractorStyle.h b/Core/Code/Interactions/mitkVtkInteractorStyle.h
index 9cba9d82ee..c64236f3b9 100644
--- a/Core/Code/Interactions/mitkVtkInteractorStyle.h
+++ b/Core/Code/Interactions/mitkVtkInteractorStyle.h
@@ -1,65 +1,64 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-07-22 16:41:18 +0200 (Fr, 17 Aug 2007) $
-Version: $Revision: 11618 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
/**
* \brief Implements the handling of events that are missing for MITK interaction.
*
* This class inherits from vtkInteractorStyleUser, a class that handles
* VTK-Events and invokes callbacks by means of an observer pattern.
*
* Most event-types needed for typical MITK interaction have already
* been implemented in vtkInteractorStyleUser (Mouse-Buttons + Keyboard).
* However, wheel-events and widgetModifed-events (whatever these are)
* have not been handled so far. This is the purpose of this class.
*/
#ifndef __mitkVtkInteractorStyle_h
#define __mitkVtkInteractorStyle_h
#include "MitkExports.h"
#include <vtkInteractorStyleUser.h>
class MITK_CORE_EXPORT mitkVtkInteractorStyle : public vtkInteractorStyleUser
{
public:
// default VTK c'tor
static mitkVtkInteractorStyle *New();
vtkTypeRevisionMacro(mitkVtkInteractorStyle,vtkInteractorStyleUser);
/**
* \brief Called when scrolling forwards with the mouse-wheel.
*/
virtual void OnMouseWheelForward();
/**
* \brief Called when scrolling backwards with the mouse-wheel.
*/
virtual void OnMouseWheelBackward();
protected:
mitkVtkInteractorStyle();
~mitkVtkInteractorStyle();
private:
mitkVtkInteractorStyle(const mitkVtkInteractorStyle&); // Not implemented.
void operator=(const mitkVtkInteractorStyle&); // Not implemented.
};
#endif
diff --git a/Core/Code/Interactions/mitkWheelEvent.cpp b/Core/Code/Interactions/mitkWheelEvent.cpp
index b514e043e0..c22d7ed12c 100644
--- a/Core/Code/Interactions/mitkWheelEvent.cpp
+++ b/Core/Code/Interactions/mitkWheelEvent.cpp
@@ -1,32 +1,31 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
-Version: $Revision: 17179 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkWheelEvent.h"
#include "mitkVector.h"
mitk::WheelEvent::WheelEvent(mitk::BaseRenderer* sender, int type, int button, int buttonState, int key, const mitk::Point2D& displPosition, int delta)
: DisplayPositionEvent(sender, type, button, buttonState, key, displPosition)
{
//m_WorldPosition = worldPosition;
//m_WorldPositionIsSet = true;
m_Delta = delta;
}
int mitk::WheelEvent::GetDelta() const
{
return m_Delta;
}
diff --git a/Core/Code/Interactions/mitkWheelEvent.h b/Core/Code/Interactions/mitkWheelEvent.h
index a4fb989bf7..104e348aaf 100644
--- a/Core/Code/Interactions/mitkWheelEvent.h
+++ b/Core/Code/Interactions/mitkWheelEvent.h
@@ -1,56 +1,55 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
-Version: $Revision: 17179 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 WheelEvent_H_HEADER_INCLUDED_C184F366
#define WheelEvent_H_HEADER_INCLUDED_C184F366
#include <MitkExports.h>
#include "mitkDisplayPositionEvent.h"
#include "mitkVector.h"
namespace mitk {
//##Documentation
//## @brief Event that stores coordinates and rotation on mouse wheel events
//##
//## Stores display position of the mouse and 3D world position in mm.
//## @ingroup Interaction
class MITK_CORE_EXPORT WheelEvent : public DisplayPositionEvent
{
public:
//##Documentation
//## @brief Constructor with all necessary arguments.
//##
//## @param sender: the widget, that caused that event, so that it can be asked for worldCoordinates. changed later to a focus
//## @param type, button, buttonState, key: information from the Event
//## @param displPosition: the 2D Position e.g. from the mouse
//## @param worldPosition: the 3D position e.g. from a picking
//## @param delta: the movement of the mousewheel
WheelEvent(BaseRenderer* sender, int type, int button, int buttonState, int key, const Point2D& displPosition, int delta);
int GetDelta() const;
protected:
int m_Delta;
};
} // namespace mitk
#endif /* WheelEvent_H_HEADER_INCLUDED_C184F366 */
diff --git a/Core/Code/Interfaces/mitkIDataNodeReader.h b/Core/Code/Interfaces/mitkIDataNodeReader.h
index 53dc864b15..bd52977710 100644
--- a/Core/Code/Interfaces/mitkIDataNodeReader.h
+++ b/Core/Code/Interfaces/mitkIDataNodeReader.h
@@ -1,59 +1,58 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKIDATANODEREADER_H
#define MITKIDATANODEREADER_H
#include <mitkDataNode.h>
#include <mitkServiceInterface.h>
namespace mitk {
class DataStorage;
/**
* \ingroup MicroServices_Interfaces
*
* This interface provides methods to load data from the local filesystem
* into a given mitk::DataStorage.
*/
struct IDataNodeReader
{
virtual ~IDataNodeReader() {}
/**
* Reads the local file given by <code>fileName</code> and constructs one or more
* mitk::DataNode instances which are added to the given mitk::DataStorage <code>storage</code>.
*
* \param fileName The absolute path to a local file.
* \param storage The mitk::DataStorage which will contain the constructed data nodes.
* \return The number of constructed mitk::DataNode instances.
*
* \note Errors during reading the file or constructing the data node should be expressed by
* throwing appropriate exceptions.
*
* \see mitk::DataNodeFactory
*/
virtual int Read(const std::string& fileName, mitk::DataStorage& storage) = 0;
};
}
US_DECLARE_SERVICE_INTERFACE(mitk::IDataNodeReader, "org.mitk.IDataNodeReader")
#endif // MITKIDATANODEREADER_H
diff --git a/Core/Code/Rendering/mbilogo.h b/Core/Code/Rendering/mbilogo.h
index 5299a49f72..57ffa7fa9b 100644
--- a/Core/Code/Rendering/mbilogo.h
+++ b/Core/Code/Rendering/mbilogo.h
@@ -1,8437 +1,8436 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-06-27 12:01:21 +0200 (Mi, 27 Jun 2007) $
-Version: $Revision: 10984 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/ for details.
+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 the above copyright notices for more information.
+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 _mbilogo_1804289383
#define _mbilogo_1804289383
/**
* This file includes a simple logo of the department
* Medical and Biological Informatics at the DKFZ
* into MITK
*
* NOTE: the logo is created by the QT qembed tool,
* and thus it is upside down.
*/
static const unsigned int mbiLogo_NumberOfScalars = 4;
static const unsigned int mbiLogo_Width = 420;
static const unsigned int mbiLogo_Height = 280;
static const unsigned int mbiLogo_Data[] = {
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x130047b9,0x310047b9,0x550047b9,
0x5f0047b9,0x7c0047b9,0x8f0047b9,0x9c0047b9,0x970047b9,0x950047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x950047b9,0x970047b9,
0x9c0047b9,0x920047b9,0x8c0047b9,0x550047b9,0x110047b9,0x0,0x0,0xa0047b9,0x300047b9,0x660047b9,0x8b0047b9,0xa50047b9,0x970047b9,0x950047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x950047b9,0x980047b9,0xac0047b9,0x820047b9,
0x410047b9,0xb0047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x640047b9,0x9f0047b9,0x950047b9,0x990047b9,0x970047b9,0x950047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x950047b9,0x970047b9,0xa30047b9,0x8c0047b9,0x6c0047b9,0x340047b9,0xc0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x180047b9,0x7a0047b9,0xb40047b9,0x9b0047b9,0x940047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x950047b9,0x980047b9,0xac0047b9,0x820047b9,0x410047b9,0xb0047b9,0x40047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0047b9,0x340047b9,0x6b0047b9,
0x8c0047b9,0xa40047b9,0x970047b9,0x950047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,0x960047b9,
0x950047b9,0x980047b9,0xac0047b9,0x820047b9,0x410047b9,0xb0047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x10047b9,0x330047b9,0x5d0047b9,0xa60047b9,
0xd70047b9,0xf70047b9,0xea0047b9,0xe50047b9,0xe60047b9,0xe60047b9,0xe60047b9,0xe80047b9,0xf50047b9,0xdb0047b9,0xb70047b9,0x760047b9,0x4b0047b9,0x130047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x60047b9,0x100047b9,0x150047b9,0x1d0047b9,0x1e0047b9,0x230047b9,0x280047b9,0x410047b9,0x580047b9,0x740047b9,
0x7a0047b9,0x920047b9,0xa10047b9,0xab0047b9,0xa60047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa60047b9,
0xab0047b9,0xa20047b9,0x9e0047b9,0x5e0047b9,0x120047b9,0x0,0x0,0xa0047b9,0x340047b9,0x720047b9,0x9b0047b9,0xb30047b9,0xa70047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa80047b9,0xba0047b9,0x930047b9,
0x470047b9,0xa0047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x10047b9,0x70047b9,0x300047b9,0x7d0047b9,0xae0047b9,0xa50047b9,0xa90047b9,0xa70047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa40047b9,0xa90047b9,0xba0047b9,0x980047b9,0x5f0047b9,0x250047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x190047b9,0x8b0047b9,0xc30047b9,0xab0047b9,0xa40047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa80047b9,0xba0047b9,0x930047b9,0x470047b9,0xa0047b9,0x50047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,0x250047b9,0x630047b9,
0x9a0047b9,0xb90047b9,0xa80047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,0xa50047b9,
0xa50047b9,0xa80047b9,0xba0047b9,0x930047b9,0x470047b9,0xa0047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x130047b9,0x240047b9,0x2f0047b9,0x5a0047b9,0x790047b9,0xb30047b9,
0xd80047b9,0xf20047b9,0xe60047b9,0xe40047b9,0xe50047b9,0xe50047b9,0xe40047b9,0xe50047b9,0xf00047b9,0xdd0047b9,0xc00047b9,0x8d0047b9,0x6b0047b9,0x3f0047b9,
0x260047b9,0x120047b9,0x90047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x120047b9,0x4b0047b9,0x6a0047b9,0x980047b9,0xa50047b9,0xc30047b9,0xd50047b9,0xdf0047b9,0xe20047b9,0xe80047b9,
0xe80047b9,0xec0047b9,0xef0047b9,0xf20047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf40047b9,0xe80047b9,0xdf0047b9,0x870047b9,0x180047b9,0x0,0x0,0xe0047b9,0x4b0047b9,0xa30047b9,0xde0047b9,0xf80047b9,0xef0047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf10047b9,0xfb0047b9,0xd40047b9,
0x660047b9,0xc0047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x420047b9,0xa50047b9,0xda0047b9,0xf50047b9,0xf10047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xef0047b9,0xf70047b9,0xff0047b9,0xd00047b9,0x480047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x230047b9,0xc80047b9,0xff0047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf10047b9,0xfb0047b9,0xd40047b9,0x660047b9,0xc0047b9,0x60047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x5c0047b9,
0xdb0047b9,0xff0047b9,0xf30047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,0xf00047b9,
0xf00047b9,0xf10047b9,0xfb0047b9,0xd40047b9,0x660047b9,0xc0047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1d0047b9,0x6b0047b9,0xb90047b9,0xd40047b9,0xe50047b9,0xe80047b9,0xf20047b9,
0xf70047b9,0xfa0047b9,0xf90047b9,0xf80047b9,0xf80047b9,0xf80047b9,0xf80047b9,0xf90047b9,0xfa0047b9,0xf70047b9,0xf60047b9,0xec0047b9,0xe80047b9,0xd40047b9,
0xb70047b9,0x6e0047b9,0x2f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x110047b9,
0x120047b9,0x1f0047b9,0x230047b9,0x4e0047b9,0x710047b9,0xad0047b9,0xcc0047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0x9e0047b9,0x1d0047b9,0x0,0x0,0x120047b9,0x590047b9,0xc10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,
0x7a0047b9,0xe0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x10047b9,0x30047b9,0x370047b9,0x9f0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x9f0047b9,0x230047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x2b0047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0x7a0047b9,0xe0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0047b9,
0xc40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0x7a0047b9,0xe0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x10047b9,0x1a0047b9,0x360047b9,0x820047b9,0xcc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd00047b9,0x920047b9,0x470047b9,0x210047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0047b9,0x4d0047b9,
0x650047b9,0x9d0047b9,0xcb0047b9,0xe20047b9,0xe60047b9,0xf00047b9,0xf50047b9,0xfa0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfc0047b9,0xf60047b9,0x920047b9,0x1b0047b9,0x0,0x0,0xf0047b9,0x520047b9,0xb20047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,
0x700047b9,0xc0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x330047b9,0x930047b9,0xdb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x910047b9,0x240047b9,0x80047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x700047b9,0xc0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,
0x6a0047b9,0xd10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x700047b9,0xc0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x100047b9,0x700047b9,0xc00047b9,0xee0047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xfe0047b9,0xf60047b9,0xf00047b9,0xc90047b9,0x810047b9,0x210047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x110047b9,0x180047b9,0x390047b9,0x6e0047b9,0xaf0047b9,
0xc50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf10047b9,0x900047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xaf0047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x2a0047b9,0x8d0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xfa0047b9,0xa00047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x170047b9,0x720047b9,0xdc0047b9,0xfe0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x20047b9,0x90047b9,0x2f0047b9,0x6f0047b9,0xd00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,0x7e0047b9,0x360047b9,0x60047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x590047b9,0x960047b9,0xd70047b9,0xe20047b9,0xf10047b9,
0xf30047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x10047b9,0x610047b9,0xce0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0x9f0047b9,0x340047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x340047b9,0xbe0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x440047b9,0xa20047b9,0xd60047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xd90047b9,0xa40047b9,0x420047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x70047b9,0x140047b9,0x340047b9,0x640047b9,0xbb0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x10047b9,0x200047b9,
0x5a0047b9,0xbe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,
0xfa0047b9,0xbe0047b9,0x3d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x640047b9,0xd40047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,
0x0,0x2d0047b9,0x9c0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x9e0047b9,0x350047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x210047b9,0x7c0047b9,0xcd0047b9,0xdf0047b9,0xf20047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x70047b9,0x5f0047b9,
0xc40047b9,0xf90047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xbf0047b9,0x590047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x30047b9,0x160047b9,0x870047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,
0x70047b9,0x620047b9,0xd20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x820047b9,0x240047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x60047b9,0x1c0047b9,0x310047b9,0x840047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x150047b9,0x540047b9,0xc10047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xce0047b9,
0x600047b9,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x350047b9,0xc40047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x140047b9,
0x550047b9,0xbe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x7d0047b9,0x1d0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x210047b9,0x810047b9,0xc30047b9,0xed0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2a0047b9,0xa70047b9,0xff0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8d0047b9,
0x2a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1d0047b9,0x7d0047b9,0xdb0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x230047b9,
0xa70047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xc40047b9,0x350047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x80047b9,0x360047b9,0x7e0047b9,0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x250047b9,0x8b0047b9,0xf80047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xdc0047b9,0x930047b9,0x330047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x230047b9,0x840047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x30047b9,0x10047b9,0x6e0047b9,
0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x870047b9,0x170047b9,0x40047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x3e0047b9,0xa50047b9,0xd90047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2b0047b9,0x9f0047b9,0xf60047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfc0047b9,0x9f0047b9,0x370047b9,0x30047b9,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x20047b9,0x0,0x3f0047b9,0xdf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0xa0047b9,0x450047b9,0xaf0047b9,
0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xd40047b9,0x670047b9,0xe0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0xe0047b9,0x460047b9,
0xa00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x1e0047b9,0x8b0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0xa60047b9,0x410047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x880047b9,0xfc0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x1f0047b9,0x9c0047b9,0xf50047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xbb0047b9,0x270047b9,0x10047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x720047b9,0xda0047b9,
0xe90047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x750047b9,0xe20047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd40047b9,0x430047b9,0x20047b9,0x10047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x50047b9,0x2f0047b9,0x9f0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x230047b9,0xc90047b9,0xff0047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xd10047b9,0x300047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x20047b9,0x430047b9,0xd40047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0x90047b9,0x610047b9,0xd40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xde0047b9,0x700047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x3f0047b9,0xc90047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x30047b9,0x0,0x510047b9,0xf30047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0x5c0047b9,0x250047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x410047b9,0xa60047b9,0xea0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x30047b9,0x730047b9,0xdb0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd40047b9,0x610047b9,0x90047b9,0x10047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x230047b9,0x8d0047b9,0xe50047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x80047b9,0x1a0047b9,0x770047b9,0xe90047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x7c0047b9,0x4a0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x350047b9,0x9f0047b9,0xfc0047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x10047b9,0x30047b9,0x5a0047b9,0xd60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xe20047b9,0x750047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x310047b9,0x980047b9,0xee0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0xe0047b9,0x420047b9,0xa60047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xb00047b9,0x800047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x240047b9,0x820047b9,0xda0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x4e0047b9,0xbc0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8b0047b9,0x1e0047b9,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x580047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0xd0047b9,0x4f0047b9,0xb00047b9,0xf10047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xc80047b9,0x9a0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1d0047b9,0x7d0047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x20047b9,0x40047b9,0x3d0047b9,0xb00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf60047b9,0x9f0047b9,0x2b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x150047b9,0xa10047b9,0xfd0047b9,0xfd0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x140047b9,0x720047b9,0xd10047b9,0xf60047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xe40047b9,0xb70047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x350047b9,0xc40047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x410047b9,0xa60047b9,0xe10047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8f0047b9,0x220047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x430047b9,0xad0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x180047b9,0x8a0047b9,0xeb0047b9,0xf80047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xe40047b9,0xbb0047b9,
0x0,0x0,0x0,0x0,0x0,0x30047b9,0x180047b9,0x870047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x350047b9,0x9f0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xfd0047b9,0xbc0047b9,0x2b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x500047b9,0xd30047b9,0xff0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x700047b9,0xe0047b9,0x70047b9,0x0,0x0,0x1c0047b9,0x990047b9,0xfc0047b9,0xf90047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xe60047b9,0xbe0047b9,
0x0,0x0,0x0,0x0,0x0,0x70047b9,0x650047b9,0xd40047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x230047b9,0x820047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xbf0047b9,0x590047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x2d0047b9,0xad0047b9,0xff0047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x7f0047b9,0x100047b9,0x80047b9,0x0,0x0,0x1a0047b9,0x910047b9,0xf40047b9,0xf80047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xe40047b9,0xbd0047b9,
0x0,0x0,0x0,0x10047b9,0x0,0x2d0047b9,0xbc0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x270047b9,
0x7e0047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xff0047b9,0xcc0047b9,0x600047b9,0x30047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x520047b9,0xc00047b9,
0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xfa0047b9,0xef0047b9,0xe60047b9,0xe10047b9,0xe40047b9,0xe50047b9,
0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,
0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,
0xe50047b9,0xe60047b9,0xee0047b9,0xc90047b9,0x620047b9,0xb0047b9,0x70047b9,0x0,0x0,0x1a0047b9,0x910047b9,0xf40047b9,0xf80047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xe50047b9,0xbb0047b9,
0x0,0x0,0x0,0x20047b9,0x0,0x470047b9,0xd30047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,
0xcc0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xde0047b9,0x7e0047b9,0x270047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x40047b9,0x700047b9,
0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xe00047b9,0xa00047b9,0x760047b9,0x580047b9,0x6d0047b9,0x6f0047b9,
0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,
0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,
0x6e0047b9,0x710047b9,0x790047b9,0x630047b9,0x300047b9,0x70047b9,0x40047b9,0x0,0x0,0x1c0047b9,0x990047b9,0xfc0047b9,0xf90047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xe40047b9,0xbb0047b9,
0x0,0x0,0x0,0x80047b9,0x280047b9,0x950047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xfb0047b9,0xf40047b9,0xf00047b9,0xea0047b9,0xe90047b9,0xe20047b9,0xdc0047b9,0xd80047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xdb0047b9,0xde0047b9,0xe10047b9,0xe20047b9,0xe70047b9,0xeb0047b9,0xf00047b9,0xf00047b9,0xf60047b9,0xfb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x1e0047b9,0x5a0047b9,0xbe0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,
0x820047b9,0x230047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x210047b9,
0xab0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xe50047b9,0x940047b9,0x2d0047b9,0x0,0x90047b9,0xe0047b9,
0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,
0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,
0xd0047b9,0xf0047b9,0x160047b9,0xd0047b9,0x60047b9,0x20047b9,0x10047b9,0x0,0x0,0x180047b9,0x8a0047b9,0xeb0047b9,0xf80047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xe60047b9,0xbd0047b9,
0x0,0x0,0x0,0xe0047b9,0x6b0047b9,0xd70047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xfe0047b9,0xc70047b9,0xb30047b9,0x8d0047b9,0x810047b9,0x580047b9,0x310047b9,0x230047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x250047b9,0x2b0047b9,0x3e0047b9,0x590047b9,0x600047b9,0x7c0047b9,0x8f0047b9,0xb00047b9,0xbc0047b9,0xe10047b9,0xf50047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4f0047b9,0xc20047b9,0xfb0047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0x9f0047b9,
0x350047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160047b9,
0x670047b9,0xcc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xca0047b9,0x290047b9,0x0,0x20047b9,0x70047b9,
0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,
0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,
0x70047b9,0x70047b9,0x80047b9,0x70047b9,0x40047b9,0x10047b9,0x0,0x0,0x0,0x140047b9,0x720047b9,0xd10047b9,0xf60047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xf00047b9,0xc50047b9,
0x0,0x0,0x0,0x260047b9,0xb80047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xee0047b9,
0xe70047b9,0xca0047b9,0x9d0047b9,0x650047b9,0x520047b9,0x2c0047b9,0x220047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1d0047b9,0x2d0047b9,0x4f0047b9,0x570047b9,0x8b0047b9,0xcb0047b9,0xff0047b9,
0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x130047b9,0x440047b9,0xb10047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0xa60047b9,0x410047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x180047b9,0x730047b9,0xe10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0x6a0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x4f0047b9,0xb00047b9,0xf10047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xdc0047b9,0xaf0047b9,
0x0,0x0,0x0,0x350047b9,0xd20047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xa70047b9,
0x690047b9,0x280047b9,0x1f0047b9,0x110047b9,0x110047b9,0x80047b9,0xa0047b9,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x20047b9,0x40047b9,0x90047b9,0x90047b9,0x100047b9,0x80047b9,0x340047b9,0x9e0047b9,0xf50047b9,
0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x290047b9,0xa50047b9,0xfc0047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc20047b9,0x410047b9,0x30047b9,
0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x380047b9,0xce0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xcf0047b9,0x600047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x420047b9,0xa60047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xc40047b9,0x940047b9,
0x0,0x30047b9,0x0,0x630047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf20047b9,0xcf0047b9,0x9c0047b9,0x440047b9,
0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x820047b9,0xed0047b9,
0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0xb0047b9,0x240047b9,0x8d0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xcb0047b9,0x600047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0xe50047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xc00047b9,0x310047b9,0x0,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,0x1a0047b9,0x770047b9,0xe90047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0x890047b9,0x580047b9,
0x0,0x70047b9,0x220047b9,0x820047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaa0047b9,0x500047b9,0x280047b9,0xb0047b9,
0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x150047b9,0x8e0047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x2b0047b9,0x9f0047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0x5e0047b9,0x70047b9,0x10047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x30047b9,0x1a0047b9,0x8b0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x500047b9,0x0,
0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x510047b9,0xf30047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0x5e0047b9,0x280047b9,
0x0,0x100047b9,0x5e0047b9,0xbc0047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xfb0047b9,0xab0047b9,0x4c0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0047b9,0x920047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x30047b9,0x1e0047b9,0x8b0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xe00047b9,0x700047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x300047b9,0xc40047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xae0047b9,0x400047b9,
0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x230047b9,0xc90047b9,0xff0047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xd20047b9,0x2c0047b9,0x0,
0x0,0x180047b9,0x7a0047b9,0xe00047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xad0047b9,0x450047b9,0x1a0047b9,0x10047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xe0047b9,0x70047b9,0x0,0x0,0x0,0x750047b9,0xe20047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x7a0047b9,0xb0047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1e0047b9,0x7d0047b9,0xd80047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0x8b0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0047b9,0x9c0047b9,0xf50047b9,
0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xb80047b9,0x250047b9,0x10047b9,
0x0,0x1e0047b9,0xa90047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xcf0047b9,0x500047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6f0047b9,0xd0047b9,0x0,0x10047b9,0xa0047b9,0x610047b9,0xd40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0x9d0047b9,0x180047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x220047b9,0x890047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,
0x3d0047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,0x430047b9,0xaf0047b9,
0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xd80047b9,0x6b0047b9,0xe0047b9,0x0,
0x0,0x1a0047b9,0xb80047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xf40047b9,0x9d0047b9,0x2b0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe60047b9,
0x720047b9,0x40047b9,0x0,0x0,0x720047b9,0xdb0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0x8b0047b9,0x240047b9,0x80047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x20047b9,0x0,0x520047b9,0xe10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe70047b9,
0x840047b9,0x280047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x700047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x990047b9,0x270047b9,0x80047b9,0x0,
0x10047b9,0x2c0047b9,0xd30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf20047b9,0xaf0047b9,0x420047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,
0x620047b9,0xb0047b9,0x0,0x4d0047b9,0xd50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xa70047b9,0x2a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x130047b9,0x8b0047b9,0xf80047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xdc0047b9,0x770047b9,0x190047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x270047b9,
0xc00047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xc80047b9,0x450047b9,0x0,0x20047b9,0x0,
0x60047b9,0x390047b9,0xdb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0x6e0047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,
0x3b0047b9,0x20047b9,0x440047b9,0x9d0047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc00047b9,0x540047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0xa0047b9,0x300047b9,0x9e0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,
0xff0047b9,0xaf0047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160047b9,
0x6c0047b9,0xcd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x7d0047b9,0x210047b9,0x10047b9,0x10047b9,0x0,
0x1f0047b9,0x520047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd10047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,
0x5e0047b9,0x4a0047b9,0xa80047b9,0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xfd0047b9,0xc80047b9,0x600047b9,0x60047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400047b9,0xcd0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xeb0047b9,0x6c0047b9,0x10047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x160047b9,0x720047b9,0xd60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x820047b9,0x240047b9,0x0,0x0,0x0,0x0,
0x2a0047b9,0x5b0047b9,0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xb80047b9,0x240047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,
0xad0047b9,0xa80047b9,0xe10047b9,0xfd0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xcc0047b9,0x6c0047b9,0x240047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x260047b9,0x9c0047b9,0xf90047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xef0047b9,0xaf0047b9,0x430047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x310047b9,0x9e0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x9e0047b9,0x350047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x410047b9,0x700047b9,0xe60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xf50047b9,0x8a0047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,
0xf00047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd60047b9,0x730047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x430047b9,0xac0047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xf40047b9,0x9d0047b9,0x260047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x420047b9,0xa20047b9,0xd60047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,0xa30047b9,0x420047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x4c0047b9,0x7b0047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xce0047b9,0x6c0047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,
0xfa0047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xfc0047b9,0x9f0047b9,0x310047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x5c0047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xff0047b9,0xcd0047b9,0x440047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x20047b9,0xa0047b9,0x2f0047b9,0x6f0047b9,0xd00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf20047b9,0x8f0047b9,0x360047b9,0x60047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x630047b9,0x900047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb20047b9,0x530047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0xa60047b9,0x400047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100047b9,0xa00047b9,0xfd0047b9,0xfd0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x9b0047b9,0x2b0047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x100047b9,0x700047b9,0xc00047b9,0xee0047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xfe0047b9,0xf60047b9,0xf00047b9,0xcb0047b9,0x910047b9,0x310047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x740047b9,0xa10047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xb90047b9,0x5d0047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc20047b9,
0x410047b9,0x50047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x430047b9,0xad0047b9,0xfc0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xe90047b9,0x780047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x10047b9,0x1a0047b9,0x360047b9,0x820047b9,0xcc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd00047b9,0x920047b9,0x470047b9,0x240047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x7f0047b9,0xab0047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa40047b9,0x420047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xcb0047b9,0x600047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x500047b9,0xd70047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xca0047b9,0x350047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1d0047b9,0x6b0047b9,0xb90047b9,0xd20047b9,0xe60047b9,0xeb0047b9,0xf60047b9,
0xf70047b9,0xfa0047b9,0xf60047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xf60047b9,0xfa0047b9,0xf70047b9,0xf60047b9,0xec0047b9,0xe80047b9,0xd40047b9,
0xb70047b9,0x6e0047b9,0x2f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x7b0047b9,0xa60047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x7f0047b9,0x1d0047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0x5e0047b9,0x70047b9,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x300047b9,0xbf0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,0x610047b9,0x60047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x130047b9,0x250047b9,0x320047b9,0x640047b9,0x940047b9,0xcd0047b9,
0xe90047b9,0xfb0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0xfb0047b9,0xea0047b9,0xcb0047b9,0x970047b9,0x740047b9,0x460047b9,
0x280047b9,0x120047b9,0x90047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x7a0047b9,0xa50047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe70047b9,0x7e0047b9,0x1d0047b9,0x80047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xdb0047b9,0x720047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40047b9,0x630047b9,0xcf0047b9,
0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xbd0047b9,0x550047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x330047b9,0x6e0047b9,
0x880047b9,0x990047b9,0x860047b9,0x9f0047b9,0xd80047b9,0xd80047b9,0x9f0047b9,0x860047b9,0x990047b9,0x880047b9,0x6c0047b9,0x350047b9,0x140047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x7a0047b9,0xa50047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xa60047b9,0x460047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0x680047b9,0x80047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x70047b9,0x750047b9,
0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xa30047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0xa0047b9,0x160047b9,
0x190047b9,0x1d0047b9,0x180047b9,0x1b0047b9,0x270047b9,0x270047b9,0x1b0047b9,0x180047b9,0x1d0047b9,0x190047b9,0x150047b9,0xc0047b9,0x70047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x7c0047b9,0xa50047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf20047b9,0xb80047b9,0x5a0047b9,0x120047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0x970047b9,0x50047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0047b9,
0xab0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,0x580047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x7d0047b9,0xa70047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xac0047b9,0x4d0047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0x8d0047b9,0x240047b9,0x30047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x140047b9,
0x680047b9,0xcc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,0x980047b9,0x330047b9,0x50047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x780047b9,0xa30047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb30047b9,0x540047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xf90047b9,0xa40047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x180047b9,0x730047b9,0xe10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xe50047b9,0x8c0047b9,0x1a0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x740047b9,0xa20047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xbf0047b9,0x5e0047b9,0x140047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x960047b9,0x3a0047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x380047b9,0xce0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xc50047b9,0x200047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x590047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xe50047b9,0x810047b9,0x160047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,0x630047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0xe50047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0x770047b9,0x20047b9,0x20047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x3f0047b9,0x710047b9,0xe60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0x9c0047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,0x6f0047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x30047b9,0x1a0047b9,0x8b0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xd00047b9,0x640047b9,0x70047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x2b0047b9,0x5b0047b9,0xe20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc90047b9,0x300047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa90047b9,0x540047b9,0x190047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x310047b9,0xc70047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xbf0047b9,0x2c0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x300047b9,0x600047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,0x550047b9,0x0,0x50047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xf80047b9,0xbe0047b9,0x3e0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1e0047b9,0x8c0047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd30047b9,0x400047b9,0x0,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x170047b9,0x4b0047b9,0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xa80047b9,0x3c0047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x9f0047b9,0x340047b9,0xe0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x330047b9,0x980047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0x9c0047b9,0x2f0047b9,
0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x310047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xec0047b9,0x790047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfa0047b9,0xa10047b9,0x290047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x20047b9,0x0,0x540047b9,0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0x880047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x190047b9,0xcb0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc80047b9,0x420047b9,0x30047b9,0x10047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8d0047b9,0x240047b9,0xb0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0xf0047b9,0x8b0047b9,0xf80047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,
0x3e0047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1f0047b9,0xae0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe80047b9,0xa50047b9,0x3f0047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1b0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0x9f0047b9,0x280047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x90047b9,0x300047b9,0x9c0047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe70047b9,
0x830047b9,0x2a0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x160047b9,0x770047b9,0xe10047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfc0047b9,0xa00047b9,0x3a0047b9,0x60047b9,0x20047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x190047b9,0x900047b9,0xf30047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8f0047b9,0x240047b9,
0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400047b9,0xcf0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xdd0047b9,0x770047b9,0x160047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x110047b9,0x5c0047b9,0xbd0047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfe0047b9,0xde0047b9,0xa20047b9,0x400047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180047b9,0x8e0047b9,0xf00047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0x9f0047b9,
0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xda0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6f0047b9,0xe0047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x290047b9,0xaf0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,
0xff0047b9,0xac0047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x70047b9,0x220047b9,0x820047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xa40047b9,0x580047b9,0x120047b9,
0x110047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160047b9,0x930047b9,0xf40047b9,
0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,
0xe90047b9,0xea0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0x8f0047b9,0x240047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x230047b9,0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xb0047b9,0x50047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x510047b9,0xb90047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xe80047b9,0x5a0047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x30047b9,0x0,0x630047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xeb0047b9,0xdc0047b9,0x940047b9,
0x550047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8e0047b9,0xfa0047b9,
0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,
0x8b0047b9,0x950047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xf50047b9,0x9f0047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1b0047b9,0xd60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,0x670047b9,0x30047b9,0x10047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x540047b9,0xe40047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xef0047b9,0xaa0047b9,0x430047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x350047b9,0xd20047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,
0xb60047b9,0x680047b9,0x4c0047b9,0x240047b9,0x1f0047b9,0x170047b9,0x110047b9,0xc0047b9,0xf0047b9,0xb0047b9,0x70047b9,0x50047b9,0x60047b9,0x60047b9,
0x50047b9,0x80047b9,0xe0047b9,0x120047b9,0xe0047b9,0x100047b9,0x150047b9,0x1b0047b9,0x1a0047b9,0x200047b9,0x190047b9,0x590047b9,0xb80047b9,0xff0047b9,
0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe00047b9,
0x530047b9,0x3c0047b9,0xa50047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0x8f0047b9,0x240047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x70047b9,0x90047b9,
0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,
0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x60047b9,
0x0,0x2c0047b9,0xdb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x710047b9,0x130047b9,0xe0047b9,0x40047b9,0x60047b9,0x70047b9,
0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x80047b9,0x70047b9,0x40047b9,0x10047b9,0x0,0x0,
0x0,0x20047b9,0x50047b9,0x90047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,
0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,
0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x70047b9,0x30047b9,0x0,0x150047b9,0xa70047b9,0xff0047b9,0xfb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xf90047b9,0x9e0047b9,0x270047b9,0x10047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x260047b9,0xb80047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,
0xf10047b9,0xe20047b9,0xe10047b9,0xcf0047b9,0xaa0047b9,0x790047b9,0x5d0047b9,0x420047b9,0x4a0047b9,0x330047b9,0x160047b9,0x50047b9,0xd0047b9,0xe0047b9,
0x0,0x1b0047b9,0x440047b9,0x5b0047b9,0x480047b9,0x570047b9,0x720047b9,0x900047b9,0x920047b9,0xb00047b9,0xcc0047b9,0xe30047b9,0xf30047b9,0xfd0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,
0x610047b9,0x1e0047b9,0x2d0047b9,0x830047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xf50047b9,0x9f0047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,0x1a0047b9,0x200047b9,
0x100047b9,0xf0047b9,0xe0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,
0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xf0047b9,0x70047b9,
0x0,0x360047b9,0xdb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,0x760047b9,0x1b0047b9,0x130047b9,0x50047b9,0xd0047b9,0xd0047b9,
0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xf0047b9,0x160047b9,0xd0047b9,0x60047b9,0x20047b9,0x10047b9,0x0,
0x0,0x30047b9,0xc0047b9,0x1a0047b9,0xf0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,
0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,
0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xd0047b9,0xe0047b9,0xa0047b9,0x0,0x1d0047b9,0x5d0047b9,0xb40047b9,0xef0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xff0047b9,0xce0047b9,0x460047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0xe0047b9,0x6b0047b9,0xd70047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,0xbf0047b9,0xa20047b9,0xa90047b9,0x940047b9,0x770047b9,0x660047b9,0x6c0047b9,0x6d0047b9,
0x620047b9,0x7a0047b9,0xa60047b9,0xbc0047b9,0xa90047b9,0xb90047b9,0xd20047b9,0xef0047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,
0x660047b9,0x0,0x0,0x1c0047b9,0x9c0047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8f0047b9,0x240047b9,0xb0047b9,0x0,0x0,0x0,0x0,0xb0047b9,0x2e0047b9,0x5c0047b9,
0x6f0047b9,0x770047b9,0x700047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,
0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x700047b9,0x690047b9,
0x490047b9,0x890047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xad0047b9,0x760047b9,0x710047b9,0x670047b9,0x6c0047b9,0x6f0047b9,
0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x710047b9,0x790047b9,0x630047b9,0x300047b9,0x70047b9,0x40047b9,0x0,
0x0,0x100047b9,0x5f0047b9,0x7e0047b9,0x700047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,
0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,
0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6e0047b9,0x6f0047b9,0x6b0047b9,0x630047b9,0x6e0047b9,0x730047b9,0xae0047b9,0xef0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x970047b9,0x280047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x80047b9,0x280047b9,0x950047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf60047b9,0xf10047b9,0xec0047b9,0xef0047b9,0xeb0047b9,0xe70047b9,0xe30047b9,0xe40047b9,0xe40047b9,
0xe20047b9,0xe70047b9,0xee0047b9,0xf20047b9,0xee0047b9,0xf00047b9,0xf40047b9,0xf80047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,
0x6d0047b9,0xb0047b9,0x10047b9,0x10047b9,0x220047b9,0x8f0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0x9f0047b9,0x280047b9,0x0,0x0,0x0,0x0,0xe0047b9,0x380047b9,0x9e0047b9,
0xf10047b9,0xfd0047b9,0xe90047b9,0xe40047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,
0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe40047b9,
0xde0047b9,0xe80047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xef0047b9,0xe60047b9,0xe50047b9,0xe40047b9,0xe40047b9,0xe50047b9,
0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe60047b9,0xee0047b9,0xc90047b9,0x620047b9,0xb0047b9,0x70047b9,0x0,
0x0,0x230047b9,0xbc0047b9,0xf30047b9,0xe60047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,
0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,
0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe50047b9,0xe40047b9,0xe30047b9,0xe50047b9,0xe60047b9,0xf30047b9,0xfb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xd70047b9,0x680047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x20047b9,0x0,0x470047b9,0xd50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x710047b9,0xd0047b9,0x20047b9,0x0,0x0,0x280047b9,0x9f0047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8f0047b9,0x240047b9,0xb0047b9,0x0,0x0,0xa0047b9,0x280047b9,0x890047b9,
0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x7f0047b9,0x100047b9,0x80047b9,0x0,
0x0,0x2e0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xb90047b9,0x310047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x10047b9,0x0,0x2d0047b9,0xbe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xe0047b9,0x50047b9,0x0,0x0,0xb0047b9,0x240047b9,0x8f0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0x9f0047b9,0x280047b9,0x0,0x0,0x20047b9,0x20047b9,0x260047b9,
0x5f0047b9,0xc50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x700047b9,0xe0047b9,0x70047b9,0x0,
0x0,0x270047b9,0xdf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfe0047b9,0xd80047b9,0x610047b9,0x70047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x60047b9,0x630047b9,0xd10047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x80047b9,0x0,0x0,0x0,0x0,0x280047b9,0x9f0047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8f0047b9,0x240047b9,0xb0047b9,0x0,0x0,0x0,
0x0,0x5e0047b9,0xc20047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x250047b9,0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xbd0047b9,0x550047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0x70047b9,0x760047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0xb0047b9,0x240047b9,0x8f0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0x9f0047b9,0x280047b9,0x0,0x0,0x0,
0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xa50047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1b0047b9,0xa70047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x280047b9,0x9d0047b9,0xf70047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8f0047b9,0x1f0047b9,0x40047b9,0x0,
0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0x550047b9,0x0,0x30047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x130047b9,0x550047b9,0xc10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x220047b9,0x8f0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0x850047b9,0x0,0x0,
0x0,0x0,0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x890047b9,0x240047b9,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x80047b9,0x5f0047b9,0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2b0047b9,0xbc0047b9,0xfd0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe70047b9,0x630047b9,0x90047b9,
0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xd70047b9,0x7d0047b9,0x1a0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x150047b9,0x590047b9,0xc00047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xdc0047b9,0x700047b9,
0x0,0x0,0x0,0x0,0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xc20047b9,0x250047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xfa0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x40047b9,0x600047b9,
0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,
0x610047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xfb0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x720047b9,0x10047b9,0x20047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200047b9,0x5a0047b9,0xc00047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x10047b9,0x200047b9,
0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,
0xdb0047b9,0x710047b9,0x0,0x0,0x0,0x0,0x0,0x200047b9,0x5a0047b9,0xbe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xc00047b9,0x510047b9,0x30047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x5f0047b9,
0xc10047b9,0xf70047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x20047b9,0x600047b9,0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd70047b9,0x610047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,0xcc0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xaf0047b9,0x280047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x1f0047b9,
0x4d0047b9,0xaf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf40047b9,0xdb0047b9,0x710047b9,0x0,0x0,0x0,0x0,0x0,0x270047b9,0x7e0047b9,0xde0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xcf0047b9,0x400047b9,0x0,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x4c0047b9,0xa20047b9,0xef0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x610047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x230047b9,0x820047b9,0xd90047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0x9e0047b9,0x2f0047b9,
0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x20047b9,0x100047b9,0x1c0047b9,0x720047b9,0xc90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xdb0047b9,0x710047b9,0x0,0x0,0x0,0x20047b9,0x0,0x350047b9,0x9f0047b9,0xfe0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0x880047b9,
0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0xa0047b9,0x660047b9,0xbd0047b9,0xd60047b9,0xed0047b9,0xf60047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x610047b9,0xa0047b9,0x10047b9,0x0,0x0,0x0,0x410047b9,0xa50047b9,
0xdf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,
0x3a0047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x30047b9,0x110047b9,0x2c0047b9,0x490047b9,0x910047b9,0xd00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xdb0047b9,0x710047b9,0x0,0x0,0x0,0x20047b9,0x50047b9,0x3c0047b9,
0x9f0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x730047b9,0x1a0047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2f0047b9,0x6e0047b9,0xb60047b9,0xd70047b9,0xed0047b9,0xee0047b9,0xfa0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x610047b9,0xa0047b9,0x10047b9,0x0,0x0,0x0,
0x400047b9,0xa50047b9,0xdf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,
0xcd0047b9,0x670047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x90047b9,0x120047b9,0x2c0047b9,0x4e0047b9,0x8b0047b9,0xae0047b9,0xf80047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xdb0047b9,0x710047b9,0x0,0x0,0x0,0x10047b9,
0x50047b9,0x3c0047b9,0x9f0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,
0xff0047b9,0xa80047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x290047b9,0x4d0047b9,0x940047b9,
0xc90047b9,0xe30047b9,0xe20047b9,0xec0047b9,0xf10047b9,0xf90047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xfa0047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x610047b9,0xa0047b9,0x10047b9,0x0,
0x0,0x0,0x400047b9,0xa50047b9,0xdf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x6e0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xea0047b9,0x5c0047b9,0x0,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0xa0047b9,0xe0047b9,0x1c0047b9,
0x270047b9,0x490047b9,0x660047b9,0x970047b9,0xb70047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200047b9,0x5a0047b9,0xc00047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xdb0047b9,0x6e0047b9,0x0,0x0,
0x0,0x10047b9,0x50047b9,0x3c0047b9,0x9f0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,0x6d0047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x250047b9,0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xef0047b9,0xa70047b9,0x420047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x40047b9,0x370047b9,0x580047b9,0x8a0047b9,0xa20047b9,0xc70047b9,0xd60047b9,0xdf0047b9,0xe20047b9,0xe80047b9,0xec0047b9,0xef0047b9,
0xec0047b9,0xf20047b9,0xf80047b9,0xfa0047b9,0xf90047b9,0xf80047b9,0xf60047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf90047b9,0xf80047b9,0xfa0047b9,0xf80047b9,0xf30047b9,0xf40047b9,0xf80047b9,0xfb0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x600047b9,0xc40047b9,0xf90047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x690047b9,0x100047b9,
0x40047b9,0x0,0x0,0x0,0x400047b9,0xa50047b9,0xdf0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0x710047b9,0xd0047b9,0x70047b9,0x0,
0x0,0x270047b9,0xe20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xa20047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x40047b9,0xc0047b9,0x110047b9,0x190047b9,0x1c0047b9,0x260047b9,0x2b0047b9,0x480047b9,0x5d0047b9,0x7f0047b9,0x970047b9,0xa90047b9,
0xa10047b9,0xbf0047b9,0xe50047b9,0xff0047b9,0xf20047b9,0xf00047b9,0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xed0047b9,0xf60047b9,0xeb0047b9,0xcb0047b9,0xce0047b9,0xe20047b9,0xf40047b9,
0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200047b9,0x590047b9,0xc30047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,
0x210047b9,0x0,0x0,0x10047b9,0x50047b9,0x3c0047b9,0x9e0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x850047b9,0x110047b9,0x80047b9,0x0,
0x0,0x2f0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x540047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200047b9,0x350047b9,0x490047b9,
0x420047b9,0x5f0047b9,0x860047b9,0x9d0047b9,0x930047b9,0x8e0047b9,0x840047b9,0x9d0047b9,0xcd0047b9,0xdc0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xdb0047b9,0xd40047b9,0xc20047b9,0xa40047b9,0x950047b9,0x8c0047b9,0x970047b9,0x8a0047b9,0x680047b9,0x780047b9,0xb70047b9,0xf00047b9,
0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x5f0047b9,
0xbb0047b9,0xe10047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xdb0047b9,0xdb0047b9,0xe40047b9,0xfd0047b9,0xa70047b9,
0x210047b9,0x0,0x0,0x0,0x0,0x0,0x420047b9,0xa10047b9,0xcb0047b9,0xdd0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd80047b9,0xdb0047b9,0xe50047b9,0xf40047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0xf10047b9,0xdb0047b9,0xd70047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xe10047b9,0xbe0047b9,0x5b0047b9,0xb0047b9,0x60047b9,0x0,
0x0,0x210047b9,0xb20047b9,0xe50047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xdc0047b9,0xeb0047b9,0xcc0047b9,0x4b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0xa0047b9,0xa0047b9,0xf0047b9,
0xc0047b9,0x120047b9,0x180047b9,0x1e0047b9,0x1b0047b9,0x1b0047b9,0x170047b9,0x1c0047b9,0x240047b9,0x270047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x250047b9,0x220047b9,0x1f0047b9,0x1c0047b9,0x1a0047b9,0x1c0047b9,0x1a0047b9,0xb0047b9,0x300047b9,0x990047b9,0xf10047b9,
0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x120047b9,
0x230047b9,0x280047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x250047b9,0x270047b9,0x2e0047b9,0x1e0047b9,
0x40047b9,0x0,0x0,0x0,0x0,0x10047b9,0xc0047b9,0x1f0047b9,0x250047b9,0x270047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x210047b9,0x3b0047b9,0x720047b9,0xc10047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xff0047b9,0xa70047b9,0x410047b9,0x1e0047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x280047b9,0x220047b9,0x100047b9,0x40047b9,0x20047b9,0x0,
0x0,0x40047b9,0x220047b9,0x290047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x250047b9,0x2a0047b9,0x260047b9,0xc0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x840047b9,0xf10047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x2c0047b9,0x9c0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xff0047b9,0x980047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160047b9,0x900047b9,0xf30047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x50047b9,0x480047b9,0xaa0047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xc80047b9,0x120047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1b0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0xc0047b9,0x360047b9,0x960047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x570047b9,0x0,0x10047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x80047b9,0x1b0047b9,0x840047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,0x980047b9,0x310047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x50047b9,0x0,0x570047b9,0xe40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xe50047b9,0x8e0047b9,0x2a0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x10047b9,0x0,0x350047b9,0xe80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xcf0047b9,0x610047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x170047b9,0xcc0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbe0047b9,0x5b0047b9,
0x280047b9,0x70047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1d0047b9,0xac0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf60047b9,0xcf0047b9,
0x8a0047b9,0x340047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x160047b9,0x780047b9,0xe00047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xe80047b9,0x970047b9,0x670047b9,0x2e0047b9,0x210047b9,0x170047b9,0x130047b9,0x100047b9,0x130047b9,0xe0047b9,0xb0047b9,0x60047b9,0x20047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x110047b9,0x5c0047b9,0xc10047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xfb0047b9,0xea0047b9,0xe60047b9,0xcd0047b9,0xa60047b9,0x7b0047b9,0x690047b9,0x570047b9,0x5d0047b9,0x470047b9,0x380047b9,0x1a0047b9,0x60047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x80047b9,0x220047b9,0x7e0047b9,0xe60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdd0047b9,0xc90047b9,0xb60047b9,0xbe0047b9,0xa20047b9,0x790047b9,0x370047b9,0xb0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x30047b9,0x0,0x4e0047b9,0xdf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xf50047b9,0xf30047b9,0xf00047b9,0xf80047b9,0xde0047b9,0xa30047b9,0x4b0047b9,0xe0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x1d0047b9,0xb40047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc10047b9,0x590047b9,0x120047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x1d0047b9,0x970047b9,0xfa0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xb20047b9,0x520047b9,0xf0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0xc0047b9,0x490047b9,0xa90047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,0xaf0047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x5c0047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb00047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100047b9,0xa70047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb00047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x110047b9,0x670047b9,0xce0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb00047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x1b0047b9,0x720047b9,0xd60047b9,0xff0047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb00047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x310047b9,0x9f0047b9,0xf90047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb00047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f0047b9,0xab0047b9,0xeb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb00047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x10047b9,0x580047b9,0xd60047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb00047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,0x750047b9,0xda0047b9,
0xea0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb00047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0047b9,0x590047b9,
0xa40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xaf0047b9,0x500047b9,0x100047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xf20047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xf20047b9,0x910047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xb00047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6e0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x410047b9,0xa00047b9,0xce0047b9,0xf30047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xb30047b9,0x520047b9,0xf0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x900047b9,0xf00047b9,
0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf70047b9,0xf00047b9,0x900047b9,0x1a0047b9,0x0,0x0,0x100047b9,0x500047b9,0xae0047b9,0xee0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,
0x6d0047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0xb0047b9,0x2a0047b9,0x4f0047b9,0xae0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbf0047b9,0x5a0047b9,0x120047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x950047b9,0xf90047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xf90047b9,0x950047b9,0x1a0047b9,0x0,0x0,0x110047b9,0x520047b9,0xb50047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,
0x710047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x4b0047b9,0xa30047b9,0xeb0047b9,0xe60047b9,0xf30047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xe40047b9,0xa40047b9,0x480047b9,0xf0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x210047b9,0xaf0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x210047b9,0x0,0x0,0x150047b9,0x610047b9,0xd40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0x850047b9,0x110047b9,0x80047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x10047b9,0xd0047b9,0x1a0047b9,0x520047b9,0x780047b9,0xc60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbf0047b9,0x810047b9,0x2f0047b9,0xb0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x170047b9,0x770047b9,0xc80047b9,
0xd30047b9,0xdb0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xdb0047b9,0xd30047b9,0xc80047b9,0x770047b9,0x170047b9,0x0,0x0,0xd0047b9,0x440047b9,0x900047b9,0xc70047b9,0xde0047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xe10047b9,0xbe0047b9,
0x5b0047b9,0xb0047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x190047b9,0x650047b9,0x990047b9,0xd10047b9,0xd90047b9,0xe30047b9,0xe80047b9,0xef0047b9,
0xef0047b9,0xf60047b9,0xf80047b9,0xfa0047b9,0xf90047b9,0xf80047b9,0xf80047b9,0xf80047b9,0xf80047b9,0xf80047b9,0xf90047b9,0xf80047b9,0xf60047b9,0xf20047b9,
0xf30047b9,0xee0047b9,0xeb0047b9,0xe40047b9,0xe20047b9,0xdd0047b9,0xd70047b9,0xb80047b9,0xa20047b9,0x640047b9,0x3f0047b9,0xf0047b9,0x60047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x160047b9,0x240047b9,
0x250047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x250047b9,0x240047b9,0x160047b9,0x20047b9,0x0,0x0,0x50047b9,0xa0047b9,0x1c0047b9,0x230047b9,0x270047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x280047b9,0x220047b9,
0x100047b9,0x40047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,0x130047b9,0x1b0047b9,0x290047b9,0x340047b9,0x560047b9,0x720047b9,0x990047b9,
0xa50047b9,0xc70047b9,0xde0047b9,0xed0047b9,0xe50047b9,0xe40047b9,0xe50047b9,0xe50047b9,0xe40047b9,0xe60047b9,0xe90047b9,0xe00047b9,0xd10047b9,0xbb0047b9,
0xb30047b9,0x9a0047b9,0x860047b9,0x650047b9,0x530047b9,0x370047b9,0x290047b9,0x1f0047b9,0x1f0047b9,0x130047b9,0xd0047b9,0x50047b9,0x20047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x2f0047b9,0x550047b9,0x850047b9,
0x950047b9,0xbf0047b9,0xdd0047b9,0xf10047b9,0xe90047b9,0xe60047b9,0xe60047b9,0xe60047b9,0xe60047b9,0xe70047b9,0xed0047b9,0xe00047b9,0xcd0047b9,0xaf0047b9,
0xa70047b9,0x860047b9,0x6e0047b9,0x420047b9,0x2d0047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x580047b9,0x910047b9,0x8b0047b9,0x890047b9,
0x730047b9,0xa10047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc00047b9,0x980047b9,0x7b0047b9,0x870047b9,0x8e0047b9,0xa70047b9,0x6e0047b9,
0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x20047b9,0xb0047b9,0x70047b9,0x140047b9,0x1e0047b9,0x290047b9,0x210047b9,0x360047b9,0x750047b9,0xa40047b9,0x9d0047b9,0x9d0047b9,
0x8b0047b9,0xaf0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xc70047b9,0xa80047b9,0x900047b9,0x9b0047b9,0xa00047b9,0xb50047b9,0x880047b9,
0x390047b9,0x200047b9,0x280047b9,0x230047b9,0x120047b9,0x70047b9,0xf0047b9,0x80047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x260047b9,0x260047b9,0x670047b9,0xaa0047b9,0xe10047b9,0xd80047b9,0xdb0047b9,0xe70047b9,0xf10047b9,0xee0047b9,0xef0047b9,
0xea0047b9,0xf00047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf40047b9,0xf00047b9,0xec0047b9,0xee0047b9,0xee0047b9,0xf40047b9,0xeb0047b9,
0xdb0047b9,0xd80047b9,0xe00047b9,0xbe0047b9,0x640047b9,0x2c0047b9,0x4a0047b9,0x1e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x60047b9,0x160047b9,
0x1d0047b9,0x360047b9,0x5c0047b9,0x870047b9,0x880047b9,0xc60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc30047b9,0x8b0047b9,0xa90047b9,0x7f0047b9,0x3d0047b9,0x1e0047b9,0x190047b9,0xe0047b9,0xe0047b9,0x40047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1d0047b9,0x700047b9,
0xaa0047b9,0xe20047b9,0xe30047b9,0xe90047b9,0xe90047b9,0xf40047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xe70047b9,0xf10047b9,0xe80047b9,0xe00047b9,0xc50047b9,0x890047b9,0x4b0047b9,0x3e0047b9,0x50047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x80047b9,0x190047b9,0x200047b9,0x520047b9,0x7e0047b9,0xd10047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xed0047b9,0xac0047b9,0x9f0047b9,0x690047b9,
0x370047b9,0x1c0047b9,0x150047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2a0047b9,0x870047b9,0xc30047b9,0xe40047b9,0xe60047b9,0xf60047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xee0047b9,0xee0047b9,0xe40047b9,
0xe30047b9,0xa90047b9,0x740047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x50047b9,0x150047b9,0x1d0047b9,0x570047b9,0x8b0047b9,0xe80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xd50047b9,0x780047b9,0x3d0047b9,0x1f0047b9,0x190047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x150047b9,0x760047b9,0xbf0047b9,0xe50047b9,0xea0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xf70047b9,0xe60047b9,0xe00047b9,0xc40047b9,0x890047b9,0x270047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x10047b9,0xd0047b9,0x150047b9,0x3a0047b9,0x770047b9,0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x890047b9,0x410047b9,0x1e0047b9,0x160047b9,0x50047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x3b0047b9,0x8e0047b9,0xda0047b9,0xe40047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xe90047b9,0xe10047b9,0xbe0047b9,0x760047b9,0x150047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x1f0047b9,
0x430047b9,0x9f0047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xf00047b9,0xec0047b9,
0xf00047b9,0xee0047b9,0xea0047b9,0xe20047b9,0xdb0047b9,0xd80047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd80047b9,0xe00047b9,0xeb0047b9,0xf30047b9,0xef0047b9,0xed0047b9,0xed0047b9,0xf50047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x770047b9,0x390047b9,0x110047b9,
0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x170047b9,0x770047b9,
0xc40047b9,0xf30047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0xb40047b9,0x980047b9,
0xae0047b9,0xa00047b9,0x890047b9,0x5b0047b9,0x330047b9,0x230047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x250047b9,0x200047b9,0x550047b9,0x940047b9,0xba0047b9,0xa80047b9,0xa60047b9,0x9e0047b9,0xd40047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xdf0047b9,0xca0047b9,0x780047b9,
0x230047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0xd0047b9,0x370047b9,0x760047b9,0xd60047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xf30047b9,0xf50047b9,0xe90047b9,0xde0047b9,0xcf0047b9,0xba0047b9,0x830047b9,0x550047b9,0x390047b9,
0x4c0047b9,0x400047b9,0x2a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x330047b9,0x590047b9,0x460047b9,0x470047b9,0x3f0047b9,0x720047b9,0xc10047b9,0xdf0047b9,
0xd80047b9,0xdc0047b9,0xe90047b9,0xf50047b9,0xf30047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,
0x870047b9,0x350047b9,0x1c0047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5b0047b9,0xc00047b9,0xde0047b9,0xf80047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xc50047b9,0xc60047b9,0x870047b9,0x3e0047b9,0x1e0047b9,0x220047b9,0x180047b9,0x100047b9,0xa0047b9,
0x100047b9,0xd0047b9,0xb0047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0xb0047b9,0x130047b9,0xf0047b9,0xd0047b9,0xa0047b9,0x140047b9,0x240047b9,0x280047b9,
0x200047b9,0x3d0047b9,0x870047b9,0xc60047b9,0xc50047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,
0xef0047b9,0xc20047b9,0x770047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0xc0047b9,0x4a0047b9,0xbd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xfa0047b9,0xea0047b9,0xe30047b9,0xc90047b9,0x940047b9,0x640047b9,0x640047b9,0x270047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x270047b9,0x640047b9,0x640047b9,0x940047b9,0xc80047b9,0xe00047b9,0xe80047b9,0xf50047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xd90047b9,0x760047b9,0x350047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x710047b9,0xd10047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xe80047b9,0x8b0047b9,0x560047b9,0x1c0047b9,0x1b0047b9,0x120047b9,0x150047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x90047b9,0x150047b9,0x120047b9,0x1b0047b9,0x1e0047b9,0x3d0047b9,0x810047b9,0xce0047b9,0xe80047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xf90047b9,0xda0047b9,0xaf0047b9,0x4b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0x80047b9,0x600047b9,0xd40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xed0047b9,0xe50047b9,0xc10047b9,
0x870047b9,0x2a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0047b9,0x6c0047b9,0x880047b9,0xba0047b9,0xd60047b9,0xec0047b9,
0xf50047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xad0047b9,0x460047b9,0xd0047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x300047b9,0x490047b9,0x370047b9,0x3d0047b9,0x4c0047b9,0x5e0047b9,0x680047b9,0x6f0047b9,
0x670047b9,0x620047b9,0x600047b9,0x5d0047b9,0x5c0047b9,0x5c0047b9,0x5d0047b9,0x580047b9,0x560047b9,0x3f0047b9,0x240047b9,0x150047b9,0x250047b9,0x170047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0x700047b9,0xd60047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0x9d0047b9,0x580047b9,0x1a0047b9,
0x190047b9,0x80047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x150047b9,0x160047b9,0x2c0047b9,0x4e0047b9,0x960047b9,
0xcb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xeb0047b9,0xd10047b9,0x720047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x2b0047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x230047b9,0x2d0047b9,0x530047b9,0x670047b9,0x5b0047b9,0x610047b9,0x6c0047b9,0x7c0047b9,0x830047b9,0x870047b9,
0x830047b9,0x7d0047b9,0x7b0047b9,0x7a0047b9,0x790047b9,0x790047b9,0x7a0047b9,0x760047b9,0x750047b9,0x630047b9,0x4d0047b9,0x410047b9,0x4e0047b9,0x430047b9,
0x2a0047b9,0x1d0047b9,0x1b0047b9,0x100047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x10047b9,0x60047b9,0x5e0047b9,0xd40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xf10047b9,0xcd0047b9,0x980047b9,0x3d0047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x340047b9,
0x690047b9,0xb20047b9,0xd50047b9,0xed0047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd40047b9,0x600047b9,0x80047b9,0x10047b9,0x0,0x0,0x0,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd50047b9,0x2b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x190047b9,0x8e0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcb0047b9,0x590047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1b0047b9,0x830047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xdc0047b9,0xdc0047b9,0xda0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd80047b9,0xd20047b9,0xd70047b9,0xe00047b9,0xe40047b9,0xe60047b9,0xe80047b9,0xe90047b9,0xea0047b9,
0xe90047b9,0xe80047b9,0xe90047b9,0xe80047b9,0xe80047b9,0xe80047b9,0xe80047b9,0xe70047b9,0xe70047b9,0xe40047b9,0xe00047b9,0xdd0047b9,0xe20047b9,0xdf0047b9,
0xd30047b9,0xae0047b9,0x930047b9,0x500047b9,0x1c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x8b0047b9,0xac0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xac0047b9,0x8b0047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x5a0047b9,0xc80047b9,0xee0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf20047b9,0x9e0047b9,0x460047b9,0x260047b9,0x90047b9,0x20047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0xa0047b9,
0x120047b9,0x2b0047b9,0x490047b9,0x980047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xd60047b9,0x700047b9,0x0,0x0,0x0,0x0,
0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd00047b9,0x250047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90047b9,
0x140047b9,0x840047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbf0047b9,0x520047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x170047b9,0x7a0047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xf50047b9,0xb10047b9,0x7d0047b9,0x400047b9,0x260047b9,0xd0047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x850047b9,0xa10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,0x850047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x10047b9,0x30047b9,0x3e0047b9,0xbb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf30047b9,0xe00047b9,0x8b0047b9,0x3b0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x380047b9,0x7c0047b9,0xc50047b9,0xdd0047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd40047b9,0x600047b9,0x80047b9,0x10047b9,0x0,
0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb60047b9,0x210047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,
0x120047b9,0x760047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xac0047b9,0x490047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6e0047b9,0xd00047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xf90047b9,0xef0047b9,0xeb0047b9,0xd00047b9,0xa60047b9,0x510047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x780047b9,0x8e0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0x8e0047b9,0x780047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x3c0047b9,0x9e0047b9,0xe30047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc20047b9,0x5e0047b9,0xd0047b9,0xd0047b9,0x10047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x10047b9,0xb0047b9,0x140047b9,0x340047b9,0x630047b9,0xc60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xd60047b9,0x6e0047b9,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xae0047b9,0x1f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x720047b9,0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0xa50047b9,0x460047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x130047b9,0x690047b9,0xc80047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb20047b9,0x700047b9,0x240047b9,0xe0047b9,0x10047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x730047b9,0x8a0047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x8a0047b9,0x730047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x310047b9,0x990047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0xbe0047b9,0x5e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x650047b9,0xbc0047b9,0xed0047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x670047b9,0x90047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf10047b9,0xf00047b9,0xa10047b9,0x3d0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,
0x1f0047b9,0x790047b9,0xd50047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xf80047b9,0x990047b9,0x3f0047b9,0xb0047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x140047b9,0x230047b9,0x720047b9,0xc40047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8d0047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,0x410047b9,0x1a0047b9,0x10047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160047b9,
0x6e0047b9,0xd60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xfd0047b9,0xd90047b9,0x9d0047b9,0x390047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x620047b9,0xb90047b9,0xd00047b9,0xdc0047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xdb0047b9,0xdc0047b9,0xe40047b9,0xf50047b9,0x930047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf40047b9,0xc00047b9,0x660047b9,0x90047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0047b9,
0xa90047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xe50047b9,0x880047b9,0x350047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x130047b9,0x220047b9,0x250047b9,0x270047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x250047b9,0x280047b9,0x2b0047b9,0x170047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc60047b9,0x620047b9,
0x230047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x80047b9,0x750047b9,
0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xd90047b9,
0x8c0047b9,0x290047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x80047b9,0x80047b9,0x140047b9,0x1d0047b9,0x250047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x270047b9,0x240047b9,
0x180047b9,0xe0047b9,0x150047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,0xa0047b9,0x180047b9,0x230047b9,0x280047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x270047b9,0x240047b9,0x1f0047b9,0x140047b9,0x120047b9,0xa0047b9,0xa0047b9,0x20047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xc60047b9,
0x660047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5d0047b9,0xcb0047b9,
0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0x990047b9,
0x350047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x290047b9,0x650047b9,0x980047b9,0xcc0047b9,0xd70047b9,0xda0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xde0047b9,0xc50047b9,
0x820047b9,0x520047b9,0x630047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160047b9,0x320047b9,0x7e0047b9,0xc30047b9,0xdf0047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xdc0047b9,0xce0047b9,0xa80047b9,0x740047b9,0x5b0047b9,0x330047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xc30047b9,0x5e0047b9,0x160047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x340047b9,0xbb0047b9,0xff0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe70047b9,0x9e0047b9,0x3a0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,0x120047b9,0x2a0047b9,
0x490047b9,0x760047b9,0x880047b9,0xc60047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xe60047b9,0xb40047b9,0xc20047b9,0x8a0047b9,0x410047b9,0x1e0047b9,0x160047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x10047b9,0x0,0x1b0047b9,0x440047b9,0x780047b9,0x930047b9,0xe10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd50047b9,0xba0047b9,0x930047b9,0x880047b9,0x5b0047b9,0x320047b9,0x190047b9,0x150047b9,0x50047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd40047b9,0x3e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x140047b9,0x670047b9,0xda0047b9,0xfe0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xce0047b9,0x420047b9,0x20047b9,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x210047b9,0x670047b9,0xb50047b9,
0xd40047b9,0xe80047b9,0xe80047b9,0xf40047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xf70047b9,0xf00047b9,0xf50047b9,0xe90047b9,0xe20047b9,0xbe0047b9,0x760047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0xb0047b9,0x660047b9,0xc20047b9,0xee0047b9,0xea0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf50047b9,0xf20047b9,0xea0047b9,0xea0047b9,0xde0047b9,0xce0047b9,0x980047b9,0x710047b9,0x1a0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0x9f0047b9,0x1f0047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x560047b9,0xc30047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xde0047b9,0x6d0047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x1e0047b9,0x3a0047b9,0x840047b9,0xc70047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x770047b9,0x390047b9,0x110047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x10047b9,0x10047b9,0x1d0047b9,0x610047b9,0xc70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xd00047b9,0x7d0047b9,
0x3e0047b9,0x1a0047b9,0x120047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xfb0047b9,0x810047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,0x900047b9,0xff0047b9,0xfd0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf20047b9,0x790047b9,0xc0047b9,0x10047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x190047b9,0x760047b9,0xc20047b9,0xed0047b9,0xf50047b9,0xfe0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xdf0047b9,0xca0047b9,0x780047b9,0x230047b9,0x0,0x0,0x0,
0x0,0x30047b9,0x0,0x4a0047b9,0xc30047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xf60047b9,0xe60047b9,
0xe50047b9,0xa70047b9,0x620047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x3e0047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x370047b9,0xd30047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xa60047b9,0x1c0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0x70047b9,0x320047b9,0x760047b9,0xd70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,0x880047b9,0x350047b9,0x120047b9,0x0,
0x0,0x30047b9,0x2a0047b9,0x9e0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xc20047b9,0x670047b9,0x320047b9,0xf0047b9,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x7a0047b9,0x1d0047b9,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x130047b9,0x690047b9,0xdf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc30047b9,0x5d0047b9,0x130047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x3b0047b9,0x9d0047b9,0xd50047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xf20047b9,0xb70047b9,0x430047b9,0x0,
0x0,0x0,0x630047b9,0xd40047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xf60047b9,0xd90047b9,0xba0047b9,0x610047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,0x7c0047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x570047b9,0xc20047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfe0047b9,0xda0047b9,0x660047b9,0xe0047b9,0x10047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x10047b9,0x50047b9,0x390047b9,0x990047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa60047b9,0x360047b9,
0x10047b9,0x230047b9,0xb30047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc40047b9,0x730047b9,0x240047b9,0x100047b9,0x20047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xcb0047b9,0x140047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x900047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xb50047b9,0x320047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x3d0047b9,0x9d0047b9,0xdc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf50047b9,0xbe0047b9,
0x530047b9,0x580047b9,0xd80047b9,0xfe0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf20047b9,0xee0047b9,0xb70047b9,0x530047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x4c0047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x380047b9,0xd20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xd40047b9,0x630047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x20047b9,0x0,0x310047b9,0x990047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xb90047b9,0xb20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb60047b9,0x500047b9,0x220047b9,0x20047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x7a0047b9,0x1f0047b9,0x80047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x80047b9,0x1a0047b9,0x700047b9,0xe10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0x9a0047b9,0x2c0047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x10047b9,0x1f0047b9,0x790047b9,0xd50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xee0047b9,0xee0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf70047b9,0xc60047b9,0x770047b9,0x1b0047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcb0047b9,0x6d0047b9,0x120047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x500047b9,0xba0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xd40047b9,0x4b0047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x170047b9,0x6e0047b9,0xd60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf50047b9,0xea0047b9,0xdf0047b9,0xda0047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd80047b9,0xe00047b9,0xe60047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfc0047b9,0xf70047b9,0xe90047b9,0xdb0047b9,0xd80047b9,0xd80047b9,0xda0047b9,0xe60047b9,0xf10047b9,0xf40047b9,0xfd0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x730047b9,0x2b0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa80047b9,0xc0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0xf0047b9,0x6e0047b9,0xda0047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xb40047b9,0x2b0047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x270047b9,0xab0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcc0047b9,0x950047b9,0x4f0047b9,0x2e0047b9,0x240047b9,0x260047b9,0x250047b9,
0x220047b9,0x4f0047b9,0x7a0047b9,0xd50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf90047b9,0xd80047b9,0x8a0047b9,0x400047b9,0x200047b9,0x220047b9,0x370047b9,0x720047b9,0xb80047b9,0xd30047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xce0047b9,0x780047b9,0x1b0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf60047b9,0xe80047b9,0xe10047b9,0xda0047b9,0xdb0047b9,0xda0047b9,0xdb0047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd70047b9,0xf00047b9,0xff0047b9,0xfa0047b9,0xf90047b9,0xf70047b9,0xf80047b9,0xf60047b9,0xf60047b9,0xf60047b9,0xf80047b9,
0xf70047b9,0xf90047b9,0xf80047b9,0xfc0047b9,0xfa0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,0x380047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x250047b9,0xac0047b9,0xff0047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xd30047b9,0x650047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,
0x40047b9,0x6d0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xe30047b9,0xb30047b9,0x680047b9,0x340047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x180047b9,0x760047b9,0xbc0047b9,0xe80047b9,0xf20047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xeb0047b9,0x960047b9,0x210047b9,0x0,0x0,0x0,0x0,0x100047b9,0x570047b9,0x710047b9,0xaa0047b9,0xd50047b9,0xf30047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0x740047b9,
0x2a0047b9,0x10047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xdc0047b9,0x810047b9,0x590047b9,0x2b0047b9,0x310047b9,0x270047b9,0x290047b9,0x250047b9,
0x260047b9,0x260047b9,0x260047b9,0x210047b9,0x3d0047b9,0x4a0047b9,0x450047b9,0x430047b9,0x440047b9,0x420047b9,0x410047b9,0x410047b9,0x430047b9,0x420047b9,
0x450047b9,0x4b0047b9,0x490047b9,0x7a0047b9,0xab0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x610047b9,0xa0047b9,0x60047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x350047b9,0xd00047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0x990047b9,0x2b0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,
0x3f0047b9,0xa80047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0x9b0047b9,0x3d0047b9,0xe0047b9,0xa0047b9,0x10047b9,0x0,0x0,0x0,0x0,
0x0,0x10047b9,0x40047b9,0x160047b9,0x180047b9,0x5f0047b9,0xc30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xe00047b9,0x5a0047b9,0x0,0x0,0x0,0x0,0x0,0x40047b9,0x120047b9,0x120047b9,0x2c0047b9,0x560047b9,0xb10047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0xce0047b9,
0x780047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x380047b9,0x910047b9,0xc70047b9,0xe00047b9,0xde0047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xa40047b9,0x3c0047b9,0xc0047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x30047b9,0x0,0x670047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x4d0047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x1d0047b9,
0x950047b9,0xee0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe60047b9,0x9f0047b9,0x380047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x5e0047b9,0xbf0047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xdc0047b9,0x420047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x500047b9,
0xa20047b9,0xf10047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xd60047b9,0x740047b9,0x220047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6c0047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x30047b9,0xb0047b9,0x1c0047b9,0x220047b9,0x320047b9,0x4e0047b9,0xb40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xc40047b9,0x5f0047b9,0x120047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x90047b9,0x260047b9,0x880047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xcb0047b9,0x2e0047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0047b9,
0xc80047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xc70047b9,0x400047b9,0x30047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0x90047b9,0x480047b9,0xce0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xe30047b9,0x5f0047b9,0x0,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x100047b9,
0x1c0047b9,0x780047b9,0xd70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xff0047b9,0xc70047b9,0x540047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x470047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x500047b9,0xb70047b9,0xe60047b9,0xf90047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xf60047b9,0x980047b9,0x1c0047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x120047b9,0x660047b9,0xc60047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfc0047b9,0xff0047b9,0x980047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x550047b9,
0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfc0047b9,0xe60047b9,0x730047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6c0047b9,0xde0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xe90047b9,0x840047b9,0x230047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0xe0047b9,0x720047b9,0xd10047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xb30047b9,0x4b0047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x570047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x100047b9,0x170047b9,0x560047b9,0xdb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xb30047b9,0x160047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x150047b9,0x860047b9,0xef0047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf60047b9,0xd90047b9,0x770047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,0x2e0047b9,0x8b0047b9,
0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf70047b9,0x9d0047b9,0x2e0047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0xd0047b9,0x790047b9,0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xec0047b9,0x9c0047b9,0x3b0047b9,0xc0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x20047b9,0x90047b9,0x600047b9,0xd20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xfe0047b9,0xa20047b9,0x1f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x5c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x740047b9,0xe00047b9,
0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x2e0047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x230047b9,0xba0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xed0047b9,0x990047b9,0x390047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x130047b9,0x5f0047b9,0xc30047b9,
0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd40047b9,0x490047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0047b9,0xaa0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf00047b9,0xb20047b9,0x530047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x710047b9,0xda0047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0x770047b9,0x80047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x5b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0047b9,0x520047b9,
0xdc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x490047b9,0x0,0x10047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x280047b9,0xd00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xea0047b9,0x7a0047b9,0x110047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x140047b9,0x670047b9,0xcb0047b9,
0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xff0047b9,0xb70047b9,0x2a0047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160047b9,0x6f0047b9,0xcd0047b9,0xf40047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xef0047b9,0xb00047b9,0x510047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0xf0047b9,0x790047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xcb0047b9,0x5d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x590047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x700047b9,0xef0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x790047b9,0x100047b9,0x50047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x30047b9,0x0,0x4d0047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xdd0047b9,0x450047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x910047b9,0xef0047b9,
0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,
0xf00047b9,0x860047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x1d0047b9,0x7f0047b9,0xea0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf30047b9,0xc00047b9,0x610047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x180047b9,0x870047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xbb0047b9,0x340047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x560047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,
0x0,0x9c0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xed0047b9,0x990047b9,0x370047b9,0xc0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x70047b9,0x140047b9,0x700047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd50047b9,0x2d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x140047b9,0xb20047b9,0xff0047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,
0xcf0047b9,0x6d0047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x540047b9,0xf10047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf40047b9,0xcb0047b9,0x6c0047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x70047b9,0x210047b9,0x910047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xda0047b9,0x670047b9,0x140047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x5f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x390047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb50047b9,0x560047b9,0x120047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0xc0047b9,0x330047b9,0x950047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,
0xff0047b9,0xb50047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x2f0047b9,0xd90047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xed0047b9,
0xa10047b9,0x440047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200047b9,0xca0047b9,0xff0047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf80047b9,0xeb0047b9,0x8a0047b9,0x1b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x320047b9,0xc60047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc30047b9,0x560047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1c0047b9,0x970047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,0xad0047b9,0x4e0047b9,0xf0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0xb0047b9,0x380047b9,0x9a0047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,
0xfe0047b9,0xa00047b9,0x1c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x4f0047b9,0xdf0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,
0x910047b9,0x310047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0047b9,0x9e0047b9,0xf50047b9,
0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfc0047b9,0xff0047b9,0xa00047b9,0x1d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0047b9,0x860047b9,0xdf0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0x900047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x720047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x40047b9,0x290047b9,0x9f0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xc40047b9,0x630047b9,0x130047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x110047b9,0x550047b9,0xb50047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,
0xdd0047b9,0x790047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x90047b9,0x720047b9,0xea0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x740047b9,0x140047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x5b0047b9,0xc30047b9,
0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xc10047b9,0x210047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2a0047b9,0x920047b9,0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd30047b9,0x370047b9,0x0,0x30047b9,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x40047b9,0x40047b9,0x780047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xdd0047b9,0x7c0047b9,0x170047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6e0047b9,0xcd0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,
0xc70047b9,0x680047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x90047b9,0x1a0047b9,0x7d0047b9,0xe80047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6a0047b9,0x90047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x3b0047b9,0xa00047b9,
0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xd00047b9,0x1b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x550047b9,0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,0x690047b9,0x130047b9,0x70047b9,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x3c0047b9,0xd10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xfd0047b9,0x9a0047b9,0x1d0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x1b0047b9,0x8b0047b9,0xeb0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,
0xa80047b9,0x4b0047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x2d0047b9,0x8c0047b9,0xea0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,
0x590047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,0xa0047b9,0x670047b9,
0xe20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x310047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x170047b9,0xa60047b9,0xff0047b9,0xfc0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xc10047b9,0x580047b9,0xe0047b9,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x350047b9,0xc30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xa40047b9,0x1d0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x190047b9,0x8e0047b9,0xf70047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,
0xa00047b9,0x400047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x300047b9,0x8f0047b9,0xeb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe00047b9,
0x510047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x490047b9,
0xdc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x500047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100047b9,0x5c0047b9,0xbd0047b9,0xf50047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0x920047b9,0xd0047b9,0x0,0x0,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x250047b9,0xb70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbe0047b9,0x220047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x1d0047b9,0xaf0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe90047b9,
0x890047b9,0x2a0047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xc0047b9,0x3c0047b9,0x9b0047b9,0xec0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,
0x4c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x220047b9,
0xb60047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe60047b9,0x710047b9,0xa0047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0xe0047b9,0x6d0047b9,0xe50047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,0x310047b9,0x0,0x10047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x2d0047b9,0xbc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,0x250047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x220047b9,0xce0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe80047b9,
0x7f0047b9,0x1e0047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x440047b9,0xa40047b9,0xed0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe00047b9,
0x4f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0047b9,
0x920047b9,0xef0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe60047b9,0x790047b9,0x180047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x4c0047b9,0xe40047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,0x550047b9,0x0,0x40047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x270047b9,0xb30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,0x260047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x2a0047b9,0xe60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,
0x680047b9,0x50047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x4b0047b9,0xab0047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,
0x500047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100047b9,
0x660047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x8f0047b9,0x300047b9,0xc0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0047b9,0xae0047b9,0xff0047b9,
0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0x910047b9,0x260047b9,0x90047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x200047b9,0xa10047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,0x230047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x320047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,
0x580047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x480047b9,0xa80047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,
0x500047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x110047b9,
0x5b0047b9,0xbc0047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x9b0047b9,0x3b0047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x190047b9,0x7d0047b9,0xd70047b9,
0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xaf0047b9,0x4a0047b9,0xe0047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x240047b9,0xa40047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,0x290047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0xd0047b9,0x3c0047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdd0047b9,
0x460047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x470047b9,0xa60047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe00047b9,
0x4f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,
0x300047b9,0x930047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,0xb10047b9,0x520047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,0x340047b9,0x9a0047b9,
0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xe70047b9,0x8b0047b9,0x180047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x2b0047b9,0xb80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,0x310047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x120047b9,0x3f0047b9,0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,
0x420047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x470047b9,0xa70047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,
0x4a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,
0xf0047b9,0x780047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xbb0047b9,0x5c0047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x110047b9,0x7a0047b9,
0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xb00047b9,0x150047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x310047b9,0xc40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x3d0047b9,0x100047b9,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x280047b9,0x510047b9,0xe00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,
0x340047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x470047b9,0xa70047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe00047b9,
0x550047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,
0x0,0x490047b9,0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xda0047b9,0x790047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x450047b9,
0xdc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,0x300047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb00047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x2d0047b9,0xc40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,0x450047b9,0x1a0047b9,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x410047b9,0x650047b9,0xe40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,
0x2a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x470047b9,0xa60047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x6a0047b9,0x90047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x2d0047b9,0xd00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xf20047b9,0x8f0047b9,0x190047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2f0047b9,
0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x490047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xae0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x380047b9,0xd10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,0x4d0047b9,0x220047b9,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x510047b9,0x700047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,
0x220047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x480047b9,0xa80047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe80047b9,
0x7b0047b9,0x1c0047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x150047b9,0xb90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xaf0047b9,0x1d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x140047b9,
0xb20047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe90047b9,0x780047b9,0x90047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xab0047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa70047b9,0x470047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x3b0047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,0x500047b9,0x250047b9,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x490047b9,0x6b0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,
0x240047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x4b0047b9,0xaa0047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x7c0047b9,0x1a0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1e0047b9,0xb10047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb90047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,
0x920047b9,0xf00047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x930047b9,0x250047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb30047b9,0x1f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa60047b9,0x460047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6a0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x560047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,0x410047b9,0x140047b9,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x480047b9,0x6a0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,
0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x450047b9,0xa50047b9,0xed0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe90047b9,
0x8d0047b9,0x2d0047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x190047b9,0x8b0047b9,0xef0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcf0047b9,0x2b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x130047b9,
0x670047b9,0xc80047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xbc0047b9,0x4c0047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbb0047b9,0x1e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x120047b9,0x730047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0xa10047b9,0x410047b9,0xc0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6b0047b9,0xca0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x20047b9,0x0,0x660047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,0x2c0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x490047b9,0x6a0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,
0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xd0047b9,0x400047b9,0x9d0047b9,0xee0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xed0047b9,
0x9d0047b9,0x3e0047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x130047b9,0x670047b9,0xc80047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,0x400047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x110047b9,
0x540047b9,0xb60047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xc90047b9,0x570047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcd0047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x100047b9,0x740047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xab0047b9,0x4b0047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x690047b9,0xc90047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x50047b9,0x210047b9,0xb10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x1e0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x490047b9,0x6a0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,
0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x2d0047b9,0x8d0047b9,0xea0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,
0xb00047b9,0x510047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0xf0047b9,0x4a0047b9,0xa90047b9,0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x5d0047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,
0x390047b9,0x960047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xef0047b9,0x760047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x2f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0xe0047b9,0x710047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb90047b9,0x5c0047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x120047b9,0x670047b9,0xc60047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x710047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x80047b9,0x680047b9,0xe50047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,0x260047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x480047b9,0x6a0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,
0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,0x1e0047b9,0x7f0047b9,0xe80047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,
0xaf0047b9,0x4f0047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x100047b9,0x520047b9,0xb10047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x650047b9,0x20047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,
0x2f0047b9,0x8e0047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0x840047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,0x450047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,
0x150047b9,0x760047b9,0xe60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xdb0047b9,0x780047b9,0x160047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x150047b9,0x6c0047b9,0xcc0047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x6a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x380047b9,0xc80047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd30047b9,0x250047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x490047b9,0x6b0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,
0x250047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x50047b9,0x670047b9,0xe20047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,
0xc10047b9,0x5f0047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0xc0047b9,0x3b0047b9,0x9c0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe80047b9,0x830047b9,0x220047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,
0x180047b9,0x770047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe00047b9,0x4f0047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90047b9,
0x1e0047b9,0x7d0047b9,0xe80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xf30047b9,0x8b0047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x160047b9,0x740047b9,0xd10047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x5e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x580047b9,0xef0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb90047b9,0x230047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x510047b9,0x700047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,
0x1f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x5d0047b9,0xe20047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,
0xcb0047b9,0x6a0047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0xa0047b9,0x220047b9,0x830047b9,0xe80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x9c0047b9,0x3b0047b9,0xc0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,
0xa0047b9,0x6e0047b9,0xe40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb00047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe60047b9,0x710047b9,0xd0047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,
0x280047b9,0x880047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xb20047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x180047b9,0x830047b9,0xe60047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x580047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0047b9,
0x480047b9,0xcd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa60047b9,0x1d0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x410047b9,0x650047b9,0xe40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,
0x2d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x420047b9,0xe00047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,
0xec0047b9,0x8f0047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x50047b9,0x20047b9,0x650047b9,0xe20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0xb10047b9,0x540047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x550047b9,0xe10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc10047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe90047b9,0x860047b9,0x280047b9,0x80047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,
0x290047b9,0x880047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd00047b9,0x240047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x130047b9,0x8c0047b9,0xf60047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x5b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0047b9,
0xc70047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xa90047b9,0x1e0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x280047b9,0x510047b9,0xe00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdd0047b9,
0x460047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2f0047b9,0xe40047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,
0xff0047b9,0xb40047b9,0x1c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x20047b9,0x0,0x5b0047b9,0xe20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,0xac0047b9,0x4e0047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,
0x0,0x440047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc30047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xc80047b9,0x650047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,
0x3e0047b9,0xa10047b9,0xee0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x4e0047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x230047b9,0xb00047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x5b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x2b0047b9,0xb60047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xf20047b9,0x930047b9,0x1a0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x120047b9,0x3f0047b9,0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,
0x5a0047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1d0047b9,0xcf0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd70047b9,0x270047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x410047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xc50047b9,0x630047b9,0x130047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x2f0047b9,0xdb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc90047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xff0047b9,0x930047b9,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,
0x4c0047b9,0xb40047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe70047b9,0x6e0047b9,0xd0047b9,0x30047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x2a0047b9,0xce0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x5a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x450047b9,0xd70047b9,0xff0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xd90047b9,0x7a0047b9,0x170047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0xd0047b9,0x3c0047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,
0x5a0047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0047b9,0xb60047b9,0xff0047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd90047b9,0x290047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x2f0047b9,0xe20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xdd0047b9,0x7c0047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x280047b9,0xda0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcb0047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcf0047b9,0x3a0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,
0x880047b9,0xe00047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xbc0047b9,0x5d0047b9,0xe0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x20047b9,0x720047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x560047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40047b9,0x260047b9,0x4d0047b9,0x5d0047b9,0xd30047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xbc0047b9,0x5d0047b9,0x100047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x320047b9,0xde0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x690047b9,0x80047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180047b9,0x870047b9,0xf00047b9,
0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xe20047b9,0x4c0047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1e0047b9,0xd10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xfd0047b9,0x9b0047b9,0x1d0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x220047b9,0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xce0047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe10047b9,0x7c0047b9,0x190047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x210047b9,
0xc50047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xa40047b9,0x80047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x4c0047b9,0xbb0047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x3a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x130047b9,0xad0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xb70047b9,0x5a0047b9,0x100047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x2a0047b9,0xe60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,
0x780047b9,0x180047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x150047b9,0x6e0047b9,0xcf0047b9,
0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xe40047b9,0x6e0047b9,0x100047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x210047b9,0xba0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xa20047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x240047b9,0xda0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd10047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xd10047b9,0x740047b9,0x2b0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90047b9,0x7b0047b9,
0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0x640047b9,0x70047b9,0x20047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x350047b9,
0xaa0047b9,0xfc0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x800047b9,0x110047b9,0x250047b9,0x1c0047b9,0x140047b9,0x70047b9,0x80047b9,0x20047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x60047b9,0x150047b9,0x240047b9,0x250047b9,0x260047b9,0x130047b9,0x7f0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x950047b9,0x350047b9,0xa0047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x220047b9,0xce0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,
0x8f0047b9,0x300047b9,0xc0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0047b9,0x430047b9,0xa40047b9,
0xee0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xeb0047b9,0x980047b9,0x360047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1e0047b9,0xa50047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbf0047b9,0x240047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xfc0047b9,0xce0047b9,0x780047b9,0x160047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6e0047b9,0xdc0047b9,
0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xd20047b9,0x720047b9,0xe0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x150047b9,0x7b0047b9,
0xda0047b9,0xfe0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe80047b9,0xd20047b9,0xd10047b9,0x9b0047b9,0x630047b9,0x260047b9,0x130047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1d0047b9,0x730047b9,0xc30047b9,0xd40047b9,0xdb0047b9,0xd40047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x790047b9,0xe0047b9,0x60047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x1d0047b9,0xaf0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,
0x9b0047b9,0x3b0047b9,0xb0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x360047b9,0x990047b9,
0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xee0047b9,0xa40047b9,0x430047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1d0047b9,0xa30047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd40047b9,0x300047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd50047b9,0x760047b9,0x340047b9,0x100047b9,
0xe0047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x150047b9,0xf0047b9,0x5e0047b9,0xd30047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x760047b9,0x210047b9,
0x180047b9,0x40047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,0xc0047b9,0x320047b9,0x760047b9,0xd20047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc40047b9,0x870047b9,0x740047b9,0x530047b9,
0x440047b9,0x390047b9,0x410047b9,0x3b0047b9,0x2a0047b9,0x250047b9,0x260047b9,0x280047b9,0x250047b9,0x290047b9,0x2b0047b9,0x320047b9,0x310047b9,0x3d0047b9,
0x390047b9,0x810047b9,0xe40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x490047b9,0x0,0x10047b9,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x190047b9,0x8e0047b9,0xf70047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,
0xb10047b9,0x520047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x100047b9,0x6d0047b9,
0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf50047b9,0xcf0047b9,0x6c0047b9,0x140047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1c0047b9,0x970047b9,0xf80047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe50047b9,0x470047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfa0047b9,0xda0047b9,0xaf0047b9,0x6e0047b9,
0x450047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x710047b9,0x950047b9,0xd50047b9,0xf40047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xec0047b9,0xbf0047b9,
0x740047b9,0x180047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0047b9,0x550047b9,0xa40047b9,0xd70047b9,0xf90047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf80047b9,0xff0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xf40047b9,0xe90047b9,0xe50047b9,0xe00047b9,
0xde0047b9,0xdc0047b9,0xdf0047b9,0xdc0047b9,0xdb0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xda0047b9,0xdb0047b9,0xdc0047b9,0xdb0047b9,0xdd0047b9,
0xdb0047b9,0xe80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x2e0047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x1b0047b9,0x8b0047b9,0xeb0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,
0xbb0047b9,0x5c0047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x490047b9,
0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf90047b9,0xf00047b9,0x870047b9,0x160047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1a0047b9,0x8f0047b9,0xf00047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x500047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x260047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcf0047b9,
0xa70047b9,0x600047b9,0x350047b9,0x220047b9,0x260047b9,0x260047b9,0x210047b9,0x3b0047b9,0x7d0047b9,0xd00047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xd50047b9,0x7a0047b9,0x4f0047b9,0x220047b9,0x250047b9,0x260047b9,0x240047b9,0x2b0047b9,0x410047b9,0x7e0047b9,0xb60047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xe80047b9,0xe80047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xb30047b9,0x160047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x140047b9,0x6e0047b9,0xcd0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,
0xda0047b9,0x770047b9,0x160047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x230047b9,
0xb60047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xff0047b9,0xb70047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1a0047b9,0x880047b9,0xea0047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe60047b9,0x720047b9,0xe0047b9,0x50047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x250047b9,0xda0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf50047b9,
0xee0047b9,0xe30047b9,0xda0047b9,0xd80047b9,0xd90047b9,0xd90047b9,0xd80047b9,0xdb0047b9,0xe60047b9,0xf60047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xf60047b9,0xe60047b9,0xe00047b9,0xd80047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xda0047b9,0xdc0047b9,0xe70047b9,0xf10047b9,0xfc0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xdb0047b9,0xd90047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xf60047b9,0x980047b9,0x1c0047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x110047b9,0x550047b9,0xb50047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,
0xf30047b9,0x8b0047b9,0x150047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1d0047b9,
0x990047b9,0xf60047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xcf0047b9,0x210047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1a0047b9,0x8b0047b9,0xec0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x8b0047b9,0x290047b9,0xb0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x1f0047b9,0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xc50047b9,0xbe0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xc40047b9,0x5f0047b9,0x120047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0xb0047b9,0x380047b9,0x9a0047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,
0xff0047b9,0xb20047b9,0x220047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100047b9,
0x5f0047b9,0xc40047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x530047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1a0047b9,0x8b0047b9,0xec0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0x9f0047b9,0x420047b9,0xe0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x2d0047b9,0xdb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd10047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xbb0047b9,0xb20047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xa40047b9,0x3c0047b9,0xc0047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0xc0047b9,0x330047b9,0x950047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xcf0047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,
0x3c0047b9,0xa40047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe90047b9,0x830047b9,0x280047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1a0047b9,0x880047b9,0xea0047b9,0xf60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x9a0047b9,0x3b0047b9,0xb0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x460047b9,0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xce0047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xee0047b9,0xa10047b9,0x8e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdd0047b9,0x610047b9,0xb0047b9,0x60047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x70047b9,0x140047b9,0x700047b9,0xe70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xea0047b9,0x4c0047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,
0xb0047b9,0x610047b9,0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xcb0047b9,0x660047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1b0047b9,0x8e0047b9,0xf10047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xef0047b9,0xb30047b9,0x530047b9,0xf0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x590047b9,0xe20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xcb0047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8e0047b9,0x7a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,0x340047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x30047b9,0x0,0x4d0047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xe30047b9,0x670047b9,0x90047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x340047b9,0xd20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xef0047b9,0x820047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1a0047b9,0x930047b9,0xf90047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xcb0047b9,0x6c0047b9,0x150047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x560047b9,0xe10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc90047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe60047b9,0x650047b9,0x440047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0x900047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x280047b9,0xd00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xed0047b9,0xa00047b9,0x3d0047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0xa0047b9,0x900047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xba0047b9,0x2c0047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1c0047b9,0xa70047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xec0047b9,0x8b0047b9,0x1b0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,
0xd0047b9,0x6c0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc30047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf20047b9,0x490047b9,0x180047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0xc20047b9,0x560047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x230047b9,0xba0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf30047b9,0xc30047b9,0x5f0047b9,0x100047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0xe0047b9,0x570047b9,0xbd0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0x480047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x160047b9,0xb80047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xf70047b9,0x8e0047b9,0x190047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,
0x260047b9,0x850047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc10047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xcb0047b9,0x250047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x680047b9,0x130047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x150047b9,0x840047b9,0xed0047b9,0xf90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfa0047b9,0xf60047b9,0x990047b9,0x1e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x70047b9,0x120047b9,0x6e0047b9,0xe10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0x9c0047b9,0x300047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x2d0047b9,0xd00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xaf0047b9,0x1e0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,
0x440047b9,0xa30047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb00047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xf70047b9,0xa20047b9,0x1f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,0x390047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x120047b9,0x620047b9,0xc40047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xff0047b9,0xb50047b9,0x1f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x30047b9,0x0,0x4c0047b9,0xd60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xe60047b9,0x750047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x10047b9,0x0,0x4a0047b9,0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xce0047b9,0x1d0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100047b9,
0x4e0047b9,0xae0047b9,0xee0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xc20047b9,0x560047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf80047b9,0x840047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x90047b9,0x2a0047b9,0x8c0047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,0x4c0047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x1a0047b9,0x940047b9,0xfd0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc60047b9,0x380047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x40047b9,0xe0047b9,0x760047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,0x2f0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x130047b9,
0x640047b9,0xc30047b9,0xf50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0x840047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0x960047b9,0x280047b9,0x90047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x920047b9,0x210047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x60047b9,0xe0047b9,0x790047b9,0xf10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,0x710047b9,0x140047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x110047b9,0x590047b9,0xc10047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,0x7b0047b9,0x1a0047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x10047b9,0x210047b9,0x890047b9,0xe80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x3e0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x110047b9,
0x690047b9,0xcb0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xef0047b9,0x760047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfc0047b9,0xf60047b9,0xf30047b9,0xed0047b9,0xf30047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xf40047b9,0xe30047b9,0xc80047b9,0xd30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xff0047b9,0xd50047b9,0x500047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xff0047b9,0xc10047b9,0x320047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x10047b9,0x0,0x480047b9,0xd50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xb90047b9,0x550047b9,0xe0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x30047b9,0x120047b9,0x680047b9,0xdd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd30047b9,0x740047b9,0x1e0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x150047b9,0x6b0047b9,0xc60047b9,0xf30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,0x5f0047b9,0x0,0x30047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0047b9,
0x900047b9,0xeb0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0xc90047b9,0x570047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf50047b9,0xd60047b9,0xb70047b9,0xa70047b9,0xc50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfb0047b9,0xc40047b9,0x7f0047b9,0x4f0047b9,0x870047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfd0047b9,0xff0047b9,0xb60047b9,0x2d0047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xd50047b9,0x730047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x2b0047b9,0xbb0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xea0047b9,0x7e0047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x20047b9,0x0,0x360047b9,0xc80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xc30047b9,0x450047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x180047b9,0xa90047b9,0xff0047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe40047b9,0x750047b9,0x140047b9,0x70047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x220047b9,
0xb40047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xbc0047b9,0x4c0047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf30047b9,0xcf0047b9,0x8a0047b9,0x470047b9,0x620047b9,0xd10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xe30047b9,0x700047b9,0x1b0047b9,0x0,0x2f0047b9,0xb70047b9,0xf70047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfa0047b9,0xd10047b9,0x610047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xd50047b9,0x7a0047b9,0x1b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x840047b9,0xee0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbe0047b9,0x2d0047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x730047b9,0xe30047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa20047b9,0x3d0047b9,0x170047b9,0x10047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,
0xf0047b9,0x7c0047b9,0xed0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x920047b9,0x320047b9,0xc0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x4a0047b9,
0xdc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x930047b9,0x250047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf60047b9,0xe80047b9,0x8a0047b9,0xe0047b9,0xa0047b9,0x920047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xde0047b9,0x3a0047b9,0x0,0x30047b9,0x100047b9,0x400047b9,0xa20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0x8c0047b9,0x190047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xf70047b9,0x990047b9,0x310047b9,0x0,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x110047b9,0x660047b9,0xcb0047b9,0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x4c0047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x20047b9,0x1e0047b9,0x8e0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf40047b9,0xbc0047b9,0x530047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x130047b9,
0x830047b9,0xeb0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xeb0047b9,0x9c0047b9,0x3d0047b9,0xa0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,0xe0047b9,0x690047b9,
0xe20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe90047b9,0x780047b9,0x90047b9,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf90047b9,0xf20047b9,0x850047b9,0x0,0x0,0x360047b9,0x9e0047b9,0xd90047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xf70047b9,0x840047b9,0x30047b9,0x0,0x0,0x0,0x0,0x3e0047b9,0xa10047b9,0xf60047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xfd0047b9,0xbf0047b9,0x390047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,
0x9d0047b9,0x3d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x90047b9,0x280047b9,0x820047b9,0xe80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0x990047b9,0x2c0047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x350047b9,0xc20047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb40047b9,0x520047b9,
0x270047b9,0xe0047b9,0xe0047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x160047b9,0x1a0047b9,0x7b0047b9,
0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xb20047b9,0x530047b9,0x110047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x370047b9,0x9c0047b9,
0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x490047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf70047b9,0xee0047b9,0x8b0047b9,0x120047b9,0x0,0x40047b9,0x360047b9,0x870047b9,0xe90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0x920047b9,0x230047b9,0x40047b9,0x0,0x0,0x0,0x10047b9,0x100047b9,0x290047b9,0x910047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xc50047b9,0x610047b9,0x190047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,0x990047b9,
0x390047b9,0x50047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x30047b9,0x0,0x510047b9,0xe40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xd50047b9,0x630047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0047b9,0x730047b9,0xd30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf30047b9,0xd10047b9,
0x9d0047b9,0x5d0047b9,0x420047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x170047b9,0x730047b9,0xa80047b9,0xed0047b9,
0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xbe0047b9,0x5f0047b9,0x110047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x490047b9,0xb20047b9,
0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,0x300047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf70047b9,0xed0047b9,0x8e0047b9,0x1f0047b9,0x0,0x0,0x0,0x2b0047b9,0x890047b9,0xca0047b9,0xf60047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf70047b9,0x9f0047b9,
0x2b0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2b0047b9,0x9b0047b9,0xf30047b9,0xf70047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xc60047b9,
0x660047b9,0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xd50047b9,0x9d0047b9,0x3b0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1b0047b9,0xae0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xb50047b9,0x320047b9,0x0,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1b0047b9,0x7a0047b9,0xd90047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xfa0047b9,0xbe0047b9,0xa10047b9,0x650047b9,0x340047b9,0x220047b9,0x260047b9,0x260047b9,0x210047b9,0x3b0047b9,0x780047b9,0xd60047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf60047b9,0xd60047b9,0x750047b9,0x170047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x190047b9,0x8d0047b9,0xe30047b9,
0xf70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,0xb00047b9,0x150047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf70047b9,0xed0047b9,0x8c0047b9,0x1b0047b9,0x0,0x0,0x0,0x60047b9,0x260047b9,0x510047b9,0xb40047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x8f0047b9,0x290047b9,
0xc0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90047b9,0x1a0047b9,0x780047b9,0xd70047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc60047b9,0x620047b9,
0x230047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x750047b9,0x320047b9,0x70047b9,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x190047b9,0x7f0047b9,0xdd0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfe0047b9,0xd90047b9,0x680047b9,0x120047b9,0x30047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x340047b9,0xab0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xfc0047b9,0xf10047b9,0xee0047b9,0xe30047b9,0xda0047b9,0xd80047b9,0xd90047b9,0xd90047b9,0xd80047b9,0xdb0047b9,0xe60047b9,0xf70047b9,0xfe0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf50047b9,0xe10047b9,0x7d0047b9,0x170047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200047b9,0xc60047b9,0xff0047b9,
0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xe70047b9,0x8b0047b9,0x180047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf70047b9,0xed0047b9,0x8c0047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x530047b9,0xbb0047b9,0xef0047b9,
0xf50047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xf60047b9,0x9f0047b9,0x2b0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0047b9,0x750047b9,0xcd0047b9,
0xdf0047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xf40047b9,0xc00047b9,0x650047b9,0x90047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xef0047b9,0xc20047b9,0x760047b9,0x190047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80047b9,0x300047b9,0x960047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc10047b9,0x570047b9,0x110047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4d0047b9,0xb10047b9,0xec0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf20047b9,0xb50047b9,0xb80047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xfb0047b9,0x9d0047b9,0x1b0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x530047b9,0xf60047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf10047b9,0xaf0047b9,0x4a0047b9,0xe0047b9,0x0,
0xda0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xf70047b9,0xeb0047b9,0x8b0047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x170047b9,0x380047b9,0x840047b9,
0xc80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,0x890047b9,0x310047b9,0xd0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x110047b9,0x390047b9,
0x770047b9,0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf20047b9,0x9f0047b9,0x430047b9,0x1b0047b9,0x10047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdc0047b9,0x870047b9,0x350047b9,0x1c0047b9,0x30047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x730047b9,0x8a0047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x8a0047b9,0x730047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40047b9,0x0,0x690047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xfd0047b9,0x920047b9,0x100047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x50047b9,0x450047b9,0xd00047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe90047b9,0x520047b9,0x550047b9,0xe60047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xb70047b9,0x1c0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x1d0047b9,0x810047b9,0xeb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0x910047b9,0x260047b9,0x90047b9,0x0,
0xe30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xf40047b9,0x900047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x210047b9,
0x670047b9,0xb60047b9,0xd80047b9,0xf00047b9,0xf50047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf90047b9,0xe10047b9,0xc90047b9,0x780047b9,0x230047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x150047b9,0x780047b9,0xc20047b9,0xe90047b9,0xea0047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf80047b9,0xe40047b9,0xda0047b9,0x8e0047b9,0x3b0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xfe0047b9,0xf50047b9,0xef0047b9,0xdc0047b9,0xc90047b9,0x790047b9,0x230047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x780047b9,0x8e0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0x8e0047b9,0x780047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2b0047b9,0xad0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x580047b9,0x0,0x20047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6c0047b9,0xda0047b9,
0xf00047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xec0047b9,0x800047b9,0x0,0xf0047b9,0xd30047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd40047b9,0x260047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180047b9,0x6f0047b9,0xcd0047b9,0xf40047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdb0047b9,0x550047b9,0x0,0x40047b9,0x0,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xa80047b9,0x200047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60047b9,
0x110047b9,0x310047b9,0x5f0047b9,0xa80047b9,0xcf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0x790047b9,0x3a0047b9,0x110047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x40047b9,0x1a0047b9,0x310047b9,0x680047b9,0x8f0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd50047b9,0x790047b9,0x3c0047b9,0x140047b9,0xd0047b9,0x10047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xcf0047b9,0xa70047b9,0x610047b9,0x340047b9,0x120047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x8b0047b9,0xa90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa90047b9,0x8b0047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x190047b9,0x6e0047b9,0xce0047b9,0xfb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe90047b9,0xa30047b9,0x3a0047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x90047b9,0x5e0047b9,
0xc30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x800047b9,0x60047b9,0x30047b9,0x1d0047b9,0xcf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x2b0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x240047b9,0xac0047b9,0xff0047b9,0xfc0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd20047b9,0x310047b9,0x0,0x10047b9,0x0,
0xb10047b9,0xdc0047b9,0xda0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xdb0047b9,0xd20047b9,0xc40047b9,0x740047b9,0x160047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x450047b9,0x700047b9,0xac0047b9,0xce0047b9,0xde0047b9,0xeb0047b9,0xf40047b9,0xeb0047b9,0xf00047b9,0xfb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xef0047b9,
0xf10047b9,0xec0047b9,0xea0047b9,0xe30047b9,0xe20047b9,0xa90047b9,0x740047b9,0x180047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x20047b9,0x300047b9,0x820047b9,0xc30047b9,0xe00047b9,0xe80047b9,0xf00047b9,0xed0047b9,0xf00047b9,0xf10047b9,0xfa0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xf30047b9,
0xf10047b9,0xea0047b9,0xe90047b9,0xe30047b9,0xe20047b9,0xa90047b9,0x740047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf10047b9,0xea0047b9,0xf20047b9,0xeb0047b9,
0xe20047b9,0xcc0047b9,0xac0047b9,0x700047b9,0x450047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x600047b9,0x740047b9,0xc20047b9,0xdf0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xdf0047b9,0xc20047b9,0x740047b9,0x600047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x1d0047b9,0x800047b9,0xe40047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf10047b9,0x9a0047b9,0x2d0047b9,0x0,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x5e0047b9,0xbe0047b9,0xe20047b9,0xfc0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfb0047b9,0xf40047b9,0x980047b9,0x170047b9,0x0,0x0,0x180047b9,0xba0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe30047b9,0x490047b9,0x0,
0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x60047b9,0x710047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0x920047b9,0xd0047b9,0x0,0x0,0x0,
0x1f0047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x230047b9,0x150047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x30047b9,0xe0047b9,0x150047b9,0x200047b9,0x1f0047b9,0x3a0047b9,0x890047b9,0xb10047b9,0x8b0047b9,0xae0047b9,0xec0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,0xa50047b9,
0xa80047b9,0x900047b9,0x7f0047b9,0x530047b9,0x320047b9,0x1d0047b9,0x150047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x40047b9,0xa0047b9,0x190047b9,0x1f0047b9,0x370047b9,0x750047b9,0xa20047b9,0x930047b9,0xa50047b9,0xb80047b9,0xec0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0xb60047b9,
0xae0047b9,0x8b0047b9,0x7e0047b9,0x530047b9,0x320047b9,0x1d0047b9,0x150047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xbb0047b9,0x920047b9,0xba0047b9,0x940047b9,
0x560047b9,0x1e0047b9,0x200047b9,0x150047b9,0xe0047b9,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x120047b9,0x130047b9,0x240047b9,0x280047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x280047b9,0x240047b9,0x130047b9,0x120047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x0,0x500047b9,0xdb0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xd20047b9,0x660047b9,0xa0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,
0xc0047b9,0x3b0047b9,0x870047b9,0xeb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x7c0047b9,0x170047b9,0x50047b9,0x0,0x0,0x1e0047b9,0xac0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x610047b9,0x40047b9,
0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4d0047b9,0xba0047b9,0xf20047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xc10047b9,0x580047b9,0xe0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb0047b9,0x6f0047b9,0xa30047b9,0x760047b9,0xa00047b9,0xec0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0x970047b9,
0x990047b9,0x790047b9,0x650047b9,0x2c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x580047b9,0x8f0047b9,0x7e0047b9,0x960047b9,0xac0047b9,0xec0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0xad0047b9,
0x9f0047b9,0x740047b9,0x630047b9,0x2d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xdd0047b9,0xd60047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xda0047b9,0xe10047b9,0xa80047b9,0x5c0047b9,0x320047b9,0x580047b9,0x330047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180047b9,0x900047b9,0xf90047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc30047b9,0x620047b9,
0x1d0047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x290047b9,0x8a0047b9,0xc60047b9,0xec0047b9,0xf50047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xfd0047b9,0xed0047b9,0xe60047b9,0x840047b9,0x130047b9,0x0,0x0,0x0,0x0,0x1c0047b9,0x910047b9,0xf80047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf00047b9,0x870047b9,0x200047b9,
0xa0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x2d0047b9,0xa90047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xdf0047b9,0x690047b9,0x130047b9,0x70047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,0x4d0047b9,0x1b0047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x290047b9,0x1f0047b9,0x100047b9,0x90047b9,0x120047b9,0xb0047b9,
0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0047b9,0x450047b9,0xb20047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xfd0047b9,0xc10047b9,
0x440047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x70047b9,0x210047b9,0x3a0047b9,0x830047b9,0xc70047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xf80047b9,0x9e0047b9,0x5a0047b9,0xf0047b9,0x40047b9,0x0,0x0,0x0,0x0,0x1a0047b9,0x880047b9,0xfe0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xb00047b9,0x3c0047b9,
0xe0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x570047b9,0xd30047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd30047b9,0x370047b9,0x0,0x30047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd00047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x10047b9,0x560047b9,
0xd30047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xa50047b9,0x370047b9,0x110047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x210047b9,0x680047b9,0xb50047b9,0xd10047b9,0xe50047b9,0xea0047b9,0xf30047b9,0xf50047b9,0xfd0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf50047b9,0xf30047b9,0xea0047b9,0xe60047b9,0xcb0047b9,
0x960047b9,0x3d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0047b9,0x4f0047b9,0x9d0047b9,0xca0047b9,0xdd0047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xdf0047b9,0xc30047b9,0x820047b9,0x330047b9,
0xd0047b9,0x0,0x0,0x0,0x0,0x130047b9,0x4f0047b9,0xb00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xff0047b9,0x900047b9,0x60047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x1e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x0,0x2c0047b9,
0xa90047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xf90047b9,0xa10047b9,0x2c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x60047b9,0x130047b9,0x260047b9,0x350047b9,0x640047b9,0x8b0047b9,0xc30047b9,0xd60047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0xc30047b9,0x8b0047b9,0x640047b9,0x340047b9,
0x210047b9,0xa0047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0xe0047b9,0x1d0047b9,0x240047b9,0x270047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x280047b9,0x240047b9,0x160047b9,0x80047b9,
0x30047b9,0x0,0x0,0x0,0x0,0x2f0047b9,0xba0047b9,0xfb0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xc30047b9,0x560047b9,0xd0047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xda0047b9,0x280047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x4e0047b9,0xb60047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0x8f0047b9,0x2a0047b9,0x100047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x2c0047b9,0x620047b9,0x740047b9,0xa80047b9,
0xce0047b9,0xdc0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xdc0047b9,0xce0047b9,0xa80047b9,0x740047b9,0x620047b9,0x2c0047b9,0x10047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x80047b9,0x250047b9,0x940047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xda0047b9,0x670047b9,0x140047b9,0x70047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,
0x0,0x5d0047b9,0xe50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xf60047b9,0xa10047b9,0x3e0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40047b9,0xa0047b9,0x130047b9,0x160047b9,0x1e0047b9,
0x240047b9,0x270047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x270047b9,0x240047b9,0x1e0047b9,0x160047b9,0x130047b9,0xa0047b9,0x40047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x170047b9,0x9a0047b9,0xf80047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xff0047b9,0xbb0047b9,0x340047b9,0x0,0x30047b9,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x90047b9,0x850047b9,0xf30047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,0x410047b9,0x1d0047b9,0x30047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x90047b9,0x110047b9,0x7d0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xcb0047b9,0x5d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x40047b9,0x200047b9,0x920047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf30047b9,0xc40047b9,0x780047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x280047b9,0x860047b9,0xea0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0x770047b9,0x80047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x120047b9,0x130047b9,0x240047b9,0x280047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x280047b9,0x240047b9,0x130047b9,0x120047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x320047b9,0xbe0047b9,0xfd0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd70047b9,0x760047b9,0x340047b9,0xa0047b9,0x20047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x150047b9,
0x330047b9,0x8c0047b9,0xef0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xfe0047b9,0xa20047b9,0x1f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x600047b9,0x740047b9,0xc20047b9,0xdf0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xdf0047b9,0xc20047b9,0x740047b9,0x600047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x180047b9,0x610047b9,0xc50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfa0047b9,0xd80047b9,0xab0047b9,0x4e0047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x540047b9,
0xb90047b9,0xf20047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xb30047b9,0x4b0047b9,0xf0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x8b0047b9,0xa90047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa90047b9,0x8b0047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0xa0047b9,0x660047b9,0xca0047b9,0xfe0047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x5c0047b9,0x190047b9,0x160047b9,0x30047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20047b9,0x80047b9,0x270047b9,0x510047b9,0xb40047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,
0xff0047b9,0xc70047b9,0x540047b9,0x0,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x780047b9,0x8e0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0x8e0047b9,0x780047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x10047b9,0x0,0x260047b9,0x740047b9,0xd60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xef0047b9,0xe60047b9,0xbc0047b9,0x760047b9,0x150047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3d0047b9,0x990047b9,0xcf0047b9,0xf50047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xd60047b9,0x740047b9,0x220047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x730047b9,0x8a0047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x8a0047b9,0x730047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x780047b9,0xce0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x760047b9,
0x3c0047b9,0x1b0047b9,0x150047b9,0x50047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x150047b9,0x160047b9,0x5a0047b9,0x9d0047b9,0xf60047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0xce0047b9,
0x780047b9,0x1a0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x10047b9,0x10047b9,0x2a0047b9,0x740047b9,0xd60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf80047b9,0xe60047b9,
0xe30047b9,0xa90047b9,0x740047b9,0x170047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x170047b9,0x740047b9,0xa70047b9,0xe70047b9,0xee0047b9,0xfb0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0x740047b9,
0x2a0047b9,0x10047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1b0047b9,0x780047b9,0xca0047b9,0xf90047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xd50047b9,0x780047b9,0x3d0047b9,0x1e0047b9,0x160047b9,0xb0047b9,0xc0047b9,0x50047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x80047b9,0x70047b9,0x140047b9,0x1d0047b9,0x3d0047b9,0x780047b9,0xd50047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xfd0047b9,0xce0047b9,0x780047b9,0x1b0047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0x270047b9,0x620047b9,0xc60047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xfe0047b9,0xf70047b9,0xe60047b9,0xe10047b9,0xc10047b9,0x780047b9,0x390047b9,0x3a0047b9,0x70047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x130047b9,0x200047b9,0x6d0047b9,0xbf0047b9,0xe10047b9,0xe60047b9,0xf70047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd60047b9,0x740047b9,0x2b0047b9,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70047b9,0x660047b9,0xc00047b9,0xf40047b9,
0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x9b0047b9,0x9b0047b9,0x6b0047b9,0x360047b9,0x200047b9,0x1f0047b9,0x150047b9,
0x100047b9,0xb0047b9,0x120047b9,0xb0047b9,0x40047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0xa0047b9,0x130047b9,0xf0047b9,0xd0047b9,0xa0047b9,0x140047b9,0x220047b9,0x300047b9,
0x4b0047b9,0x740047b9,0x810047b9,0xcf0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfc0047b9,0xce0047b9,0x780047b9,0x1b0047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x410047b9,0xa10047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf70047b9,0xea0047b9,0xee0047b9,0xe40047b9,0xde0047b9,0xcd0047b9,0xa80047b9,0x710047b9,
0x500047b9,0x3c0047b9,0x560047b9,0x380047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x300047b9,0x5d0047b9,0x460047b9,0x470047b9,0x3f0047b9,0x720047b9,0xc00047b9,0xe10047b9,
0xdf0047b9,0xe60047b9,0xe70047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x730047b9,0x2b0047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3d0047b9,
0x9e0047b9,0xee0047b9,0xf20047b9,0xfe0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd30047b9,
0xb20047b9,0x9d0047b9,0xb70047b9,0x990047b9,0x660047b9,0x350047b9,0x2a0047b9,0x250047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x260047b9,
0x260047b9,0x260047b9,0x260047b9,0x260047b9,0x200047b9,0x400047b9,0x920047b9,0xbe0047b9,0xa70047b9,0xa60047b9,0x9e0047b9,0xd40047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xf30047b9,0xc40047b9,0x770047b9,0x1b0047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10047b9,0xd0047b9,
0x110047b9,0x610047b9,0xc20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf40047b9,
0xf00047b9,0xeb0047b9,0xf10047b9,0xed0047b9,0xe30047b9,0xdb0047b9,0xdb0047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,
0xd90047b9,0xd90047b9,0xd90047b9,0xd90047b9,0xd80047b9,0xdb0047b9,0xeb0047b9,0xf50047b9,0xee0047b9,0xed0047b9,0xed0047b9,0xf50047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,0x410047b9,0x1d0047b9,0x30047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x5f0047b9,0xbc0047b9,0xdb0047b9,0xf60047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xfd0047b9,0xef0047b9,0xec0047b9,0x9e0047b9,0x3d0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x10047b9,0xe0047b9,0x320047b9,0x690047b9,0xc20047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xaf0047b9,0x5e0047b9,0x120047b9,0xd0047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x70047b9,0x620047b9,0xa70047b9,0xe50047b9,0xe60047b9,0xf80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf90047b9,
0xee0047b9,0xd10047b9,0xa90047b9,0x4f0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x20047b9,0x120047b9,0x1b0047b9,0x3c0047b9,0x760047b9,0xd80047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xde0047b9,
0x980047b9,0x4b0047b9,0x290047b9,0xc0047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x150047b9,0x760047b9,0xbe0047b9,0xe10047b9,0xe60047b9,0xf60047b9,
0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf10047b9,0xec0047b9,0xd90047b9,0xc40047b9,0x7d0047b9,
0x380047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30047b9,0x160047b9,0x1f0047b9,0x3c0047b9,0x7d0047b9,0xd00047b9,
0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xba0047b9,0x900047b9,0x520047b9,0x2f0047b9,0x150047b9,
0xb0047b9,0x10047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd90047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x740047b9,0x8b0047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xec0047b9,0x8b0047b9,0x740047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1a0047b9,0x710047b9,
0x980047b9,0xce0047b9,0xdb0047b9,0xe70047b9,0xe80047b9,0xf40047b9,0xfb0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xfd0047b9,0xf40047b9,0xf50047b9,0xea0047b9,0xe40047b9,0xc90047b9,0x9f0047b9,0x580047b9,0x300047b9,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd80047b9,0x250047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x730047b9,0x8a0047b9,0xea0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xea0047b9,0x8a0047b9,0x730047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50047b9,0x150047b9,
0x1a0047b9,0x2c0047b9,0x4a0047b9,0x760047b9,0x880047b9,0xc60047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xd50047b9,0xc50047b9,0x870047b9,0x540047b9,0x1e0047b9,0x1c0047b9,0x110047b9,0xa0047b9,0x10047b9,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe20047b9,0x270047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x780047b9,0x8e0047b9,0xf40047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf40047b9,0x8e0047b9,0x780047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x140047b9,0x290047b9,0x650047b9,0x980047b9,0xcc0047b9,0xd60047b9,0xdc0047b9,0xe40047b9,0xee0047b9,0xee0047b9,0xf00047b9,
0xec0047b9,0xf00047b9,0xf10047b9,0xfa0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfd0047b9,0xf40047b9,0xf00047b9,0xec0047b9,0xf00047b9,0xee0047b9,0xee0047b9,0xe40047b9,
0xde0047b9,0xcd0047b9,0xa70047b9,0x760047b9,0x660047b9,0x260047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0x2c0047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x850047b9,0xa10047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xa10047b9,0x850047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x80047b9,0x80047b9,0x140047b9,0x1d0047b9,0x250047b9,0x220047b9,0x330047b9,0x640047b9,0x910047b9,0x990047b9,0xa10047b9,
0x950047b9,0xa30047b9,0xb60047b9,0xec0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xfe0047b9,0xc70047b9,0xa70047b9,0x910047b9,0xa00047b9,0x990047b9,0x910047b9,0x640047b9,
0x340047b9,0x200047b9,0x1e0047b9,0x150047b9,0x130047b9,0x80047b9,0x20047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff0047b9,0xfd0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xd40047b9,0x240047b9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x720047b9,0x870047b9,0xe60047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xe60047b9,0x870047b9,0x720047b9,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x330047b9,0x620047b9,0x6b0047b9,0x750047b9,
0x6a0047b9,0x770047b9,0x850047b9,0xbb0047b9,0xf00047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,
0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xff0047b9,0xf30047b9,0xce0047b9,0x970047b9,0x760047b9,0x670047b9,0x740047b9,0x6c0047b9,0x620047b9,0x330047b9,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
};
#endif
diff --git a/Core/Code/Rendering/mitkBaseRenderer.cpp b/Core/Code/Rendering/mitkBaseRenderer.cpp
index ac3d54ad04..41749f5f79 100644
--- a/Core/Code/Rendering/mitkBaseRenderer.cpp
+++ b/Core/Code/Rendering/mitkBaseRenderer.cpp
@@ -1,829 +1,828 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkBaseRenderer.h"
#include "mitkMapper.h"
#include "mitkResliceMethodProperty.h"
// Geometries
#include "mitkPlaneGeometry.h"
#include "mitkSlicedGeometry3D.h"
// Controllers
#include "mitkCameraController.h"
#include "mitkSliceNavigationController.h"
#include "mitkCameraRotationController.h"
#include "mitkVtkInteractorCameraController.h"
#ifdef MITK_USE_TD_MOUSE
#include "mitkTDMouseVtkCameraController.h"
#else
#include "mitkCameraController.h"
#endif
#include "mitkVtkLayerController.h"
// Events
#include "mitkEventMapper.h"
#include "mitkGlobalInteraction.h"
#include "mitkPositionEvent.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkProperties.h"
#include "mitkWeakPointerProperty.h"
#include "mitkInteractionConst.h"
// VTK
#include <vtkLinearTransform.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
mitk::BaseRenderer::BaseRendererMapType mitk::BaseRenderer::baseRendererMap;
mitk::BaseRenderer* mitk::BaseRenderer::GetInstance(vtkRenderWindow * renWin)
{
for(BaseRendererMapType::iterator mapit = baseRendererMap.begin();
mapit != baseRendererMap.end(); mapit++)
{
if( (*mapit).first == renWin)
return (*mapit).second;
}
return NULL;
}
void mitk::BaseRenderer::AddInstance(vtkRenderWindow* renWin, BaseRenderer* baseRenderer)
{
if(renWin == NULL || baseRenderer == NULL)
return;
// ensure that no BaseRenderer is managed twice
mitk::BaseRenderer::RemoveInstance(renWin);
baseRendererMap.insert(BaseRendererMapType::value_type(renWin,baseRenderer));
}
void mitk::BaseRenderer::RemoveInstance(vtkRenderWindow* renWin)
{
BaseRendererMapType::iterator mapit = baseRendererMap.find(renWin);
if(mapit != baseRendererMap.end())
baseRendererMap.erase(mapit);
}
mitk::BaseRenderer* mitk::BaseRenderer::GetByName( const std::string& name )
{
for(BaseRendererMapType::iterator mapit = baseRendererMap.begin();
mapit != baseRendererMap.end(); mapit++)
{
if( (*mapit).second->m_Name == name)
return (*mapit).second;
}
return NULL;
}
vtkRenderWindow* mitk::BaseRenderer::GetRenderWindowByName( const std::string& name )
{
for(BaseRendererMapType::iterator mapit = baseRendererMap.begin();
mapit != baseRendererMap.end(); mapit++)
{
if( (*mapit).second->m_Name == name)
return (*mapit).first;
}
return NULL;
}
mitk::BaseRenderer::BaseRenderer( const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm ) :
m_RenderWindow(NULL), m_VtkRenderer(NULL), m_MapperID(defaultMapper), m_DataStorage(NULL), m_RenderingManager(rm), m_LastUpdateTime(0),
m_CameraController(NULL), m_SliceNavigationController(NULL), m_CameraRotationController(NULL), /*m_Size(),*/
m_Focused(false), m_WorldGeometry(NULL), m_TimeSlicedWorldGeometry(NULL), m_CurrentWorldGeometry(NULL), m_CurrentWorldGeometry2D(NULL),
m_DisplayGeometry(NULL), m_Slice(0), m_TimeStep(), m_CurrentWorldGeometry2DUpdateTime(), m_DisplayGeometryUpdateTime(),
m_TimeStepUpdateTime(), m_WorldGeometryData(NULL), m_DisplayGeometryData(NULL), m_CurrentWorldGeometry2DData(NULL),
m_WorldGeometryNode(NULL), m_DisplayGeometryNode(NULL), m_CurrentWorldGeometry2DNode(NULL), m_DisplayGeometryTransformTime(0),
m_CurrentWorldGeometry2DTransformTime(0), m_Name(name), /*m_Bounds(),*/ m_EmptyWorldGeometry(true), m_DepthPeelingEnabled(true),
m_MaxNumberOfPeels(100), m_NumberOfVisibleLODEnabledMappers(0)
{
m_Bounds[0] = 0;
m_Bounds[1] = 0;
m_Bounds[2] = 0;
m_Bounds[3] = 0;
m_Bounds[4] = 0;
m_Bounds[5] = 0;
if (name != NULL)
{
m_Name = name;
}
else
{
m_Name = "unnamed renderer";
itkWarningMacro(<< "Created unnamed renderer. Bad for serialization. Please choose a name.");
}
if(renWin != NULL)
{
m_RenderWindow = renWin;
m_RenderWindow->Register(NULL);
}
else
{
itkWarningMacro(<< "Created mitkBaseRenderer without vtkRenderWindow present.");
}
m_Size[0] = 0;
m_Size[1] = 0;
//instances.insert( this );
//adding this BaseRenderer to the List of all BaseRenderer
m_RenderingManager->GetGlobalInteraction()->AddFocusElement(this);
WeakPointerProperty::Pointer rendererProp = WeakPointerProperty::New((itk::Object*)this);
m_CurrentWorldGeometry2D = mitk::PlaneGeometry::New();
m_CurrentWorldGeometry2DData = mitk::Geometry2DData::New();
m_CurrentWorldGeometry2DData->SetGeometry2D(m_CurrentWorldGeometry2D);
m_CurrentWorldGeometry2DNode = mitk::DataNode::New();
m_CurrentWorldGeometry2DNode->SetData(m_CurrentWorldGeometry2DData);
m_CurrentWorldGeometry2DNode->GetPropertyList()->SetProperty("renderer", rendererProp);
m_CurrentWorldGeometry2DNode->GetPropertyList()->SetProperty("layer", IntProperty::New(1000));
m_CurrentWorldGeometry2DNode->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( ) );
m_CurrentWorldGeometry2DNode->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( 1 ) );
m_CurrentWorldGeometry2DTransformTime = m_CurrentWorldGeometry2DNode->GetVtkTransform()->GetMTime();
m_DisplayGeometry = mitk::DisplayGeometry::New();
m_DisplayGeometry->SetWorldGeometry(m_CurrentWorldGeometry2D);
m_DisplayGeometryData = mitk::Geometry2DData::New();
m_DisplayGeometryData->SetGeometry2D(m_DisplayGeometry);
m_DisplayGeometryNode = mitk::DataNode::New();
m_DisplayGeometryNode->SetData(m_DisplayGeometryData);
m_DisplayGeometryNode->GetPropertyList()->SetProperty("renderer", rendererProp);
m_DisplayGeometryTransformTime = m_DisplayGeometryNode->GetVtkTransform()->GetMTime();
mitk::SliceNavigationController::Pointer sliceNavigationController = mitk::SliceNavigationController::New( "navigation" );
sliceNavigationController->SetRenderer( this );
sliceNavigationController->ConnectGeometrySliceEvent( this );
sliceNavigationController->ConnectGeometryUpdateEvent( this );
sliceNavigationController->ConnectGeometryTimeEvent( this, false );
m_SliceNavigationController = sliceNavigationController;
m_CameraRotationController = mitk::CameraRotationController::New();
m_CameraRotationController->SetRenderWindow( m_RenderWindow );
m_CameraRotationController->AcquireCamera();
//if TD Mouse Interaction is activated, then call TDMouseVtkCameraController instead of VtkInteractorCameraController
#ifdef MITK_USE_TD_MOUSE
m_CameraController = mitk::TDMouseVtkCameraController::New();
#else
m_CameraController = mitk::CameraController::New(NULL);
#endif
m_VtkRenderer = vtkRenderer::New();
if (mitk::VtkLayerController::GetInstance(m_RenderWindow) == NULL)
{
mitk::VtkLayerController::AddInstance(m_RenderWindow,m_VtkRenderer);
mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertSceneRenderer(m_VtkRenderer);
}
else
mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertSceneRenderer(m_VtkRenderer);
}
mitk::BaseRenderer::~BaseRenderer()
{
if(m_VtkRenderer!=NULL)
{
m_VtkRenderer->Delete();
m_VtkRenderer = NULL;
}
if(m_CameraController.IsNotNull())
m_CameraController->SetRenderer(NULL);
m_RenderingManager->GetGlobalInteraction()->RemoveFocusElement(this);
mitk::VtkLayerController::RemoveInstance(m_RenderWindow);
RemoveAllLocalStorages();
m_DataStorage = NULL;
if(m_RenderWindow!=NULL)
{
m_RenderWindow->Delete();
m_RenderWindow = NULL;
}
}
void mitk::BaseRenderer::RemoveAllLocalStorages()
{
this->InvokeEvent(mitk::BaseRenderer::RendererResetEvent());
std::list<mitk::BaseLocalStorageHandler*>::iterator it;
for ( it=m_RegisteredLocalStorageHandlers.begin() ; it != m_RegisteredLocalStorageHandlers.end(); it++ )
(*it)->ClearLocalStorage(this,false);
m_RegisteredLocalStorageHandlers.clear();
}
void mitk::BaseRenderer::RegisterLocalStorageHandler( mitk::BaseLocalStorageHandler *lsh )
{
m_RegisteredLocalStorageHandlers.push_back(lsh);
}
void mitk::BaseRenderer::UnregisterLocalStorageHandler( mitk::BaseLocalStorageHandler *lsh )
{
m_RegisteredLocalStorageHandlers.remove(lsh);
}
void mitk::BaseRenderer::SetDataStorage(DataStorage* storage)
{
if ( storage != NULL )
{
m_DataStorage = storage;
this->Modified();
}
}
const mitk::BaseRenderer::MapperSlotId mitk::BaseRenderer::defaultMapper = 1;
void mitk::BaseRenderer::Paint()
{
}
void mitk::BaseRenderer::Initialize()
{
}
void mitk::BaseRenderer::Resize(int w, int h)
{
m_Size[0] = w;
m_Size[1] = h;
if(m_CameraController)
m_CameraController->Resize(w, h); //(formerly problematic on windows: vtkSizeBug)
GetDisplayGeometry()->SetSizeInDisplayUnits(w, h);
}
void mitk::BaseRenderer::InitRenderer(vtkRenderWindow* renderwindow)
{
if(m_RenderWindow != NULL)
{
m_RenderWindow->Delete();
}
m_RenderWindow = renderwindow;
if(m_RenderWindow != NULL)
{
m_RenderWindow->Register(NULL);
}
RemoveAllLocalStorages();
if(m_CameraController.IsNotNull())
{
m_CameraController->SetRenderer(this);
}
//BUG (#1551) added settings for depth peeling
m_RenderWindow->SetAlphaBitPlanes(1);
m_VtkRenderer->SetUseDepthPeeling(m_DepthPeelingEnabled);
m_VtkRenderer->SetMaximumNumberOfPeels(m_MaxNumberOfPeels);
m_VtkRenderer->SetOcclusionRatio(0.1);
}
void mitk::BaseRenderer::InitSize(int w, int h)
{
m_Size[0] = w;
m_Size[1] = h;
GetDisplayGeometry()->SetSizeInDisplayUnits(w, h, false);
GetDisplayGeometry()->Fit();
}
void mitk::BaseRenderer::SetSlice(unsigned int slice)
{
if(m_Slice!=slice)
{
m_Slice = slice;
if(m_TimeSlicedWorldGeometry.IsNotNull())
{
SlicedGeometry3D* slicedWorldGeometry=dynamic_cast<SlicedGeometry3D*>(m_TimeSlicedWorldGeometry->GetGeometry3D(m_TimeStep));
if(slicedWorldGeometry!=NULL)
{
if(m_Slice >= slicedWorldGeometry->GetSlices())
m_Slice = slicedWorldGeometry->GetSlices()-1;
SetCurrentWorldGeometry2D(slicedWorldGeometry->GetGeometry2D(m_Slice));
SetCurrentWorldGeometry(slicedWorldGeometry);
}
}
else
Modified();
}
}
void mitk::BaseRenderer::SetTimeStep(unsigned int timeStep)
{
if(m_TimeStep!=timeStep)
{
m_TimeStep = timeStep;
m_TimeStepUpdateTime.Modified();
if(m_TimeSlicedWorldGeometry.IsNotNull())
{
if(m_TimeStep >= m_TimeSlicedWorldGeometry->GetTimeSteps())
m_TimeStep = m_TimeSlicedWorldGeometry->GetTimeSteps()-1;
SlicedGeometry3D* slicedWorldGeometry=dynamic_cast<SlicedGeometry3D*>(m_TimeSlicedWorldGeometry->GetGeometry3D(m_TimeStep));
if(slicedWorldGeometry!=NULL)
{
SetCurrentWorldGeometry2D(slicedWorldGeometry->GetGeometry2D(m_Slice));
SetCurrentWorldGeometry(slicedWorldGeometry);
}
}
else
Modified();
}
}
int mitk::BaseRenderer::GetTimeStep(const mitk::BaseData* data) const
{
if( (data==NULL) || (data->IsInitialized()==false) )
{
return -1;
}
return data->GetTimeSlicedGeometry()->MSToTimeStep(GetTime());
}
mitk::ScalarType mitk::BaseRenderer::GetTime() const
{
if(m_TimeSlicedWorldGeometry.IsNull())
{
return 0;
}
else
{
ScalarType timeInMS = m_TimeSlicedWorldGeometry->TimeStepToMS(GetTimeStep());
if(timeInMS == ScalarTypeNumericTraits::NonpositiveMin())
return 0;
else
return timeInMS;
}
}
void mitk::BaseRenderer::SetWorldGeometry(mitk::Geometry3D* geometry)
{
itkDebugMacro("setting WorldGeometry to " << geometry);
if(m_WorldGeometry != geometry)
{
if(geometry->GetBoundingBox()->GetDiagonalLength2() == 0)
return;
m_WorldGeometry = geometry;
m_TimeSlicedWorldGeometry=dynamic_cast<TimeSlicedGeometry*>(geometry);
SlicedGeometry3D* slicedWorldGeometry;
if(m_TimeSlicedWorldGeometry.IsNotNull())
{
itkDebugMacro("setting TimeSlicedWorldGeometry to " << m_TimeSlicedWorldGeometry);
if(m_TimeStep >= m_TimeSlicedWorldGeometry->GetTimeSteps())
m_TimeStep = m_TimeSlicedWorldGeometry->GetTimeSteps()-1;
slicedWorldGeometry=dynamic_cast<SlicedGeometry3D*>(m_TimeSlicedWorldGeometry->GetGeometry3D(m_TimeStep));
}
else
{
slicedWorldGeometry=dynamic_cast<SlicedGeometry3D*>(geometry);
}
Geometry2D::Pointer geometry2d;
if(slicedWorldGeometry!=NULL)
{
if(m_Slice >= slicedWorldGeometry->GetSlices() && (m_Slice != 0))
m_Slice = slicedWorldGeometry->GetSlices()-1;
geometry2d = slicedWorldGeometry->GetGeometry2D(m_Slice);
if(geometry2d.IsNull())
{
PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New();
plane->InitializeStandardPlane(slicedWorldGeometry);
geometry2d = plane;
}
SetCurrentWorldGeometry(slicedWorldGeometry);
}
else
{
geometry2d=dynamic_cast<Geometry2D*>(geometry);
if(geometry2d.IsNull())
{
PlaneGeometry::Pointer plane = PlaneGeometry::New();
plane->InitializeStandardPlane(geometry);
geometry2d = plane;
}
SetCurrentWorldGeometry(geometry);
}
SetCurrentWorldGeometry2D(geometry2d); // calls Modified()
}
if(m_CurrentWorldGeometry2D.IsNull())
itkWarningMacro("m_CurrentWorldGeometry2D is NULL");
}
void mitk::BaseRenderer::SetDisplayGeometry(mitk::DisplayGeometry* geometry2d)
{
itkDebugMacro("setting DisplayGeometry to " << geometry2d);
if (m_DisplayGeometry != geometry2d)
{
m_DisplayGeometry = geometry2d;
m_DisplayGeometryData->SetGeometry2D(m_DisplayGeometry);
m_DisplayGeometryUpdateTime.Modified();
Modified();
}
}
void mitk::BaseRenderer::SetCurrentWorldGeometry2D(mitk::Geometry2D* geometry2d)
{
if (m_CurrentWorldGeometry2D != geometry2d)
{
m_CurrentWorldGeometry2D = geometry2d;
m_CurrentWorldGeometry2DData->SetGeometry2D(m_CurrentWorldGeometry2D);
m_DisplayGeometry->SetWorldGeometry(m_CurrentWorldGeometry2D);
m_CurrentWorldGeometry2DUpdateTime.Modified();
Modified();
}
}
void mitk::BaseRenderer::SendUpdateSlice()
{
m_DisplayGeometryUpdateTime.Modified();
m_CurrentWorldGeometry2DUpdateTime.Modified();
}
void mitk::BaseRenderer::SetCurrentWorldGeometry(mitk::Geometry3D* geometry)
{
m_CurrentWorldGeometry = geometry;
if(geometry == NULL)
{
m_Bounds[0] = 0;
m_Bounds[1] = 0;
m_Bounds[2] = 0;
m_Bounds[3] = 0;
m_Bounds[4] = 0;
m_Bounds[5] = 0;
m_EmptyWorldGeometry = true;
return;
}
BoundingBox::Pointer boundingBox =
m_CurrentWorldGeometry->CalculateBoundingBoxRelativeToTransform(NULL);
const BoundingBox::BoundsArrayType& worldBounds = boundingBox->GetBounds();
m_Bounds[0] = worldBounds[0];
m_Bounds[1] = worldBounds[1];
m_Bounds[2] = worldBounds[2];
m_Bounds[3] = worldBounds[3];
m_Bounds[4] = worldBounds[4];
m_Bounds[5] = worldBounds[5];
if(boundingBox->GetDiagonalLength2()<=mitk::eps)
m_EmptyWorldGeometry = true;
else
m_EmptyWorldGeometry = false;
}
void mitk::BaseRenderer::SetGeometry(const itk::EventObject & geometrySendEvent)
{
const SliceNavigationController::GeometrySendEvent* sendEvent =
dynamic_cast<const SliceNavigationController::GeometrySendEvent *>(&geometrySendEvent);
assert(sendEvent!=NULL);
SetWorldGeometry(sendEvent ->GetTimeSlicedGeometry());
}
void mitk::BaseRenderer::UpdateGeometry(const itk::EventObject & geometryUpdateEvent)
{
const SliceNavigationController::GeometryUpdateEvent* updateEvent =
dynamic_cast<const SliceNavigationController::GeometryUpdateEvent*>(&geometryUpdateEvent);
if (updateEvent==NULL) return;
if (m_CurrentWorldGeometry.IsNotNull())
{
SlicedGeometry3D* slicedWorldGeometry=dynamic_cast<SlicedGeometry3D*>(m_CurrentWorldGeometry.GetPointer());
if (slicedWorldGeometry)
{
Geometry2D* geometry2D = slicedWorldGeometry->GetGeometry2D(m_Slice);
SetCurrentWorldGeometry2D(geometry2D); // calls Modified()
}
}
}
void mitk::BaseRenderer::SetGeometrySlice(const itk::EventObject & geometrySliceEvent)
{
const SliceNavigationController::GeometrySliceEvent* sliceEvent =
dynamic_cast<const SliceNavigationController::GeometrySliceEvent *>(&geometrySliceEvent);
assert(sliceEvent!=NULL);
SetSlice(sliceEvent->GetPos());
}
void mitk::BaseRenderer::SetGeometryTime(const itk::EventObject & geometryTimeEvent)
{
const SliceNavigationController::GeometryTimeEvent * timeEvent =
dynamic_cast<const SliceNavigationController::GeometryTimeEvent *>(&geometryTimeEvent);
assert(timeEvent!=NULL);
SetTimeStep(timeEvent->GetPos());
}
const double* mitk::BaseRenderer::GetBounds() const
{
return m_Bounds;
}
void mitk::BaseRenderer::MousePressEvent(mitk::MouseEvent *me)
{
//set the Focus on the renderer
/*bool success =*/ m_RenderingManager->GetGlobalInteraction()->SetFocus(this);
/*
if (! success)
mitk::StatusBar::GetInstance()->DisplayText("Warning! from mitkBaseRenderer.cpp: Couldn't focus this BaseRenderer!");
*/
//if (m_CameraController)
//{
// if(me->GetButtonState()!=512) // provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine
// m_CameraController->MousePressEvent(me);
//}
if(m_MapperID==1)
{
Point2D p(me->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position);
mitk::EventMapper::MapEvent( &event, m_RenderingManager->GetGlobalInteraction() );
}
else if(m_MapperID>1)//==2 for 3D and ==5 for stencil
{
Point2D p(me->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
me->SetDisplayPosition(p);
mitk::EventMapper::MapEvent( me, m_RenderingManager->GetGlobalInteraction() );
}
}
void mitk::BaseRenderer::MouseReleaseEvent(mitk::MouseEvent *me)
{
//if (m_CameraController)
//{
// if(me->GetButtonState()!=512) // provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine
// m_CameraController->MouseReleaseEvent(me);
//}
if(m_MapperID==1)
{
Point2D p(me->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position);
mitk::EventMapper::MapEvent( &event, m_RenderingManager->GetGlobalInteraction() );
}
else if(m_MapperID==2)
{
Point2D p(me->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
me->SetDisplayPosition(p);
mitk::EventMapper::MapEvent( me, m_RenderingManager->GetGlobalInteraction() );
}
}
void mitk::BaseRenderer::MouseMoveEvent(mitk::MouseEvent *me)
{
//if (m_CameraController)
//{
// if((me->GetButtonState()<=512) || (me->GetButtonState()>=516))// provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine
// m_CameraController->MouseMoveEvent(me);
//}
if(m_MapperID==1)
{
Point2D p(me->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position);
mitk::EventMapper::MapEvent( &event, m_RenderingManager->GetGlobalInteraction() );
}
else if(m_MapperID==2)
{
Point2D p(me->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
me->SetDisplayPosition(p);
mitk::EventMapper::MapEvent( me, m_RenderingManager->GetGlobalInteraction() );
}
}
void mitk::BaseRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const
{
mitk::Point2D worldPoint2D;
GetDisplayGeometry()->DisplayToWorld(displayPoint, worldPoint2D);
GetDisplayGeometry()->Map(worldPoint2D, worldPoint);
}
void mitk::BaseRenderer::WheelEvent(mitk::WheelEvent * we)
{
if(m_MapperID==1)
{
Point2D p(we->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::PositionEvent event(this, we->GetType(), we->GetButton(), we->GetButtonState(), mitk::Key_unknown, p, position);
mitk::EventMapper::MapEvent( we, m_RenderingManager->GetGlobalInteraction() );
mitk::EventMapper::MapEvent( &event, m_RenderingManager->GetGlobalInteraction() );
}
else if(m_MapperID==2)
{
Point2D p(we->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
we->SetDisplayPosition(p);
mitk::EventMapper::MapEvent( we, m_RenderingManager->GetGlobalInteraction() );
}
}
void mitk::BaseRenderer::KeyPressEvent(mitk::KeyEvent *ke)
{
if(m_MapperID==1)
{
Point2D p(ke->GetDisplayPosition());
Point2D p_mm;
Point3D position;
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
GetDisplayGeometry()->DisplayToWorld(p, p_mm);
GetDisplayGeometry()->Map(p_mm, position);
mitk::KeyEvent event(this, ke->GetType(), ke->GetButton(), ke->GetButtonState(), ke->GetKey(), ke->GetText(), p);
mitk::EventMapper::MapEvent( &event, m_RenderingManager->GetGlobalInteraction() );
}
else if(m_MapperID==2)
{
Point2D p(ke->GetDisplayPosition());
GetDisplayGeometry()->ULDisplayToDisplay(p,p);
ke->SetDisplayPosition(p);
mitk::EventMapper::MapEvent( ke, m_RenderingManager->GetGlobalInteraction() );
}
}
void mitk::BaseRenderer::DrawOverlayMouse(mitk::Point2D& itkNotUsed(p2d))
{
MITK_INFO<<"BaseRenderer::DrawOverlayMouse()- should be inconcret implementation OpenGLRenderer."<<std::endl;
}
void mitk::BaseRenderer::RequestUpdate()
{
m_RenderingManager->RequestUpdate(this->m_RenderWindow);
}
void mitk::BaseRenderer::ForceImmediateUpdate()
{
m_RenderingManager->ForceImmediateUpdate(this->m_RenderWindow);
}
unsigned int mitk::BaseRenderer::GetNumberOfVisibleLODEnabledMappers() const
{
return m_NumberOfVisibleLODEnabledMappers;
}
mitk::RenderingManager* mitk::BaseRenderer::GetRenderingManager() const
{
return m_RenderingManager.GetPointer();
}
/*!
Sets the new Navigation controller
*/
void mitk::BaseRenderer::SetSliceNavigationController(mitk::SliceNavigationController *SlicenavigationController)
{
if (SlicenavigationController == NULL)
return;
//disconnect old from globalinteraction
m_RenderingManager->GetGlobalInteraction()->RemoveListener(SlicenavigationController);
//copy worldgeometry
SlicenavigationController->SetInputWorldGeometry( SlicenavigationController->GetCreatedWorldGeometry() );
SlicenavigationController->Update();
//set new
m_SliceNavigationController = SlicenavigationController;
m_SliceNavigationController->SetRenderer( this );
if (m_SliceNavigationController.IsNotNull())
{
m_SliceNavigationController->ConnectGeometrySliceEvent( this );
m_SliceNavigationController->ConnectGeometryUpdateEvent( this );
m_SliceNavigationController->ConnectGeometryTimeEvent( this, false );
}
}
/*!
Sets the new camera controller and deletes the vtkRenderWindowInteractor in case of the VTKInteractorCameraController
*/
void mitk::BaseRenderer::SetCameraController(CameraController* cameraController)
{
mitk::VtkInteractorCameraController::Pointer vtkInteractorCameraController = dynamic_cast<mitk::VtkInteractorCameraController*>(cameraController);
if (vtkInteractorCameraController.IsNotNull())
MITK_INFO<<"!!!WARNING!!!: RenderWindow interaction events are no longer handled via CameraController (See Bug #954)."<<std::endl;
m_CameraController->SetRenderer(NULL);
m_CameraController = NULL;
m_CameraController = cameraController;
m_CameraController->SetRenderer(this);
}
void mitk::BaseRenderer::PrintSelf(std::ostream& os, itk::Indent indent) const
{
os << indent << " MapperID: " << m_MapperID << std::endl;
os << indent << " Slice: " << m_Slice << std::endl;
os << indent << " TimeStep: " << m_TimeStep << std::endl;
os << indent << " WorldGeometry: ";
if(m_WorldGeometry.IsNull())
os << "NULL" << std::endl;
else
m_WorldGeometry->Print(os, indent);
os << indent << " CurrentWorldGeometry2D: ";
if(m_CurrentWorldGeometry2D.IsNull())
os << "NULL" << std::endl;
else
m_CurrentWorldGeometry2D->Print(os, indent);
os << indent << " CurrentWorldGeometry2DUpdateTime: " << m_CurrentWorldGeometry2DUpdateTime << std::endl;
os << indent << " CurrentWorldGeometry2DTransformTime: " << m_CurrentWorldGeometry2DTransformTime << std::endl;
os << indent << " DisplayGeometry: ";
if(m_DisplayGeometry.IsNull())
os << "NULL" << std::endl;
else
m_DisplayGeometry->Print(os, indent);
os << indent << " DisplayGeometryTransformTime: " << m_DisplayGeometryTransformTime << std::endl;
Superclass::PrintSelf(os,indent);
}
void mitk::BaseRenderer::SetDepthPeelingEnabled( bool enabled )
{
m_DepthPeelingEnabled = enabled;
m_VtkRenderer->SetUseDepthPeeling(enabled);
}
void mitk::BaseRenderer::SetMaxNumberOfPeels( int maxNumber )
{
m_MaxNumberOfPeels = maxNumber;
m_VtkRenderer->SetMaximumNumberOfPeels(maxNumber);
}
diff --git a/Core/Code/Rendering/mitkBaseRenderer.h b/Core/Code/Rendering/mitkBaseRenderer.h
index 3a3749ce04..45c4a69b7c 100644
--- a/Core/Code/Rendering/mitkBaseRenderer.h
+++ b/Core/Code/Rendering/mitkBaseRenderer.h
@@ -1,587 +1,586 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4
#define BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4
#include "mitkDataStorage.h"
#include "mitkGeometry2D.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkDisplayGeometry.h"
#include "mitkGeometry2DData.h"
#include "mitkCameraController.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkWheelEvent.h"
//#include "mitkMapper.h"
#include "mitkSliceNavigationController.h"
#include "mitkCameraController.h"
#include "mitkCameraRotationController.h"
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <map>
#include <set>
namespace mitk
{
class NavigationController;
class SliceNavigationController;
class CameraRotationController;
class CameraController;
class DataStorage;
class Mapper;
class BaseLocalStorageHandler;
//##Documentation
//## @brief Organizes the rendering process
//##
//## Organizes the rendering process. A Renderer contains a reference to a
//## DataStorage and asks the mappers of the data objects to render
//## the data into the renderwindow it is associated to.
//##
//## \#Render() checks if rendering is currently allowed by calling
//## RenderWindow::PrepareRendering(). Initialization of a rendering context
//## can also be performed in this method.
//##
//## The actual rendering code has been moved to \#Repaint()
//## Both \#Repaint() and \#Update() are declared protected now.
//##
//## Note: Separation of the Repaint and Update processes (rendering vs
//## creating a vtk prop tree) still needs to be worked on. The whole
//## rendering process also should be reworked to use VTK based classes for
//## both 2D and 3D rendering.
//## @ingroup Renderer
class MITK_CORE_EXPORT BaseRenderer : public itk::Object
{
public:
typedef std::map<vtkRenderWindow*,BaseRenderer*> BaseRendererMapType;
static BaseRendererMapType baseRendererMap;
static BaseRenderer* GetInstance(vtkRenderWindow * renWin);
static void AddInstance(vtkRenderWindow* renWin, BaseRenderer* baseRenderer);
static void RemoveInstance(vtkRenderWindow* renWin);
static BaseRenderer* GetByName( const std::string& name );
static vtkRenderWindow* GetRenderWindowByName( const std::string& name );
#pragma GCC visibility push(default)
itkEventMacro( RendererResetEvent, itk::AnyEvent );
#pragma GCC visibility pop
/** Standard class typedefs. */
mitkClassMacro(BaseRenderer, itk::Object);
BaseRenderer( const char* name = NULL, vtkRenderWindow * renWin = NULL, mitk::RenderingManager* rm= NULL );
//##Documentation
//## @brief MapperSlotId defines which kind of mapper (e.g., 2D or 3D) shoud be used.
typedef int MapperSlotId;
enum StandardMapperSlot{Standard2D=1, Standard3D=2};
virtual void SetDataStorage( DataStorage* storage ); ///< set the datastorage that will be used for rendering
//##Documentation
//## return the DataStorage that is used for rendering
virtual DataStorage::Pointer GetDataStorage() const
{
return m_DataStorage.GetPointer();
};
//##Documentation
//## @brief Access the RenderWindow into which this renderer renders.
vtkRenderWindow* GetRenderWindow() const
{
return m_RenderWindow;
}
vtkRenderer* GetVtkRenderer() const
{
return m_VtkRenderer;
}
//##Documentation
//## @brief Default mapper id to use.
static const MapperSlotId defaultMapper;
//##Documentation
//## @brief Do the rendering and flush the result.
virtual void Paint();
//##Documentation
//## @brief Initialize the RenderWindow. Should only be called from RenderWindow.
virtual void Initialize();
//##Documentation
//## @brief Called to inform the renderer that the RenderWindow has been resized.
virtual void Resize(int w, int h);
//##Documentation
//## @brief Initialize the renderer with a RenderWindow (@a renderwindow).
virtual void InitRenderer(vtkRenderWindow* renderwindow);
//##Documentation
//## @brief Set the initial size. Called by RenderWindow after it has become
//## visible for the first time.
virtual void InitSize(int w, int h);
//##Documentation
//## @brief Draws a point on the widget.
//## Should be used during conferences to show the position of the remote mouse
virtual void DrawOverlayMouse(Point2D& p2d);
//##Documentation
//## @brief Set/Get the WorldGeometry (m_WorldGeometry) for 3D and 2D rendering, that describing the
//## (maximal) area to be rendered.
//##
//## Depending of the type of the passed Geometry3D more or less information can be extracted:
//## \li if it is a Geometry2D (which is a sub-class of Geometry3D), m_CurrentWorldGeometry2D is
//## also set to point to it. m_TimeSlicedWorldGeometry is set to NULL.
//## \li if it is a TimeSlicedGeometry, m_TimeSlicedWorldGeometry is also set to point to it.
//## If m_TimeSlicedWorldGeometry contains instances of SlicedGeometry3D, m_CurrentWorldGeometry2D is set to
//## one of geometries stored in the SlicedGeometry3D according to the value of m_Slice; otherwise
//## a PlaneGeometry describing the top of the bounding-box of the Geometry3D is set as the
//## m_CurrentWorldGeometry2D.
//## \li otherwise a PlaneGeometry describing the top of the bounding-box of the Geometry3D
//## is set as the m_CurrentWorldGeometry2D. m_TimeSlicedWorldGeometry is set to NULL.
//## @todo add calculation of PlaneGeometry describing the top of the bounding-box of the Geometry3D
//## when the passed Geometry3D is not sliced.
//## \sa m_WorldGeometry
//## \sa m_TimeSlicedWorldGeometry
//## \sa m_CurrentWorldGeometry2D
virtual void SetWorldGeometry(Geometry3D* geometry);
itkGetConstObjectMacro(WorldGeometry, Geometry3D);
//##Documentation
//## @brief Get the current 3D-worldgeometry (m_CurrentWorldGeometry) used for 3D-rendering
itkGetConstObjectMacro(CurrentWorldGeometry, Geometry3D);
//##Documentation
//## @brief Get the current 2D-worldgeometry (m_CurrentWorldGeometry2D) used for 2D-rendering
itkGetConstObjectMacro(CurrentWorldGeometry2D, Geometry2D);
//##Documentation
//## Calculates the bounds of the DataStorage (if it contains any valid data),
//## creates a geometry from these bounds and sets it as world geometry of the renderer.
//##
//## Call this method to re-initialize the renderer to the current DataStorage
//## (e.g. after loading an additional dataset), to ensure that the view is
//## aligned correctly.
//## \warn This is not implemented yet.
virtual bool SetWorldGeometryToDataStorageBounds()
{
return false;
}
//##Documentation
//## @brief Set/Get the DisplayGeometry (for 2D rendering)
//##
//## The DisplayGeometry describes which part of the Geometry2D m_CurrentWorldGeometry2D
//## is displayed.
virtual void SetDisplayGeometry(DisplayGeometry* geometry2d);
itkGetConstObjectMacro(DisplayGeometry, DisplayGeometry);
itkGetObjectMacro(DisplayGeometry, DisplayGeometry);
//##Documentation
//## @brief Set/Get m_Slice which defines together with m_TimeStep the 2D geometry
//## stored in m_TimeSlicedWorldGeometry used as m_CurrentWorldGeometry2D
//##
//## \sa m_Slice
virtual void SetSlice(unsigned int slice);
itkGetConstMacro(Slice, unsigned int);
//##Documentation
//## @brief Set/Get m_TimeStep which defines together with m_Slice the 2D geometry
//## stored in m_TimeSlicedWorldGeometry used as m_CurrentWorldGeometry2D
//##
//## \sa m_TimeStep
virtual void SetTimeStep(unsigned int timeStep);
itkGetConstMacro(TimeStep, unsigned int);
//##Documentation
//## @brief Get the time-step of a BaseData object which
//## exists at the time of the currently displayed content
//##
//## Returns -1 or mitk::BaseData::m_TimeSteps if there
//## is no data at the current time.
//## \sa GetTimeStep, m_TimeStep
int GetTimeStep(const BaseData* data) const;
//##Documentation
//## @brief Get the time in ms of the currently displayed content
//##
//## \sa GetTimeStep, m_TimeStep
ScalarType GetTime() const;
//##Documentation
//## @brief SetWorldGeometry is called according to the geometrySliceEvent,
//## which is supposed to be a SliceNavigationController::GeometrySendEvent
virtual void SetGeometry(const itk::EventObject & geometrySliceEvent);
//##Documentation
//## @brief UpdateWorldGeometry is called to re-read the 2D geometry from the
//## slice navigation controller
virtual void UpdateGeometry(const itk::EventObject & geometrySliceEvent);
//##Documentation
//## @brief SetSlice is called according to the geometrySliceEvent,
//## which is supposed to be a SliceNavigationController::GeometrySliceEvent
virtual void SetGeometrySlice(const itk::EventObject & geometrySliceEvent);
//##Documentation
//## @brief SetTimeStep is called according to the geometrySliceEvent,
//## which is supposed to be a SliceNavigationController::GeometryTimeEvent
virtual void SetGeometryTime(const itk::EventObject & geometryTimeEvent);
//##Documentation
//## @brief Get a data object containing the DisplayGeometry (for 2D rendering)
itkGetObjectMacro(DisplayGeometryData, Geometry2DData);
//##Documentation
//## @brief Get a data object containing the WorldGeometry (for 2D rendering)
itkGetObjectMacro(WorldGeometryData, Geometry2DData);
//##Documentation
//## @brief Get a DataNode pointing to a data object containing the WorldGeometry (3D and 2D rendering)
itkGetObjectMacro(WorldGeometryNode, DataNode);
//##Documentation
//## @brief Get a DataNode pointing to a data object containing the DisplayGeometry (for 2D rendering)
itkGetObjectMacro(DisplayGeometryNode, DataNode);
//##Documentation
//## @brief Get a DataNode pointing to a data object containing the current 2D-worldgeometry m_CurrentWorldGeometry2D (for 2D rendering)
itkGetObjectMacro(CurrentWorldGeometry2DNode, DataNode);
//##Documentation
//## @brief Sets timestamp of CurrentWorldGeometry2D and DisplayGeometry and forces so reslicing in that renderwindow
void SendUpdateSlice();
//##Documentation
//## @brief Get timestamp of last call of SetCurrentWorldGeometry2D
unsigned long GetCurrentWorldGeometry2DUpdateTime() { return m_CurrentWorldGeometry2DUpdateTime; };
//##Documentation
//## @brief Get timestamp of last call of SetDisplayGeometry
unsigned long GetDisplayGeometryUpdateTime() { return m_CurrentWorldGeometry2DUpdateTime; };
//##Documentation
//## @brief Get timestamp of last change of current TimeStep
unsigned long GetTimeStepUpdateTime() { return m_TimeStepUpdateTime; };
//##Documentation
//## @brief Perform a picking: find the x,y,z world coordinate of a
//## display x,y coordinate.
//## @warning Has to be overwritten in subclasses for the 3D-case.
//##
//## Implemented here only for 2D-rendering by using
//## m_DisplayGeometry
virtual void PickWorldPoint(const Point2D& diplayPosition, Point3D& worldPosition) const;
/** \brief Determines the object (mitk::DataNode) closest to the current
* position by means of picking
*
* \warning Implementation currently empty for 2D rendering; intended to be
* implemented for 3D renderers */
virtual DataNode* PickObject( const Point2D& /*displayPosition*/, Point3D& /*worldPosition*/ ) const { return NULL; };
//##Documentation
//## @brief Get the MapperSlotId to use.
itkGetMacro(MapperID, MapperSlotId);
itkGetConstMacro(MapperID, MapperSlotId);
//##Documentation
//## @brief Set the MapperSlotId to use.
itkSetMacro(MapperID, MapperSlotId);
//##Documentation
//## @brief Has the renderer the focus?
itkGetMacro(Focused, bool);
//##Documentation
//## @brief Tell the renderer that it is focused. The caller is responsible for focus management,
//## not the renderer itself.
itkSetMacro(Focused, bool);
//##Documentation
//## @brief Sets whether depth peeling is enabled or not
void SetDepthPeelingEnabled(bool enabled); //##Documentation
//## @brief Sets maximal number of peels
void SetMaxNumberOfPeels(int maxNumber);
itkGetMacro(Size, int*);
void SetSliceNavigationController(SliceNavigationController* SlicenavigationController);
void SetCameraController(CameraController* cameraController);
itkGetObjectMacro(CameraController, CameraController);
itkGetObjectMacro(SliceNavigationController, SliceNavigationController);
itkGetObjectMacro(CameraRotationController, CameraRotationController);
itkGetMacro(EmptyWorldGeometry, bool);
//##Documentation
//## @brief Mouse event dispatchers
//## @note for internal use only. preliminary.
virtual void MousePressEvent(MouseEvent*);
//##Documentation
//## @brief Mouse event dispatchers
//## @note for internal use only. preliminary.
virtual void MouseReleaseEvent(MouseEvent*);
//##Documentation
//## @brief Mouse event dispatchers
//## @note for internal use only. preliminary.
virtual void MouseMoveEvent(MouseEvent*);
//##Documentation
//## @brief Wheel event dispatcher
//## @note for internal use only. preliminary.
virtual void WheelEvent(mitk::WheelEvent* we);
//##Documentation
//## @brief Key event dispatcher
//## @note for internal use only. preliminary.
virtual void KeyPressEvent(KeyEvent*);
//##Documentation
//## @brief get the name of the Renderer
//## @note
const char * GetName() const
{
return m_Name.c_str();
}
//##Documentation
//## @brief get the x_size of the RendererWindow
//## @note
int GetSizeX() const
{
return m_Size[0];
}
//##Documentation
//## @brief get the y_size of the RendererWindow
//## @note
int GetSizeY() const
{
return m_Size[1];
}
const double* GetBounds() const;
void RequestUpdate();
void ForceImmediateUpdate();
/** Returns number of mappers which are visible and have level-of-detail
* rendering enabled */
unsigned int GetNumberOfVisibleLODEnabledMappers() const;
///**
//* \brief Setter for the RenderingManager that handles this instance of BaseRenderer
//*/
//void SetRenderingManager( mitk::RenderingManager* );
/**
* \brief Getter for the RenderingManager that handles this instance of BaseRenderer
*/
virtual mitk::RenderingManager* GetRenderingManager() const;
protected:
virtual ~BaseRenderer();
//##Documentation
//## @brief Call update of all mappers. To be implemented in subclasses.
virtual void Update() = 0;
vtkRenderWindow* m_RenderWindow;
vtkRenderer* m_VtkRenderer;
//##Documentation
//## @brief MapperSlotId to use. Defines which kind of mapper (e.g., 2D or 3D) shoud be used.
MapperSlotId m_MapperID;
//##Documentation
//## @brief The DataStorage that is used for rendering.
DataStorage::Pointer m_DataStorage;
//##Documentation
//## @brief The RenderingManager that manages this instance
RenderingManager::Pointer m_RenderingManager;
//##Documentation
//## @brief Timestamp of last call of Update().
unsigned long m_LastUpdateTime;
//##Documentation
//## @brief CameraController for 3D rendering
//## @note preliminary.
CameraController::Pointer m_CameraController;
SliceNavigationController::Pointer m_SliceNavigationController;
CameraRotationController::Pointer m_CameraRotationController;
//##Documentation
//## @brief Size of the RenderWindow.
int m_Size[2];
//##Documentation
//## @brief Contains whether the renderer that it is focused. The caller of
//## SetFocused is responsible for focus management, not the renderer itself.
//## is doubled because of mitk::FocusManager in GlobalInteraction!!! (ingmar)
bool m_Focused;
//##Documentation
//## @brief Sets m_CurrentWorldGeometry2D
virtual void SetCurrentWorldGeometry2D(Geometry2D* geometry2d);
//##Documentation
//## @brief Sets m_CurrentWorldGeometry
virtual void SetCurrentWorldGeometry(Geometry3D* geometry);
private:
//##Documentation
//## Pointer to the worldgeometry, describing the maximal area to be rendered
//## (3D as well as 2D).
//## It is const, since we are not allowed to change it (it may be taken
//## directly from the geometry of an image-slice and thus it would be
//## very strange when suddenly the image-slice changes its geometry).
//## \sa SetWorldGeometry
Geometry3D::Pointer m_WorldGeometry;
//##Documentation
//## m_TimeSlicedWorldGeometry is set by SetWorldGeometry if the passed Geometry3D is a
//## TimeSlicedGeometry (or a sub-class of it). If it contains instances of SlicedGeometry3D,
//## m_Slice and m_TimeStep (set via SetSlice and SetTimeStep, respectively) define
//## which 2D geometry stored in m_TimeSlicedWorldGeometry (if available)
//## is used as m_CurrentWorldGeometry2D.
//## \sa m_CurrentWorldGeometry2D
TimeSlicedGeometry::Pointer m_TimeSlicedWorldGeometry;
//##Documentation
//## Pointer to the current 3D-worldgeometry.
Geometry3D::Pointer m_CurrentWorldGeometry;
//##Documentation
//## Pointer to the current 2D-worldgeometry. The 2D-worldgeometry
//## describes the maximal area (2D manifold) to be rendered in case we
//## are doing 2D-rendering. More precisely, a subpart of this according
//## to m_DisplayGeometry is displayed.
//## It is const, since we are not allowed to change it (it may be taken
//## directly from the geometry of an image-slice and thus it would be
//## very strange when suddenly the image-slice changes its geometry).
Geometry2D::Pointer m_CurrentWorldGeometry2D;
//##Documentation
//## Pointer to the displaygeometry. The displaygeometry describes the
//## geometry of the \em visible area in the window controlled by the renderer
//## in case we are doing 2D-rendering.
//## It is const, since we are not allowed to change it.
DisplayGeometry::Pointer m_DisplayGeometry;
//##Documentation
//## Defines together with m_Slice which 2D geometry stored in m_TimeSlicedWorldGeometry
//## is used as m_CurrentWorldGeometry2D: m_TimeSlicedWorldGeometry->GetGeometry2D(m_Slice, m_TimeStep).
//## \sa m_TimeSlicedWorldGeometry
unsigned int m_Slice;
//##Documentation
//## Defines together with m_TimeStep which 2D geometry stored in m_TimeSlicedWorldGeometry
//## is used as m_CurrentWorldGeometry2D: m_TimeSlicedWorldGeometry->GetGeometry2D(m_Slice, m_TimeStep).
//## \sa m_TimeSlicedWorldGeometry
unsigned int m_TimeStep;
//##Documentation
//## @brief timestamp of last call of SetWorldGeometry
itk::TimeStamp m_CurrentWorldGeometry2DUpdateTime;
//##Documentation
//## @brief timestamp of last call of SetDisplayGeometry
itk::TimeStamp m_DisplayGeometryUpdateTime;
//##Documentation
//## @brief timestamp of last change of the current time step
itk::TimeStamp m_TimeStepUpdateTime;
protected:
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
//##Documentation
//## Data object containing the m_WorldGeometry defined above.
Geometry2DData::Pointer m_WorldGeometryData;
//##Documentation
//## Data object containing the m_DisplayGeometry defined above.
Geometry2DData::Pointer m_DisplayGeometryData;
//##Documentation
//## Data object containing the m_CurrentWorldGeometry2D defined above.
Geometry2DData::Pointer m_CurrentWorldGeometry2DData;
//##Documentation
//## DataNode objects containing the m_WorldGeometryData defined above.
DataNode::Pointer m_WorldGeometryNode;
//##Documentation
//## DataNode objects containing the m_DisplayGeometryData defined above.
DataNode::Pointer m_DisplayGeometryNode;
//##Documentation
//## DataNode objects containing the m_CurrentWorldGeometry2DData defined above.
DataNode::Pointer m_CurrentWorldGeometry2DNode;
//##Documentation
//## @brief test only
unsigned long m_DisplayGeometryTransformTime;
//##Documentation
//## @brief test only
unsigned long m_CurrentWorldGeometry2DTransformTime;
std::string m_Name;
double m_Bounds[6];
bool m_EmptyWorldGeometry;
bool m_DepthPeelingEnabled;
int m_MaxNumberOfPeels;
typedef std::set< Mapper * > LODEnabledMappersType;
/** Number of mappers which are visible and have level-of-detail
* rendering enabled */
unsigned int m_NumberOfVisibleLODEnabledMappers;
// Local Storage Handling for mappers
protected:
std::list<mitk::BaseLocalStorageHandler*> m_RegisteredLocalStorageHandlers;
public:
void RemoveAllLocalStorages();
void RegisterLocalStorageHandler( mitk::BaseLocalStorageHandler *lsh );
void UnregisterLocalStorageHandler( mitk::BaseLocalStorageHandler *lsh );
};
} // namespace mitk
#endif /* BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 */
diff --git a/Core/Code/Rendering/mitkGL.h b/Core/Code/Rendering/mitkGL.h
index 0070a38c81..4a71488297 100644
--- a/Core/Code/Rendering/mitkGL.h
+++ b/Core/Code/Rendering/mitkGL.h
@@ -1,33 +1,32 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGL_H_HEADER_INCLUDED_C1C53722
#define MITKGL_H_HEADER_INCLUDED_C1C53722
#ifdef WIN32
#include <windows.h>
#endif
#ifndef __APPLE__
#include "GL/gl.h"
#else
#include "OpenGL/gl.h"
#endif
#endif /* MITKGL_H_HEADER_INCLUDED_C1C53722 */
diff --git a/Core/Code/Rendering/mitkGLMapper2D.cpp b/Core/Code/Rendering/mitkGLMapper2D.cpp
index 779f68fb1c..6811b71f4e 100644
--- a/Core/Code/Rendering/mitkGLMapper2D.cpp
+++ b/Core/Code/Rendering/mitkGLMapper2D.cpp
@@ -1,62 +1,61 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGL.h"
#include "mitkGLMapper2D.h"
mitk::GLMapper2D::GLMapper2D()
{
}
mitk::GLMapper2D::~GLMapper2D()
{
}
void mitk::GLMapper2D::MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer)
{
if(IsVisible(renderer)==false)
return;
Paint(renderer);
}
void mitk::GLMapper2D::MitkRenderTranslucentGeometry(mitk::BaseRenderer* /*renderer*/)
{
}
void mitk::GLMapper2D::MitkRenderOverlay(mitk::BaseRenderer* /*renderer*/)
{
}
void mitk::GLMapper2D::MitkRenderVolumetricGeometry(mitk::BaseRenderer* /*renderer*/)
{
}
void mitk::GLMapper2D::ApplyProperties(mitk::BaseRenderer* renderer)
{
float rgba[4]={1.0f,1.0f,1.0f,1.0f};
// check for color prop and use it for rendering if it exists
GetColor(rgba, renderer);
// check for opacity prop and use it for rendering if it exists
GetOpacity(rgba[3], renderer);
glColor4fv(rgba);
}
diff --git a/Core/Code/Rendering/mitkGLMapper2D.h b/Core/Code/Rendering/mitkGLMapper2D.h
index 5671548f17..29a6c8f5ee 100644
--- a/Core/Code/Rendering/mitkGLMapper2D.h
+++ b/Core/Code/Rendering/mitkGLMapper2D.h
@@ -1,67 +1,66 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872
#define MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872
#include <MitkExports.h>
#include "mitkMapper2D.h"
#include "mitkBaseRenderer.h"
namespace mitk {
//##Documentation
//## @brief Base class of all OpenGL-based 2D-Mappers
//##
//## Those must implement the abstract method Paint(BaseRenderer).
//## @ingroup Mapper
class MITK_CORE_EXPORT GLMapper2D : public Mapper2D
{
public:
//##Documentation
//## @brief Do the painting into the @a renderer
virtual void Paint(mitk::BaseRenderer *renderer) = 0;
//##Documentation
//## @brief Apply color and opacity read from the PropertyList
virtual void ApplyProperties(mitk::BaseRenderer* renderer);
void MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer);
void MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer);
void MitkRenderOverlay(mitk::BaseRenderer* renderer);
void MitkRenderVolumetricGeometry(mitk::BaseRenderer* renderer);
/**
* \brief Returns whether this is an vtk-based mapper
*/
virtual bool IsVtkBased() const { return false; }
protected:
GLMapper2D();
virtual ~GLMapper2D();
};
} // namespace mitk
#endif /* MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 */
diff --git a/Core/Code/Rendering/mitkGeometry2DDataMapper2D.cpp b/Core/Code/Rendering/mitkGeometry2DDataMapper2D.cpp
index 108cef818e..fb66e66a83 100644
--- a/Core/Code/Rendering/mitkGeometry2DDataMapper2D.cpp
+++ b/Core/Code/Rendering/mitkGeometry2DDataMapper2D.cpp
@@ -1,666 +1,665 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGL.h"
#include "mitkGeometry2DDataMapper2D.h"
#include "mitkBaseRenderer.h"
#include "mitkPlaneGeometry.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkSmartPointerProperty.h"
#include "mitkPlaneOrientationProperty.h"
#include "mitkGeometry2DDataToSurfaceFilter.h"
#include "mitkSurfaceGLMapper2D.h"
#include "mitkLine.h"
#include "mitkNodePredicateDataType.h"
#include "mitkResliceMethodProperty.h"
mitk::Geometry2DDataMapper2D::Geometry2DDataMapper2D()
: m_SurfaceMapper( NULL ), m_DataStorage(NULL), m_ParentNode(NULL),
m_OtherGeometry2Ds(), m_RenderOrientationArrows( false ),
m_ArrowOrientationPositive( true )
{
}
mitk::Geometry2DDataMapper2D::~Geometry2DDataMapper2D()
{
}
const mitk::Geometry2DData* mitk::Geometry2DDataMapper2D::GetInput(void)
{
return static_cast<const Geometry2DData * > ( GetData() );
}
void mitk::Geometry2DDataMapper2D::GenerateData()
{
// collect all Geometry2DDatas accessible from the DataStorage
m_OtherGeometry2Ds.clear();
if (m_DataStorage.IsNull())
return;
mitk::NodePredicateDataType::Pointer p = mitk::NodePredicateDataType::New("Geometry2DData");
mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetDerivations(m_ParentNode, p, false);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
{
if(it->Value().IsNull())
continue;
BaseData* data = it->Value()->GetData();
if (data == NULL)
continue;
Geometry2DData* geometry2dData = dynamic_cast<Geometry2DData*>(data);
if(geometry2dData == NULL)
continue;
PlaneGeometry* planegeometry = dynamic_cast<PlaneGeometry*>(geometry2dData->GetGeometry2D());
if (planegeometry != NULL)
m_OtherGeometry2Ds.push_back(it->Value());
}
}
void mitk::Geometry2DDataMapper2D::Paint(BaseRenderer *renderer)
{
if ( !this->IsVisible(renderer) )
{
return;
}
Geometry2DData::Pointer input = const_cast< Geometry2DData * >(this->GetInput());
// intersecting with ourself?
if ( input.IsNull() || (this->GetInput()->GetGeometry2D() ==
renderer->GetCurrentWorldGeometry2D()) )
{
return; // do nothing!
}
const PlaneGeometry *inputPlaneGeometry =
dynamic_cast< const PlaneGeometry * >( input->GetGeometry2D() );
const PlaneGeometry *worldPlaneGeometry =
dynamic_cast< const PlaneGeometry* >(
renderer->GetCurrentWorldGeometry2D() );
if ( worldPlaneGeometry && inputPlaneGeometry
&& inputPlaneGeometry->GetReferenceGeometry() )
{
DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
assert( displayGeometry );
const Geometry3D *referenceGeometry =
inputPlaneGeometry->GetReferenceGeometry();
// calculate intersection of the plane data with the border of the
// world geometry rectangle
Point2D lineFrom, lineTo;
typedef Geometry3D::TransformType TransformType;
const TransformType *transform = dynamic_cast< const TransformType * >(
referenceGeometry->GetIndexToWorldTransform() );
TransformType::Pointer inverseTransform = TransformType::New();
transform->GetInverse( inverseTransform );
Line3D crossLine, otherCrossLine;
// Calculate the intersection line of the input plane with the world plane
if ( worldPlaneGeometry->IntersectionLine(
inputPlaneGeometry, crossLine ) )
{
BoundingBox::PointType boundingBoxMin, boundingBoxMax;
boundingBoxMin = referenceGeometry->GetBoundingBox()->GetMinimum();
boundingBoxMax = referenceGeometry->GetBoundingBox()->GetMaximum();
if(referenceGeometry->GetImageGeometry())
{
for(unsigned int i = 0; i < 3; ++i)
{
boundingBoxMin[i]-=0.5;
boundingBoxMax[i]-=0.5;
}
}
crossLine.Transform( *inverseTransform );
Point3D point1, point2;
// Then, clip this line with the (transformed) bounding box of the
// reference geometry.
if ( crossLine.BoxLineIntersection(
boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2],
boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2],
crossLine.GetPoint(), crossLine.GetDirection(),
point1, point2 ) == 2 )
{
// Transform the resulting line start and end points into display
// coordinates.
worldPlaneGeometry->Map(
transform->TransformPoint( point1 ), lineFrom );
worldPlaneGeometry->Map(
transform->TransformPoint( point2 ), lineTo );
Line< ScalarType, 2 > mainLine, otherLine;
Line< ScalarType, 2 > primaryHelperLine, secondaryHelperLine;
mainLine.SetPoints( lineFrom, lineTo );
primaryHelperLine.SetPoints( lineFrom, lineTo );
secondaryHelperLine.SetPoints( lineFrom, lineTo );
displayGeometry->WorldToDisplay( lineFrom, lineFrom );
displayGeometry->WorldToDisplay( lineTo, lineTo );
ScalarType lengthInDisplayUnits = (lineTo - lineFrom).GetNorm();
Vector2D mainLineDirectionOrthogonal;
mainLineDirectionOrthogonal[0] = -mainLine.GetDirection()[1];
mainLineDirectionOrthogonal[1] = mainLine.GetDirection()[0];
// lineParams stores the individual segments of the line, which are
// separated by a gap each (to mark the intersection with another
// displayed line)
std::vector< ScalarType > mainLineParams;
std::vector< ScalarType > primaryHelperLineParams;
std::vector< ScalarType > secondaryHelperLineParams;
mainLineParams.reserve( m_OtherGeometry2Ds.size() + 2 );
mainLineParams.push_back( 0.0 );
mainLineParams.push_back( 1.0 );
primaryHelperLineParams.reserve( m_OtherGeometry2Ds.size() + 2 );
primaryHelperLineParams.push_back( 0.0 );
primaryHelperLineParams.push_back( 1.0 );
secondaryHelperLineParams.reserve( m_OtherGeometry2Ds.size() + 2 );
secondaryHelperLineParams.push_back( 0.0 );
secondaryHelperLineParams.push_back( 1.0 );
// Now iterate through all other lines displayed in this window and
// calculate the positions of intersection with the line to be
// rendered; these positions will be stored in lineParams to form a
// gap afterwards.
NodesVectorType::iterator otherPlanesIt = m_OtherGeometry2Ds.begin();
NodesVectorType::iterator otherPlanesEnd = m_OtherGeometry2Ds.end();
//int mainLineThickSlicesMode = 0;
int mainLineThickSlicesNum = 1;
DataNode* dataNodeOfInputPlaneGeometry = NULL;
// Now we have to find the DataNode that contains the inputPlaneGeometry
// in order to determine the state of the thick-slice rendering
while ( otherPlanesIt != otherPlanesEnd )
{
PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >(
static_cast< Geometry2DData * >(
(*otherPlanesIt)->GetData() )->GetGeometry2D() );
// if we have found the correct node
if ( (otherPlane == inputPlaneGeometry)
&& worldPlaneGeometry->IntersectionLine(
otherPlane, otherCrossLine ) )
{
dataNodeOfInputPlaneGeometry = (*otherPlanesIt);
// if( dataNodeOfInputPlaneGeometry )
// {
// mainLineThickSlicesMode = this->DetermineThickSliceMode(dataNodeOfInputPlaneGeometry, mainLineThickSlicesNum);
// }
break;
}
otherPlanesIt++;
}
// if we did not find a dataNode for the inputPlaneGeometry there is nothing we can do from here
if ( dataNodeOfInputPlaneGeometry == NULL )
return;
// Determine if we should draw the area covered by the thick slicing, default is false.
// This will also show the area of slices that do not have thick slice mode enabled
bool showAreaOfThickSlicing = false;
dataNodeOfInputPlaneGeometry->GetBoolProperty( "reslice.thickslices.showarea", showAreaOfThickSlicing );
// get the normal of the inputPlaneGeometry
Vector3D normal = inputPlaneGeometry->GetNormal();
// determine the pixelSpacing in that direction
double thickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal );
// As the inputPlaneGeometry cuts through the center of the slice in the middle
// we have to add 0.5 pixel in order to compensate.
thickSliceDistance *= mainLineThickSlicesNum+0.5;
// not the nicest place to do it, but we have the width of the visible bloc in MM here
// so we store it in this fancy property
dataNodeOfInputPlaneGeometry->SetFloatProperty( "reslice.thickslices.sizeinmm", thickSliceDistance*2 );
if ( showAreaOfThickSlicing )
{
// vectorToHelperLine defines how to reach the helperLine from the mainLine
Vector2D vectorToHelperLine;
vectorToHelperLine = mainLineDirectionOrthogonal;
vectorToHelperLine.Normalize();
// got the right direction, so we multiply the width
vectorToHelperLine *= thickSliceDistance;
// and create the corresponding points
primaryHelperLine.SetPoints( primaryHelperLine.GetPoint1() - vectorToHelperLine,
primaryHelperLine.GetPoint2() - vectorToHelperLine );
secondaryHelperLine.SetPoints( secondaryHelperLine.GetPoint1() + vectorToHelperLine,
secondaryHelperLine.GetPoint2() + vectorToHelperLine );
}
//int otherLineThickSlicesMode = 0;
int otherLineThickSlicesNum = 1;
// by default, there is no gap for the helper lines
ScalarType gapSize = 0.0;
otherPlanesIt = m_OtherGeometry2Ds.begin();
while ( otherPlanesIt != otherPlanesEnd )
{
PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >(
static_cast< Geometry2DData * >(
(*otherPlanesIt)->GetData() )->GetGeometry2D() );
// Just as with the original line, calculate the intersection with
// the world geometry...
if ( (otherPlane != inputPlaneGeometry)
&& worldPlaneGeometry->IntersectionLine(
otherPlane, otherCrossLine ) )
{
//otherLineThickSlicesMode = this->DetermineThickSliceMode((*otherPlanesIt), otherLineThickSlicesNum);
Vector3D normal = otherPlane->GetNormal();
double otherLineThickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), normal );
otherLineThickSliceDistance *= (otherLineThickSlicesNum+0.5)*2;
Point2D otherLineFrom, otherLineTo;
// ... and clip the resulting line segment with the reference
// geometry bounding box.
otherCrossLine.Transform( *inverseTransform );
if ( otherCrossLine.BoxLineIntersection(
boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2],
boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2],
otherCrossLine.GetPoint(), otherCrossLine.GetDirection(),
point1, point2 ) == 2 )
{
worldPlaneGeometry->Map(
transform->TransformPoint( point1 ), otherLineFrom );
worldPlaneGeometry->Map(
transform->TransformPoint( point2 ), otherLineTo );
otherLine.SetPoints( otherLineFrom, otherLineTo );
// then we have to determine the gap position of the main line
// by finding the position at which the two lines cross
this->DetermineParametricCrossPositions( mainLine, otherLine, mainLineParams );
// if the other line is also in thick slice mode, we have to determine the
// gapsize considering the width of that other line and the spacing in its direction
if ( showAreaOfThickSlicing )
{
Vector2D otherLineDirection = otherLine.GetDirection();
otherLineDirection.Normalize();
mainLineDirectionOrthogonal.Normalize();
// determine the gapsize
gapSize = fabs( otherLineThickSliceDistance / ( otherLineDirection*mainLineDirectionOrthogonal ) );
gapSize = gapSize / displayGeometry->GetScaleFactorMMPerDisplayUnit();
// determine the gap positions for the helper lines as well
this->DetermineParametricCrossPositions( primaryHelperLine, otherLine, primaryHelperLineParams );
this->DetermineParametricCrossPositions( secondaryHelperLine, otherLine, secondaryHelperLineParams );
}
}
}
++otherPlanesIt;
}
// If we have to draw the helperlines, the mainline will be drawn as a dashed line
// with a fixed gapsize of 10 pixels
this->DrawLine(renderer,
lengthInDisplayUnits,
mainLine,
mainLineParams,
inputPlaneGeometry,
showAreaOfThickSlicing,
10.0
);
// If drawn, the helperlines are drawn as a solid line. The gapsize depends on the
// width of the crossed line.
if ( showAreaOfThickSlicing )
{
this->DrawLine(renderer,
lengthInDisplayUnits,
primaryHelperLine,
primaryHelperLineParams,
inputPlaneGeometry,
false,
gapSize
);
this->DrawLine(renderer,
lengthInDisplayUnits,
secondaryHelperLine,
secondaryHelperLineParams,
inputPlaneGeometry,
false,
gapSize
);
}
}
}
}
else
{
Geometry2DDataToSurfaceFilter::Pointer surfaceCreator;
SmartPointerProperty::Pointer surfacecreatorprop;
surfacecreatorprop = dynamic_cast< SmartPointerProperty * >(
GetDataNode()->GetProperty(
"surfacegeometry", renderer));
if( (surfacecreatorprop.IsNull()) ||
(surfacecreatorprop->GetSmartPointer().IsNull()) ||
((surfaceCreator = dynamic_cast< Geometry2DDataToSurfaceFilter * >(
surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull())
)
{
surfaceCreator = Geometry2DDataToSurfaceFilter::New();
surfacecreatorprop = SmartPointerProperty::New(surfaceCreator);
surfaceCreator->PlaceByGeometryOn();
GetDataNode()->SetProperty( "surfacegeometry", surfacecreatorprop );
}
surfaceCreator->SetInput( input );
// Clip the Geometry2D with the reference geometry bounds (if available)
if ( input->GetGeometry2D()->HasReferenceGeometry() )
{
surfaceCreator->SetBoundingBox(
input->GetGeometry2D()->GetReferenceGeometry()->GetBoundingBox()
);
}
int res;
bool usegeometryparametricbounds = true;
if ( GetDataNode()->GetIntProperty("xresolution", res, renderer))
{
surfaceCreator->SetXResolution(res);
usegeometryparametricbounds=false;
}
if (GetDataNode()->GetIntProperty("yresolution", res, renderer))
{
surfaceCreator->SetYResolution(res);
usegeometryparametricbounds=false;
}
surfaceCreator->SetUseGeometryParametricBounds(usegeometryparametricbounds);
// Calculate the surface of the Geometry2D
surfaceCreator->Update();
if (m_SurfaceMapper.IsNull())
{
m_SurfaceMapper=SurfaceGLMapper2D::New();
}
m_SurfaceMapper->SetSurface(surfaceCreator->GetOutput());
m_SurfaceMapper->SetDataNode(GetDataNode());
m_SurfaceMapper->Paint(renderer);
}
}
void mitk::Geometry2DDataMapper2D::DrawOrientationArrow( mitk::Point2D &outerPoint, mitk::Point2D &innerPoint,
const mitk::PlaneGeometry *planeGeometry,
const mitk::PlaneGeometry *rendererPlaneGeometry,
const mitk::DisplayGeometry *displayGeometry,
bool positiveOrientation )
{
// Draw arrows to indicate plane orientation
// Vector along line
Vector2D v1 = innerPoint - outerPoint;
v1.Normalize();
v1 *= 7.0;
// Orthogonal vector
Vector2D v2;
v2[0] = v1[1];
v2[1] = -v1[0];
// Calculate triangle tip for one side and project it back into world
// coordinates to determine whether it is above or below the plane
Point2D worldPoint2D;
Point3D worldPoint;
displayGeometry->DisplayToWorld( outerPoint + v1 + v2, worldPoint2D );
rendererPlaneGeometry->Map( worldPoint2D, worldPoint );
// Initialize remaining triangle coordinates accordingly
// (above/below state is XOR'ed with orientation flag)
Point2D p1 = outerPoint + v1 * 2.0;
Point2D p2 = outerPoint + v1
+ ((positiveOrientation ^ planeGeometry->IsAbove( worldPoint ))
? v2 : -v2);
// Draw the arrow (triangle)
glBegin( GL_TRIANGLES );
glVertex2f( outerPoint[0], outerPoint[1] );
glVertex2f( p1[0], p1[1] );
glVertex2f( p2[0], p2[1] );
glEnd();
}
void mitk::Geometry2DDataMapper2D::ApplyProperties( BaseRenderer *renderer )
{
Superclass::ApplyProperties(renderer);
PlaneOrientationProperty* decorationProperty;
this->GetDataNode()->GetProperty( decorationProperty, "decoration", renderer );
if ( decorationProperty != NULL )
{
if ( decorationProperty->GetPlaneDecoration() ==
PlaneOrientationProperty::PLANE_DECORATION_POSITIVE_ORIENTATION )
{
m_RenderOrientationArrows = true;
m_ArrowOrientationPositive = true;
}
else if ( decorationProperty->GetPlaneDecoration() ==
PlaneOrientationProperty::PLANE_DECORATION_NEGATIVE_ORIENTATION )
{
m_RenderOrientationArrows = true;
m_ArrowOrientationPositive = false;
}
else
{
m_RenderOrientationArrows = false;
}
}
}
void mitk::Geometry2DDataMapper2D::SetDatastorageAndGeometryBaseNode( mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent )
{
if (ds.IsNotNull())
{
m_DataStorage = ds;
}
if (parent.IsNotNull())
{
m_ParentNode = parent;
}
}
void mitk::Geometry2DDataMapper2D::DrawLine( BaseRenderer* renderer,
ScalarType lengthInDisplayUnits,
Line<ScalarType,2> &line,
std::vector<ScalarType> &gapPositions,
const PlaneGeometry* inputPlaneGeometry,
bool drawDashed,
ScalarType gapSizeInPixel
)
{
DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
const PlaneGeometry *worldPlaneGeometry =
dynamic_cast< const PlaneGeometry* >( renderer->GetCurrentWorldGeometry2D() );
// Apply color and opacity read from the PropertyList.
this->ApplyProperties( renderer );
ScalarType gapSizeInParamUnits =
1.0 / lengthInDisplayUnits * gapSizeInPixel;
std::sort( gapPositions.begin(), gapPositions.end() );
Point2D p1, p2;
ScalarType p1Param, p2Param;
p1Param = gapPositions[0];
p1 = line.GetPoint( p1Param );
displayGeometry->WorldToDisplay( p1, p1 );
//Workaround to show the crosshair always on top of a 2D render window
//The image is usually located at depth = 0 or negative depth values, and thus,
//the crosshair with depth = 1 is always on top.
float depthPosition = 1.0f;
if ( drawDashed )
{
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, 0xF0F0);
}
glEnable(GL_DEPTH_TEST);
// Iterate over all line segments and display each, with a gap
// in between.
unsigned int i, preLastLineParam = gapPositions.size() - 1;
for ( i = 1; i < preLastLineParam; ++i )
{
p2Param = gapPositions[i] - gapSizeInParamUnits * 0.5;
p2 = line.GetPoint( p2Param );
if ( p2Param > p1Param )
{
// Convert intersection points (until now mm) to display
// coordinates (units).
displayGeometry->WorldToDisplay( p2, p2 );
// draw
glBegin (GL_LINES);
glVertex3f(p1[0],p1[1], depthPosition);
glVertex3f(p2[0],p2[1], depthPosition);
glEnd ();
if ( (i == 1) && (m_RenderOrientationArrows) )
{
// Draw orientation arrow for first line segment
this->DrawOrientationArrow( p1, p2,
inputPlaneGeometry, worldPlaneGeometry, displayGeometry,
m_ArrowOrientationPositive );
}
}
p1Param = p2Param + gapSizeInParamUnits;
p1 = line.GetPoint( p1Param );
displayGeometry->WorldToDisplay( p1, p1 );
}
// Draw last line segment
p2Param = gapPositions[i];
p2 = line.GetPoint( p2Param );
displayGeometry->WorldToDisplay( p2, p2 );
glBegin( GL_LINES );
glVertex3f( p1[0], p1[1], depthPosition);
glVertex3f( p2[0], p2[1], depthPosition);
glEnd();
if ( drawDashed )
{
glDisable(GL_LINE_STIPPLE);
}
// Draw orientation arrows
if ( m_RenderOrientationArrows )
{
this->DrawOrientationArrow( p2, p1,
inputPlaneGeometry, worldPlaneGeometry, displayGeometry,
m_ArrowOrientationPositive );
if ( preLastLineParam < 2 )
{
// If we only have one line segment, draw other arrow, too
this->DrawOrientationArrow( p1, p2,
inputPlaneGeometry, worldPlaneGeometry, displayGeometry,
m_ArrowOrientationPositive );
}
}
}
int mitk::Geometry2DDataMapper2D::DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum )
{
int thickSlicesMode = 0;
// determine the state and the extend of the thick-slice mode
mitk::ResliceMethodProperty *resliceMethodEnumProperty=0;
if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty )
thickSlicesMode = resliceMethodEnumProperty->GetValueAsId();
IntProperty *intProperty=0;
if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty )
{
thickSlicesNum = intProperty->GetValue();
if(thickSlicesNum < 1) thickSlicesNum=0;
if(thickSlicesNum > 10) thickSlicesNum=10;
}
if ( thickSlicesMode == 0 )
thickSlicesNum = 0;
return thickSlicesMode;
}
void mitk::Geometry2DDataMapper2D::DetermineParametricCrossPositions( Line< mitk::ScalarType, 2 > &mainLine,
Line< mitk::ScalarType, 2 > &otherLine,
std::vector< mitk::ScalarType > &crossPositions )
{
Vector2D direction, dOrth;
// By means of the dot product, calculate the gap position as
// parametric value in the range [0, 1]
direction = otherLine.GetDirection();
dOrth[0] = -direction[1]; dOrth[1] = direction[0];
ScalarType gapPosition = ( otherLine.GetPoint1() - mainLine.GetPoint1() ) * dOrth;
ScalarType norm = mainLine.GetDirection() * dOrth;
if ( fabs( norm ) > eps )
{
gapPosition /= norm;
if ( (gapPosition > 0.0) && (gapPosition < 1.0) )
{
crossPositions.push_back(gapPosition);
}
}
}
diff --git a/Core/Code/Rendering/mitkGeometry2DDataMapper2D.h b/Core/Code/Rendering/mitkGeometry2DDataMapper2D.h
index c2bd74c00f..56d2db7d50 100644
--- a/Core/Code/Rendering/mitkGeometry2DDataMapper2D.h
+++ b/Core/Code/Rendering/mitkGeometry2DDataMapper2D.h
@@ -1,123 +1,122 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB
#define MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB
#include <MitkExports.h>
#include "mitkGLMapper2D.h"
#include "mitkSurfaceGLMapper2D.h"
#include "mitkDataStorage.h"
#include "mitkDataNode.h"
#include "mitkWeakPointer.h"
namespace mitk {
class BaseRenderer;
/**
* \brief OpenGL-based mapper to display a Geometry2D in a 2D window
*
* Currently implemented for mapping on PlaneGeometry.
* The result is normally a line. An important usage of this class is to show
* the orientation of the slices displayed in other 2D windows.
*
*
* Properties that can be set and influence the Geometry2DDataMapper2D are:
*
* - \b "PlaneOrientationProperty": (PlaneOrientationProperty)
* \todo implement for AbstractTransformGeometry.
* \ingroup Mapper
*/
class MITK_CORE_EXPORT Geometry2DDataMapper2D : public GLMapper2D
{
public:
mitkClassMacro(Geometry2DDataMapper2D, GLMapper2D);
itkNewMacro(Self);
/**
* \brief Get the Geometry2DData to map
*/
const Geometry2DData *GetInput();
virtual void Paint( BaseRenderer *renderer );
virtual void SetDatastorageAndGeometryBaseNode(mitk::DataStorage::Pointer ds, mitk::DataNode::Pointer parent);
/** Applies properties specific to this mapper */
virtual void ApplyProperties( BaseRenderer *renderer );
protected:
Geometry2DDataMapper2D();
virtual ~Geometry2DDataMapper2D();
virtual void GenerateData();
/**
* \brief Returns the thick slice mode for the given datanode.
*
* This method returns the value of the 'reslice.thickslices' property for
* the given datanode.
* '0': thick slice mode disabled
* '1': thick slice mode enabled
*
* The variable 'thickSlicesNum' contains the value of the 'reslice.thickslices.num'
* property that defines how many slices are shown at once.
*/
int DetermineThickSliceMode( DataNode * dn, int &thickSlicesNum );
/**
* \brief Determines the cross position of two lines and stores them as parametric coordinates
*
* This method determines the parametric position at which a line 'otherLine' crosses another line
* 'mainLine'. The result is stored in 'crossPositions'.
*/
void DetermineParametricCrossPositions( Line<ScalarType,2> &mainLine, Line<ScalarType,2> &otherLine, std::vector<ScalarType> &crossPositions );
void DrawLine( BaseRenderer * renderer, ScalarType lengthInDisplayUnits,
Line< ScalarType, 2 > &line, std::vector< ScalarType > &gapPositions,
const PlaneGeometry * inputPlaneGeometry, bool drawDashed,
ScalarType gapSizeInPixel
);
void DrawOrientationArrow( Point2D &outerPoint, Point2D &innerPoint,
const PlaneGeometry *planeGeometry,
const PlaneGeometry *rendererPlaneGeometry,
const DisplayGeometry *displayGeometry,
bool positiveOrientation = true );
SurfaceGLMapper2D::Pointer m_SurfaceMapper;
mitk::WeakPointer<mitk::DataStorage> m_DataStorage; ///< DataStorage that will be searched for sub nodes
DataNode::Pointer m_ParentNode; ///< parent node that will be used to search for sub nodes
typedef std::vector<DataNode*> NodesVectorType;
NodesVectorType m_OtherGeometry2Ds;
bool m_RenderOrientationArrows;
bool m_ArrowOrientationPositive;
};
} // namespace mitk
#endif /* MITKGEOMETRY2DDATAMAPPER2D_H_HEADER_INCLUDED_C19C0BFB */
diff --git a/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.cpp b/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.cpp
index 5d0ab6050b..aa29386111 100644
--- a/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.cpp
+++ b/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.cpp
@@ -1,573 +1,578 @@
-/*=========================================================================
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+/*===================================================================
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGeometry2DDataVtkMapper3D.h"
#include "mitkImageVtkMapper2D.h"
#include "mitkSmartPointerProperty.h"
#include "mitkSurface.h"
#include "mitkVtkRepresentationProperty.h"
#include "mitkWeakPointerProperty.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateOr.h"
#include <vtkAssembly.h>
#include <vtkDataSetMapper.h>
#include <vtkFeatureEdges.h>
#include <vtkHedgeHog.h>
#include <vtkImageData.h>
#include <vtkLinearTransform.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProp3DCollection.h>
#include <vtkProperty.h>
#include <vtkTexture.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkTubeFilter.h>
namespace mitk
{
Geometry2DDataVtkMapper3D::Geometry2DDataVtkMapper3D()
: m_NormalsActorAdded(false),
m_DataStorage(NULL)
{
m_EdgeTuber = vtkTubeFilter::New();
m_EdgeMapper = vtkPolyDataMapper::New();
m_SurfaceCreator = Geometry2DDataToSurfaceFilter::New();
m_SurfaceCreatorBoundingBox = BoundingBox::New();
m_SurfaceCreatorPointsContainer = BoundingBox::PointsContainer::New();
m_Edges = vtkFeatureEdges::New();
m_Edges->BoundaryEdgesOn();
m_Edges->FeatureEdgesOff();
m_Edges->NonManifoldEdgesOff();
m_Edges->ManifoldEdgesOff();
m_EdgeTransformer = vtkTransformPolyDataFilter::New();
m_NormalsTransformer = vtkTransformPolyDataFilter::New();
m_EdgeActor = vtkActor::New();
m_BackgroundMapper = vtkPolyDataMapper::New();
m_BackgroundActor = vtkActor::New();
m_Prop3DAssembly = vtkAssembly::New();
m_ImageAssembly = vtkAssembly::New();
m_SurfaceCreatorBoundingBox->SetPoints( m_SurfaceCreatorPointsContainer );
m_Cleaner = vtkCleanPolyData::New();
m_Cleaner->PieceInvariantOn();
m_Cleaner->ConvertLinesToPointsOn();
m_Cleaner->ConvertPolysToLinesOn();
m_Cleaner->ConvertStripsToPolysOn();
m_Cleaner->PointMergingOn();
// Make sure that the FeatureEdge algorithm is initialized with a "valid"
// (though empty) input
vtkPolyData *emptyPolyData = vtkPolyData::New();
m_Cleaner->SetInput( emptyPolyData );
emptyPolyData->Delete();
m_Edges->SetInput(m_Cleaner->GetOutput());
m_EdgeTransformer->SetInput( m_Edges->GetOutput() );
m_EdgeTuber->SetInput( m_EdgeTransformer->GetOutput() );
m_EdgeTuber->SetVaryRadiusToVaryRadiusOff();
m_EdgeTuber->SetNumberOfSides( 12 );
m_EdgeTuber->CappingOn();
m_EdgeMapper->SetInput( m_EdgeTuber->GetOutput() );
m_EdgeMapper->ScalarVisibilityOff();
m_BackgroundMapper->SetInput(emptyPolyData);
m_EdgeActor->SetMapper( m_EdgeMapper );
m_BackgroundActor->GetProperty()->SetAmbient( 0.5 );
m_BackgroundActor->GetProperty()->SetColor( 0.0, 0.0, 0.0 );
m_BackgroundActor->GetProperty()->SetOpacity( 1.0 );
m_BackgroundActor->SetMapper( m_BackgroundMapper );
vtkProperty * backfaceProperty = m_BackgroundActor->MakeProperty();
backfaceProperty->SetColor( 0.0, 0.0, 0.0 );
m_BackgroundActor->SetBackfaceProperty( backfaceProperty );
backfaceProperty->Delete();
m_FrontHedgeHog = vtkHedgeHog::New();
m_BackHedgeHog = vtkHedgeHog::New();
m_FrontNormalsMapper = vtkPolyDataMapper::New();
m_FrontNormalsMapper->SetInput( m_FrontHedgeHog->GetOutput() );
m_BackNormalsMapper = vtkPolyDataMapper::New();
m_Prop3DAssembly->AddPart( m_EdgeActor );
m_Prop3DAssembly->AddPart( m_ImageAssembly );
m_FrontNormalsActor = vtkActor::New();
m_FrontNormalsActor->SetMapper(m_FrontNormalsMapper);
m_BackNormalsActor = vtkActor::New();
m_BackNormalsActor->SetMapper(m_BackNormalsMapper);
m_ImageMapperDeletedCommand = MemberCommandType::New();
m_ImageMapperDeletedCommand->SetCallbackFunction(
this, &Geometry2DDataVtkMapper3D::ImageMapperDeletedCallback );
}
Geometry2DDataVtkMapper3D::~Geometry2DDataVtkMapper3D()
{
m_ImageAssembly->Delete();
m_Prop3DAssembly->Delete();
m_EdgeTuber->Delete();
m_EdgeMapper->Delete();
m_EdgeTransformer->Delete();
m_Cleaner->Delete();
m_Edges->Delete();
m_NormalsTransformer->Delete();
m_EdgeActor->Delete();
m_BackgroundMapper->Delete();
m_BackgroundActor->Delete();
m_FrontNormalsMapper->Delete();
m_FrontNormalsActor->Delete();
m_FrontHedgeHog->Delete();
m_BackNormalsMapper->Delete();
m_BackNormalsActor->Delete();
m_BackHedgeHog->Delete();
// Delete entries in m_ImageActors list one by one
m_ImageActors.clear();
m_DataStorage = NULL;
}
vtkProp* Geometry2DDataVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/)
{
if ( (this->GetDataNode() != NULL )
&& (m_ImageAssembly != NULL) )
{
// Do not transform the entire Prop3D assembly, but only the image part
// here. The colored frame is transformed elsewhere (via m_EdgeTransformer),
// since only vertices should be transformed there, not the poly data
// itself, to avoid distortion for anisotropic datasets.
m_ImageAssembly->SetUserTransform( this->GetDataNode()->GetVtkTransform() );
}
return m_Prop3DAssembly;
}
void Geometry2DDataVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/)
{
m_ImageAssembly->SetUserTransform(
this->GetDataNode()->GetVtkTransform(this->GetTimestep()) );
}
const Geometry2DData* Geometry2DDataVtkMapper3D::GetInput()
{
return static_cast<const Geometry2DData * > ( GetData() );
}
void Geometry2DDataVtkMapper3D::SetDataStorageForTexture(mitk::DataStorage* storage)
{
if(storage != NULL && m_DataStorage != storage )
{
m_DataStorage = storage;
this->Modified();
}
}
void Geometry2DDataVtkMapper3D::ImageMapperDeletedCallback(
itk::Object *caller, const itk::EventObject& /*event*/ )
{
ImageVtkMapper2D *imageMapper = dynamic_cast< ImageVtkMapper2D * >( caller );
if ( (imageMapper != NULL) )
{
if ( m_ImageActors.count( imageMapper ) > 0)
{
m_ImageActors[imageMapper].m_Sender = NULL; // sender is already destroying itself
m_ImageActors.erase( imageMapper );
}
}
}
void Geometry2DDataVtkMapper3D::GenerateDataForRenderer(BaseRenderer* renderer)
{
SetVtkMapperImmediateModeRendering(m_EdgeMapper);
SetVtkMapperImmediateModeRendering(m_BackgroundMapper);
// Remove all actors from the assembly, and re-initialize it with the
// edge actor
m_ImageAssembly->GetParts()->RemoveAllItems();
if ( !this->IsVisible(renderer) )
{
// visibility has explicitly to be set in the single actors
// due to problems when using cell picking:
// even if the assembly is invisible, the renderer contains
// references to the assemblies parts. During picking the
// visibility of each part is checked, and not only for the
// whole assembly.
m_ImageAssembly->VisibilityOff();
m_EdgeActor->VisibilityOff();
return;
}
// visibility has explicitly to be set in the single actors
// due to problems when using cell picking:
// even if the assembly is invisible, the renderer contains
// references to the assemblies parts. During picking the
// visibility of each part is checked, and not only for the
// whole assembly.
m_ImageAssembly->VisibilityOn();
m_EdgeActor->VisibilityOn();
Geometry2DData::Pointer input = const_cast< Geometry2DData * >(this->GetInput());
if (input.IsNotNull() && (input->GetGeometry2D() != NULL))
{
SmartPointerProperty::Pointer surfacecreatorprop;
surfacecreatorprop = dynamic_cast< SmartPointerProperty * >(GetDataNode()->GetProperty("surfacegeometry", renderer));
if ( (surfacecreatorprop.IsNull())
|| (surfacecreatorprop->GetSmartPointer().IsNull())
|| ((m_SurfaceCreator = dynamic_cast<Geometry2DDataToSurfaceFilter*>
(surfacecreatorprop->GetSmartPointer().GetPointer())).IsNull() ) )
{
m_SurfaceCreator->PlaceByGeometryOn();
surfacecreatorprop = SmartPointerProperty::New( m_SurfaceCreator );
GetDataNode()->SetProperty("surfacegeometry", surfacecreatorprop);
}
m_SurfaceCreator->SetInput(input);
int res;
if (GetDataNode()->GetIntProperty("xresolution", res, renderer))
{
m_SurfaceCreator->SetXResolution(res);
}
if (GetDataNode()->GetIntProperty("yresolution", res, renderer))
{
m_SurfaceCreator->SetYResolution(res);
}
double tubeRadius = 1.0; // Radius of tubular edge surrounding plane
// Clip the Geometry2D with the reference geometry bounds (if available)
if ( input->GetGeometry2D()->HasReferenceGeometry() )
{
Geometry3D *referenceGeometry =
input->GetGeometry2D()->GetReferenceGeometry();
BoundingBox::PointType boundingBoxMin, boundingBoxMax;
boundingBoxMin = referenceGeometry->GetBoundingBox()->GetMinimum();
boundingBoxMax = referenceGeometry->GetBoundingBox()->GetMaximum();
if ( referenceGeometry->GetImageGeometry() )
{
for ( unsigned int i = 0; i < 3; ++i )
{
boundingBoxMin[i] -= 0.5;
boundingBoxMax[i] -= 0.5;
}
}
m_SurfaceCreatorPointsContainer->CreateElementAt( 0 ) = boundingBoxMin;
m_SurfaceCreatorPointsContainer->CreateElementAt( 1 ) = boundingBoxMax;
m_SurfaceCreatorBoundingBox->ComputeBoundingBox();
m_SurfaceCreator->SetBoundingBox( m_SurfaceCreatorBoundingBox );
tubeRadius = referenceGeometry->GetDiagonalLength() / 450.0;
}
// If no reference geometry is available, clip with the current global
// bounds
else if (m_DataStorage.IsNotNull())
{
m_SurfaceCreator->SetBoundingBox(m_DataStorage->ComputeVisibleBoundingBox(NULL, "includeInBoundingBox"));
tubeRadius = sqrt( m_SurfaceCreator->GetBoundingBox()->GetDiagonalLength2() ) / 450.0;
}
// Calculate the surface of the Geometry2D
m_SurfaceCreator->Update();
Surface *surface = m_SurfaceCreator->GetOutput();
// Check if there's something to display, otherwise return
if ( (surface->GetVtkPolyData() == 0 )
|| (surface->GetVtkPolyData()->GetNumberOfCells() == 0) )
{
m_ImageAssembly->VisibilityOff();
return;
}
// add a graphical representation of the surface normals if requested
DataNode* node = this->GetDataNode();
bool displayNormals = false;
bool colorTwoSides = false;
bool invertNormals = false;
node->GetBoolProperty("draw normals 3D", displayNormals, renderer);
node->GetBoolProperty("color two sides", colorTwoSides, renderer);
node->GetBoolProperty("invert normals", invertNormals, renderer);
//if we want to draw the display normals or render two sides we have to get the colors
if( displayNormals || colorTwoSides )
{
//get colors
float frontColor[3] = { 0.0, 0.0, 1.0 };
node->GetColor( frontColor, renderer, "front color" );
float backColor[3] = { 1.0, 0.0, 0.0 };
node->GetColor( backColor, renderer, "back color" );
if ( displayNormals )
{
m_NormalsTransformer->SetInput( surface->GetVtkPolyData() );
m_NormalsTransformer->SetTransform(node->GetVtkTransform(this->GetTimestep()) );
m_FrontHedgeHog->SetInput( m_NormalsTransformer->GetOutput() );
m_FrontHedgeHog->SetVectorModeToUseNormal();
m_FrontHedgeHog->SetScaleFactor( invertNormals ? 1.0 : -1.0 );
m_FrontNormalsActor->GetProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] );
m_BackHedgeHog->SetInput( m_NormalsTransformer->GetOutput() );
m_BackHedgeHog->SetVectorModeToUseNormal();
m_BackHedgeHog->SetScaleFactor( invertNormals ? -1.0 : 1.0 );
m_BackNormalsActor->GetProperty()->SetColor( backColor[0], backColor[1], backColor[2] );
//if there is no actor added yet, add one
if ( !m_NormalsActorAdded )
{
m_Prop3DAssembly->AddPart( m_FrontNormalsActor );
m_Prop3DAssembly->AddPart( m_BackNormalsActor );
m_NormalsActorAdded = true;
}
}
//if we don't want to display normals AND there is an actor added remove the actor
else if ( m_NormalsActorAdded )
{
m_Prop3DAssembly->RemovePart( m_FrontNormalsActor );
m_Prop3DAssembly->RemovePart( m_BackNormalsActor );
m_NormalsActorAdded = false;
}
if ( colorTwoSides )
{
if ( !invertNormals )
{
m_BackgroundActor->GetProperty()->SetColor( backColor[0], backColor[1], backColor[2] );
m_BackgroundActor->GetBackfaceProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] );
}
else
{
m_BackgroundActor->GetProperty()->SetColor( frontColor[0], frontColor[1], frontColor[2] );
m_BackgroundActor->GetBackfaceProperty()->SetColor( backColor[0], backColor[1], backColor[2] );
}
}
}
// Add black background for all images (which may be transparent)
m_BackgroundMapper->SetInput( surface->GetVtkPolyData() );
m_ImageAssembly->AddPart( m_BackgroundActor );
LayerSortedActorList layerSortedActors;
// Traverse the data tree to find nodes resliced by ImageMapperGL2D
mitk::NodePredicateOr::Pointer p = mitk::NodePredicateOr::New();
//use a predicate to get all data nodes which are "images" or inherit from mitk::Image
mitk::TNodePredicateDataType< mitk::Image >::Pointer predicateAllImages = mitk::TNodePredicateDataType< mitk::Image >::New();
mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetSubset(predicateAllImages);
//process all found images
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
{
DataNode *node = it->Value();
if (node != NULL)
this->ProcessNode(node, renderer, surface, layerSortedActors);
}
// Add all image actors to the assembly, sorted according to
// layer property
LayerSortedActorList::iterator actorIt;
for ( actorIt = layerSortedActors.begin(); actorIt != layerSortedActors.end(); ++actorIt )
{
m_ImageAssembly->AddPart( actorIt->second );
}
// Configurate the tube-shaped frame: size according to the surface
// bounds, color as specified in the plane's properties
vtkPolyData *surfacePolyData = surface->GetVtkPolyData();
m_Cleaner->SetInput(surfacePolyData);
m_EdgeTransformer->SetTransform(this->GetDataNode()->GetVtkTransform(this->GetTimestep()) );
// Adjust the radius according to extent
m_EdgeTuber->SetRadius( tubeRadius );
// Get the plane's color and set the tube properties accordingly
ColorProperty::Pointer colorProperty;
colorProperty = dynamic_cast<ColorProperty*>(this->GetDataNode()->GetProperty( "color" ));
if ( colorProperty.IsNotNull() )
{
const Color& color = colorProperty->GetColor();
m_EdgeActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue());
}
else
{
m_EdgeActor->GetProperty()->SetColor( 1.0, 1.0, 1.0 );
}
m_ImageAssembly->SetUserTransform(this->GetDataNode()->GetVtkTransform(this->GetTimestep()) );
}
VtkRepresentationProperty* representationProperty;
this->GetDataNode()->GetProperty(representationProperty, "material.representation", renderer);
if ( representationProperty != NULL )
m_BackgroundActor->GetProperty()->SetRepresentation( representationProperty->GetVtkRepresentation() );
}
void Geometry2DDataVtkMapper3D::ProcessNode( DataNode * node, BaseRenderer* renderer,
Surface * surface, LayerSortedActorList &layerSortedActors )
{
if ( node != NULL )
{
//we need to get the information from the 2D mapper to render the texture on the 3D plane
ImageVtkMapper2D *imageMapper = dynamic_cast< ImageVtkMapper2D * >( node->GetMapper(1) ); //GetMapper(1) provides the 2D mapper for the data node
//if there is a 2D mapper, which is not the standard image mapper...
if(!imageMapper && node->GetMapper(1))
{ //... check if it is the composite mapper
std::string cname(node->GetMapper(1)->GetNameOfClass());
if(!cname.compare("CompositeMapper")) //string.compare returns 0 if the two strings are equal.
{
//get the standard image mapper.
//This is a special case in MITK and does only work for the CompositeMapper.
imageMapper = dynamic_cast<ImageVtkMapper2D* >( node->GetMapper(3) );
}
}
if ( (node->IsVisible(renderer)) && imageMapper )
{
WeakPointerProperty::Pointer rendererProp =
dynamic_cast< WeakPointerProperty * >(GetDataNode()->GetPropertyList()->GetProperty("renderer"));
if ( rendererProp.IsNotNull() )
{
BaseRenderer::Pointer planeRenderer = dynamic_cast< BaseRenderer * >(rendererProp->GetWeakPointer().GetPointer());
// Retrieve and update image to be mapped
const ImageVtkMapper2D::LocalStorage* localStorage = imageMapper->GetLocalStorage(planeRenderer);
if ( planeRenderer.IsNotNull() )
{
// If it has not been initialized already in a previous pass,
// generate an actor and a texture object to
// render the image associated with the ImageVtkMapper2D.
vtkActor *imageActor;
vtkDataSetMapper *dataSetMapper = NULL;
vtkTexture *texture;
if ( m_ImageActors.count( imageMapper ) == 0 )
{
dataSetMapper = vtkDataSetMapper::New();
//Enable rendering without copying the image.
dataSetMapper->ImmediateModeRenderingOn();
texture = vtkTexture::New();
texture->RepeatOff();
imageActor = vtkActor::New();
imageActor->SetMapper( dataSetMapper );
imageActor->SetTexture( texture );
// Make imageActor the sole owner of the mapper and texture
// objects
dataSetMapper->UnRegister( NULL );
texture->UnRegister( NULL );
// Store the actor so that it may be accessed in following
// passes.
m_ImageActors[imageMapper].Initialize(imageActor, imageMapper, m_ImageMapperDeletedCommand);
}
else
{
// Else, retrieve the actor and associated objects from the
// previous pass.
imageActor = m_ImageActors[imageMapper].m_Actor;
dataSetMapper = (vtkDataSetMapper *)imageActor->GetMapper();
texture = imageActor->GetTexture();
}
// Set poly data new each time its object changes (e.g. when
// switching between planar and curved geometries)
if ( (dataSetMapper != NULL) && (dataSetMapper->GetInput() != surface->GetVtkPolyData()) )
{
dataSetMapper->SetInput( surface->GetVtkPolyData() );
}
if(localStorage->m_ReslicedImage != NULL)
{
bool binaryOutline = node->IsOn( "outline binary", renderer );
if( binaryOutline )
{
texture->SetInput( localStorage->m_ReslicedImage );
}
else
{
texture->SetInput( localStorage->m_Texture->GetInput() );
}
// VTK (mis-)interprets unsigned char (binary) images as color images;
// So, we must manually turn on their mapping through a (gray scale) lookup table;
texture->SetMapColorScalarsThroughLookupTable( localStorage->m_Texture->GetMapColorScalarsThroughLookupTable() );
//re-use properties from the 2D image mapper
imageActor->SetProperty( localStorage->m_Actor->GetProperty() );
imageActor->GetProperty()->SetAmbient(0.5);
// Set texture interpolation on/off
bool textureInterpolation = node->IsOn( "texture interpolation", renderer );
texture->SetInterpolate( textureInterpolation );
//get the lookuptable from the 2D image mapper
texture->SetLookupTable( localStorage->m_Texture->GetLookupTable() );
// Store this actor to be added to the actor assembly, sort
// by layer
int layer = 1;
node->GetIntProperty( "layer", layer );
layerSortedActors.insert(std::pair< int, vtkActor * >( layer, imageActor ) );
}
}
}
}
}
}
void Geometry2DDataVtkMapper3D::ActorInfo::Initialize(vtkActor* actor, itk::Object* sender, itk::Command* command)
{
m_Actor = actor;
m_Sender = sender;
// Get informed when ImageMapper object is deleted, so that
// the data structures built here can be deleted as well
m_ObserverID = sender->AddObserver( itk::DeleteEvent(), command );
}
Geometry2DDataVtkMapper3D::ActorInfo::ActorInfo() : m_Actor(NULL), m_Sender(NULL), m_ObserverID(0)
{
}
Geometry2DDataVtkMapper3D::ActorInfo::~ActorInfo()
{
if(m_Sender != NULL)
{
m_Sender->RemoveObserver(m_ObserverID);
}
if(m_Actor != NULL)
{
m_Actor->Delete();
}
}
} // namespace mitk
diff --git a/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.h b/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.h
index fc6cbf5146..427ab02e5a 100644
--- a/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.h
+++ b/Core/Code/Rendering/mitkGeometry2DDataVtkMapper3D.h
@@ -1,211 +1,210 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKGEOMETRY2DDATAVTKMAPPER3D_H_HEADER_INCLUDED_C196C71F
#define MITKGEOMETRY2DDATAVTKMAPPER3D_H_HEADER_INCLUDED_C196C71F
#include <MitkExports.h>
#include "mitkVtkMapper3D.h"
#include "mitkDataStorage.h"
#include "mitkGeometry2DDataToSurfaceFilter.h"
#include "mitkWeakPointer.h"
#include <vtkSystemIncludes.h>
#include <vtkCleanPolyData.h>
class vtkActor;
class vtkPolyDataMapper;
class vtkAssembly;
class vtkFeatureEdges;
class vtkTubeFilter;
class vtkTransformPolyDataFilter;
class vtkHedgeHog;
namespace mitk {
class Geometry2DData;
class BaseRenderer;
class ImageVtkMapper2D;
class DataStorage;
/**
* \brief Vtk-based mapper to display a Geometry2D in a 3D window
* \ingroup Mapper
*
* Uses a Geometry2DDataToSurfaceFilter object to create a vtkPolyData representation of a given Geometry2D instance.
* Geometry2D may either contain a common flat plane or a curved plane (ThinPlateSplineCurvedGeometry).
*
* The vtkPolyData object is then decorated by a colored tube on the edges and by image textures if possible
* (currently this requires that there is a 2D render window rendering the same geometry as this mapper).
*
* Properties that influence rendering are:
*
* - \b "color": (ColorProperty) Color of the tubed frame.
* - \b "xresolution": (FloatProperty) Resolution (=number of tiles) in x direction. Only relevant for ThinPlateSplineCurvedGeometry
* - \b "yresolution": (FloatProperty) Resolution (=number of tiles) in y direction. Only relevant for ThinPlateSplineCurvedGeometry
* - \b "draw normals 3D": (BoolProperty) If true, a vtkHedgeHog is used to display normals for the generated surface object. Useful to distinguish front and back of a plane. Hedgehogs are colored according to "front color" and "back color"
* - \b "color two sides": (BoolProperty) If true, front and back side of the plane are colored differently ("front color" and "back color")
* - \b "invert normals": (BoolProperty) Inverts front/back for display.
* - \b "front color": (ColorProperty) Color for front side of the plane
* - \b "back color": (ColorProperty) Color for back side of the plane
* - \b "material.representation": (BoolProperty) Choose the representation to draw the mesh in (Surface, Wireframe, Point Cloud)
* - \b "surfacegeometry": TODO: Add documentation
* - \b "LookupTable": (LookupTableProperty) Set the lookuptable to render with.
*
* Note: The following properties are set for each image individually, and thus, also influence the rendering of this mapper:
*
* - \b "texture interpolation": (BoolProperty) Turn on/off the texture interpolation of each image
* - \b "use color": (BoolProperty) Decide whether we want to use the color property or a lookuptable.
* - \b "binary": (BoolProperty) Binary image handling: Color the value=1.0 with the color property and make the background (value=0.0) of the image translucent.
* - \b "layer": (IntProperty) Controls what image is considered "on top" of another. In the case that two should inhabit the same space, higher layer occludes lower layer.
* - \b "opacity": (FloatProperty) Set the opacity for each rendered image.
* - \b "color": (FloatProperty) Set the color for each rendered image.
*
* The internal filter pipeline which combines a (sometimes deformed) 2D surface
* with a nice frame and image textures is illustrated in the following sketch:
*
* \image html mitkGeometry2DDataVtkMapper3D.png "Internal filter pipeline"
*
*/
class MITK_CORE_EXPORT Geometry2DDataVtkMapper3D : public VtkMapper3D
{
public:
mitkClassMacro(Geometry2DDataVtkMapper3D, VtkMapper3D);
itkNewMacro(Geometry2DDataVtkMapper3D);
/**
* Overloaded since the displayed color-frame of the image mustn't be
* transformed after generation of poly data, but before (vertex coordinates
* only)
*/
virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer);
virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer);
/**
* \brief Get the Geometry2DData to map
*/
virtual const Geometry2DData *GetInput();
/**
* \brief All images found when traversing the (sub-) tree starting at
* \a iterator which are resliced by an ImageVtkMapper2D will be mapped.
* This method is used to set the data storage to traverse. This offers
* the possibility to use this mapper for other data storages (not only
* the default data storage).
*/
virtual void SetDataStorageForTexture(mitk::DataStorage* storage);
protected:
typedef std::multimap< int, vtkActor * > LayerSortedActorList;
Geometry2DDataVtkMapper3D();
virtual ~Geometry2DDataVtkMapper3D();
virtual void GenerateDataForRenderer(BaseRenderer* renderer);
void ProcessNode( DataNode * node, BaseRenderer* renderer, Surface * surface, LayerSortedActorList &layerSortedActors );
void ImageMapperDeletedCallback( itk::Object *caller, const itk::EventObject &event );
/** \brief general PropAssembly to hold the entire scene */
vtkAssembly *m_Prop3DAssembly;
/** \brief PropAssembly to hold the planes */
vtkAssembly *m_ImageAssembly;
Geometry2DDataToSurfaceFilter::Pointer m_SurfaceCreator;
BoundingBox::Pointer m_SurfaceCreatorBoundingBox;
BoundingBox::PointsContainer::Pointer m_SurfaceCreatorPointsContainer;
/** \brief Edge extractor for tube-shaped frame */
vtkFeatureEdges *m_Edges;
/** \brief Filter to apply object transform to the extracted edges */
vtkTransformPolyDataFilter *m_EdgeTransformer;
/** \brief Source to create the tube-shaped frame */
vtkTubeFilter *m_EdgeTuber;
/** \brief Mapper for the tube-shaped frame */
vtkPolyDataMapper *m_EdgeMapper;
/** \brief Actor for the tube-shaped frame */
vtkActor *m_EdgeActor;
/** \brief Mapper for black plane background */
vtkPolyDataMapper *m_BackgroundMapper;
/** \brief Actor for black plane background */
vtkActor *m_BackgroundActor;
/** \brief Transforms the suface before applying the glyph filter */
vtkTransformPolyDataFilter* m_NormalsTransformer;
/** \brief Mapper for normals representation (thin lines) */
vtkPolyDataMapper* m_FrontNormalsMapper;
vtkPolyDataMapper* m_BackNormalsMapper;
/** \brief Generates lines for surface normals */
vtkHedgeHog* m_FrontHedgeHog;
vtkHedgeHog* m_BackHedgeHog;
/** \brief Actor to hold the normals arrows */
vtkActor* m_FrontNormalsActor;
vtkActor* m_BackNormalsActor;
/** Cleans the polyline in order to avoid phantom boundaries */
vtkCleanPolyData *m_Cleaner;
/** Internal flag, if actors for normals are already added to m_Prop3DAssembly*/
bool m_NormalsActorAdded;
/** \brief The DataStorage defines which part of the data tree is traversed for renderering. */
mitk::WeakPointer<mitk::DataStorage> m_DataStorage;
class MITK_CORE_EXPORT ActorInfo
{
public:
vtkActor * m_Actor;
// we do not need a smart-pointer, because we delete our
// connection, when the referenced mapper is destroyed
itk::Object* m_Sender;
unsigned long m_ObserverID;
void Initialize(vtkActor* actor, itk::Object* sender, itk::Command* command);
ActorInfo();
~ActorInfo();
};
/** \brief List holding the vtkActor to map the image into 3D for each
* ImageMapper
*/
typedef std::map< ImageVtkMapper2D *, ActorInfo > ActorList;
ActorList m_ImageActors;
// responsiblity to remove the observer upon its destruction
typedef itk::MemberCommand< Geometry2DDataVtkMapper3D > MemberCommandType;
MemberCommandType::Pointer m_ImageMapperDeletedCommand;
};
} // namespace mitk
#endif /* MITKGEOMETRY2DDATAVTKMAPPER3D_H_HEADER_INCLUDED_C196C71F */
diff --git a/Core/Code/Rendering/mitkGradientBackground.cpp b/Core/Code/Rendering/mitkGradientBackground.cpp
index f09496e272..cd1cefa162 100644
--- a/Core/Code/Rendering/mitkGradientBackground.cpp
+++ b/Core/Code/Rendering/mitkGradientBackground.cpp
@@ -1,240 +1,239 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkGradientBackground.h"
#include "mitkVtkLayerController.h"
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkMapper.h>
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyData.h>
#include <vtkCamera.h>
#include <vtkLookupTable.h>
#include <vtkCellArray.h>
#include <vtkUnsignedIntArray.h>
#include <vtkPoints.h>
#include <vtkPointData.h>
#include <vtkObjectFactory.h>
#include <vtkRendererCollection.h>
mitk::GradientBackground::GradientBackground()
{
m_RenderWindow = NULL;
m_Renderer = vtkRenderer::New();
m_Actor = vtkActor::New();
m_Mapper = vtkPolyDataMapper::New();
m_Lut = vtkLookupTable::New();
m_Plane = vtkPolyData::New();
vtkPoints* points = vtkPoints::New( );
points->InsertPoint(0,-10,0,0);
points->InsertPoint(1,-10,1,0);
points->InsertPoint(2,10,1,0);
points->InsertPoint(3,10,0,0);
vtkCellArray* cellArray = vtkCellArray::New();
cellArray->InsertNextCell(4);
cellArray->InsertCellPoint(0);
cellArray->InsertCellPoint(1);
cellArray->InsertCellPoint(2);
cellArray->InsertCellPoint(3);
vtkUnsignedIntArray* data = vtkUnsignedIntArray::New();
data->InsertTuple1(0,1);
data->InsertTuple1(1,0);
data->InsertTuple1(2,0);
data->InsertTuple1(3,1);
m_Plane->SetPoints( points );
m_Plane->SetPolys( cellArray );
m_Plane->GetPointData()->SetScalars( data );
points->Delete();
cellArray->Delete();
data->Delete();
m_Lut->SetNumberOfColors( 2 );
m_Lut->Build();
m_Lut->SetTableValue( m_Lut->GetIndex(0), 1, 1, 1 );
m_Lut->SetTableValue( m_Lut->GetIndex(1), 0, 0, 0 );
m_Mapper->SetInput( m_Plane );
m_Mapper->SetLookupTable( m_Lut );
//m_Mapper->ImmediateModeRenderingOn();
m_Actor->SetMapper( m_Mapper );
m_Renderer->AddActor( m_Actor );
m_Renderer->InteractiveOff();
m_Renderer->GetActiveCamera()->ParallelProjectionOn();
m_Renderer->ResetCamera();
m_Renderer->GetActiveCamera()->SetParallelScale(0.5);
}
mitk::GradientBackground::~GradientBackground()
{
if ( m_RenderWindow != NULL )
if ( this->IsEnabled() )
this->Disable();
if ( m_Plane != NULL )
m_Plane->Delete();
if( m_Lut != NULL )
m_Lut->Delete();
if ( m_Mapper != NULL )
m_Mapper->Delete();
if ( m_Actor!=NULL )
m_Actor->Delete();
if ( m_Renderer != NULL )
m_Renderer->Delete();
}
/**
* Sets the renderwindow, in which the gradient background
* will be shown. Make sure, you have called this function
* before calling Enable()
*/
void mitk::GradientBackground::SetRenderWindow( vtkRenderWindow * renderWindow )
{
m_RenderWindow = renderWindow;
}
/**
* Returns the vtkRenderWindow, which is used
* for displaying the gradient background
*/
vtkRenderWindow* mitk::GradientBackground::GetRenderWindow()
{
return m_RenderWindow;
}
/**
* Returns the renderer responsible for
* rendering the color gradient into the
* vtkRenderWindow
*/
vtkRenderer* mitk::GradientBackground::GetVtkRenderer()
{
return m_Renderer;
}
/**
* Returns the actor associated with the color gradient
*/
vtkActor* mitk::GradientBackground::GetActor()
{
return m_Actor;
}
/**
* Returns the mapper associated with the color
* gradient.
*/
vtkPolyDataMapper* mitk::GradientBackground::GetMapper()
{
return m_Mapper;
}
/**
* Sets the gradient colors. The gradient
* will smoothly fade from color1 to color2
*/
void mitk::GradientBackground::SetGradientColors( double r1, double g1, double b1, double r2, double g2, double b2 )
{
m_Lut->SetTableValue( m_Lut->GetIndex(0), r1, g1, b1 );
m_Lut->SetTableValue( m_Lut->GetIndex(1), r2, g2, b2 );
}
void mitk::GradientBackground::SetUpperColor(double r, double g, double b )
{
m_Lut->SetTableValue( m_Lut->GetIndex(0), r, g, b );
}
void mitk::GradientBackground::SetLowerColor(double r, double g, double b )
{
m_Lut->SetTableValue( m_Lut->GetIndex(1), r, g, b );
}
/**
* Enables drawing of the color gradient background.
* If you want to disable it, call the Disable() function.
*/
void mitk::GradientBackground::Enable()
{
mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertBackgroundRenderer(m_Renderer,true);
}
/**
* Disables drawing of the color gradient background.
* If you want to enable it, call the Enable() function.
*/
void mitk::GradientBackground::Disable()
{
if ( this->IsEnabled() )
{
mitk::VtkLayerController::GetInstance(m_RenderWindow)->RemoveRenderer(m_Renderer);
}
}
/**
* Checks, if the gradient background is currently
* enabled (visible)
*/
bool mitk::GradientBackground::IsEnabled()
{
if ( m_RenderWindow == NULL )
return false;
else
return ( mitk::VtkLayerController::GetInstance(m_RenderWindow)->IsRendererInserted(m_Renderer));
}
void mitk::GradientBackground::SetRequestedRegionToLargestPossibleRegion()
{
//nothing to do
}
bool mitk::GradientBackground::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::GradientBackground::VerifyRequestedRegion()
{
return true;
}
void mitk::GradientBackground::SetRequestedRegion(itk::DataObject*)
{
//nothing to do
}
diff --git a/Core/Code/Rendering/mitkGradientBackground.h b/Core/Code/Rendering/mitkGradientBackground.h
index 09d218d2fc..0c0f043818 100644
--- a/Core/Code/Rendering/mitkGradientBackground.h
+++ b/Core/Code/Rendering/mitkGradientBackground.h
@@ -1,160 +1,159 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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 _vtk_Gradient_Background_h_
#define _vtk_Gradient_Background_h_
#include <mitkBaseData.h>
class vtkRenderer;
class vtkMapper;
class vtkActor;
class vtkPolyDataMapper;
class vtkLookupTable;
class vtkPolyData;
class vtkRenderWindow;
namespace mitk {
class RenderWindow;
/**
* Displays a color gradient in the background
* of a vtkRenderWindow.
* The gradient ist faked by displaying a non-interactable
* smoothly shaded plane in a separate layer behind the
* scene. After setting the renderwindow, the gradient may be
* activated by calling Enable()
*/
class MITK_CORE_EXPORT GradientBackground : public BaseData
{
public:
mitkClassMacro( GradientBackground, BaseData );
itkNewMacro( Self );
/**
* Sets the renderwindow, in which the gradient background
* will be shown. Make sure, you have called this function
* before calling Enable()
*/
virtual void SetRenderWindow( vtkRenderWindow* renderWindow );
/**
* Returns the vtkRenderWindow, which is used
* for displaying the gradient background
*/
virtual vtkRenderWindow* GetRenderWindow();
/**
* Returns the renderer responsible for
* rendering the color gradient into the
* vtkRenderWindow
*/
virtual vtkRenderer* GetVtkRenderer();
/**
* Returns the actor associated with the color gradient
*/
virtual vtkActor* GetActor();
/**
* Returns the mapper associated with the color
* gradient.
*/
virtual vtkPolyDataMapper* GetMapper();
/**
* Sets the gradient colors. The gradient
* will smoothly fade from color1 to color2
*/
virtual void SetGradientColors( double r1, double g1, double b1, double r2, double g2, double b2);
virtual void SetUpperColor(double r, double g, double b );
virtual void SetLowerColor(double r, double g, double b );
/**
* Enables drawing of the color gradient background.
* If you want to disable it, call the Disable() function.
*/
virtual void Enable();
/**
* Disables drawing of the color gradient background.
* If you want to enable it, call the Enable() function.
*/
virtual void Disable();
/**
* Checks, if the gradient background is currently
* enabled (visible)
*/
virtual bool IsEnabled();
/**
* Empty implementation, since the GradientBackground doesn't
* support the requested region concept
*/
virtual void SetRequestedRegionToLargestPossibleRegion();
/**
* Empty implementation, since the GradientBackground doesn't
* support the requested region concept
*/
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
/**
* Empty implementation, since the GradientBackground doesn't
* support the requested region concept
*/
virtual bool VerifyRequestedRegion();
/**
* Empty implementation, since the GradientBackground doesn't
* support the requested region concept
*/
virtual void SetRequestedRegion(itk::DataObject*);
protected:
/**
* Constructor
*/
GradientBackground();
/**
* Destructor
*/
~GradientBackground();
vtkRenderWindow* m_RenderWindow;
vtkRenderer* m_Renderer;
vtkActor* m_Actor;
vtkPolyDataMapper* m_Mapper;
vtkLookupTable* m_Lut;
vtkPolyData* m_Plane;
};
} //end of namespace mitk
#endif
diff --git a/Core/Code/Rendering/mitkImageVtkMapper2D.cpp b/Core/Code/Rendering/mitkImageVtkMapper2D.cpp
index 883a6cf0ea..f4950792b1 100644
--- a/Core/Code/Rendering/mitkImageVtkMapper2D.cpp
+++ b/Core/Code/Rendering/mitkImageVtkMapper2D.cpp
@@ -1,1230 +1,1235 @@
-/*=========================================================================
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+/*===================================================================
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
+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.
+
+===================================================================*/
//MITK
#include <mitkAbstractTransformGeometry.h>
#include <mitkDataNode.h>
#include <mitkDataNodeFactory.h>
#include <mitkImageSliceSelector.h>
#include <mitkLevelWindowProperty.h>
#include <mitkLookupTableProperty.h>
#include <mitkPlaneGeometry.h>
#include <mitkProperties.h>
#include <mitkResliceMethodProperty.h>
#include <mitkTimeSlicedGeometry.h>
#include <mitkVtkResliceInterpolationProperty.h>
#include <mitkPixelType.h>
//#include <mitkTransferFunction.h>
#include <mitkTransferFunctionProperty.h>
#include "mitkImageStatisticsHolder.h"
//MITK Rendering
#include "mitkImageVtkMapper2D.h"
#include "vtkMitkThickSlicesFilter.h"
#include "vtkMitkApplyLevelWindowToRGBFilter.h"
//VTK
#include <vtkProperty.h>
#include <vtkTransform.h>
#include <vtkMatrix4x4.h>
#include <vtkLookupTable.h>
#include <vtkImageData.h>
#include <vtkPoints.h>
#include <vtkGeneralTransform.h>
#include <vtkImageReslice.h>
#include <vtkImageChangeInformation.h>
#include <vtkPlaneSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkTexture.h>
#include <vtkCellArray.h>
#include <vtkCamera.h>
#include <vtkColorTransferFunction.h>
//ITK
#include <itkRGBAPixel.h>
mitk::ImageVtkMapper2D::ImageVtkMapper2D()
{
}
mitk::ImageVtkMapper2D::~ImageVtkMapper2D()
{
//The 3D RW Mapper (Geometry2DDataVtkMapper3D) is listening to this event,
//in order to delete the images from the 3D RW.
this->InvokeEvent( itk::DeleteEvent() );
}
//set the two points defining the textured plane according to the dimension and spacing
void mitk::ImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer* renderer, vtkFloatingPointType planeBounds[6])
{
LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
float depth = this->CalculateLayerDepth(renderer);
//Set the origin to (xMin; yMin; depth) of the plane. This is necessary for obtaining the correct
//plane size in crosshair rotation and swivel mode.
localStorage->m_Plane->SetOrigin(planeBounds[0], planeBounds[2], depth);
//These two points define the axes of the plane in combination with the origin.
//Point 1 is the x-axis and point 2 the y-axis.
//Each plane is transformed according to the view (transversal, coronal and saggital) afterwards.
localStorage->m_Plane->SetPoint1(planeBounds[1], planeBounds[2], depth); //P1: (xMax, yMin, depth)
localStorage->m_Plane->SetPoint2(planeBounds[0], planeBounds[3], depth); //P2: (xMin, yMax, depth)
}
float mitk::ImageVtkMapper2D::CalculateLayerDepth(mitk::BaseRenderer* renderer)
{
//get the clipping range to check how deep into z direction we can render images
double maxRange = renderer->GetVtkRenderer()->GetActiveCamera()->GetClippingRange()[1];
//Due to a VTK bug, we cannot use the whole clipping range. /100 is empirically determined
float depth = -maxRange*0.01; // divide by 100
int layer = 0;
GetDataNode()->GetIntProperty( "layer", layer, renderer);
//add the layer property for each image to render images with a higher layer on top of the others
depth += layer*10; //*10: keep some room for each image (e.g. for QBalls in between)
if(depth > 0.0f) {
depth = 0.0f;
MITK_WARN << "Layer value exceeds clipping range. Set to minimum instead.";
}
return depth;
}
const mitk::Image* mitk::ImageVtkMapper2D::GetInput( void )
{
return static_cast< const mitk::Image * >( this->GetData() );
}
vtkProp* mitk::ImageVtkMapper2D::GetVtkProp(mitk::BaseRenderer* renderer)
{
//return the actor corresponding to the renderer
return m_LSH.GetLocalStorage(renderer)->m_Actor;
}
void mitk::ImageVtkMapper2D::MitkRenderOverlay(BaseRenderer* renderer)
{
if ( this->IsVisible(renderer)==false )
return;
if ( this->GetVtkProp(renderer)->GetVisibility() )
{
this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer());
}
}
void mitk::ImageVtkMapper2D::MitkRenderOpaqueGeometry(BaseRenderer* renderer)
{
if ( this->IsVisible( renderer )==false )
return;
if ( this->GetVtkProp(renderer)->GetVisibility() )
{
this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() );
}
}
void mitk::ImageVtkMapper2D::MitkRenderTranslucentGeometry(BaseRenderer* renderer)
{
if ( this->IsVisible(renderer)==false )
return;
if ( this->GetVtkProp(renderer)->GetVisibility() )
{
this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer());
}
}
void mitk::ImageVtkMapper2D::MitkRenderVolumetricGeometry(BaseRenderer* renderer)
{
if(IsVisible(renderer)==false)
return;
if ( GetVtkProp(renderer)->GetVisibility() )
{
this->GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer());
}
}
void mitk::ImageVtkMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer )
{
LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() );
if ( input == NULL )
{
return;
}
//check if there is a valid worldGeometry
const Geometry2D *worldGeometry = renderer->GetCurrentWorldGeometry2D();
if( ( worldGeometry == NULL ) || ( !worldGeometry->IsValid() ) || ( !worldGeometry->HasReferenceGeometry() ))
{
return;
}
// check if there is something to display
if ( !input->IsVolumeSet( this->GetTimestep() ) ) return;
input->Update();
vtkImageData* inputData = input->GetVtkImageData( this->GetTimestep() );
if ( inputData == NULL )
{
return;
}
// how big the area is in physical coordinates: widthInMM x heightInMM pixels
mitk::ScalarType widthInMM, heightInMM;
// take transform of input image into account
const TimeSlicedGeometry *inputTimeGeometry = input->GetTimeSlicedGeometry();
const Geometry3D* inputGeometry = inputTimeGeometry->GetGeometry3D( this->GetTimestep() );
// Bounds information for reslicing (only reuqired if reference geometry
// is present)
vtkFloatingPointType sliceBounds[6];
bool boundsInitialized = false;
for ( int i = 0; i < 6; ++i )
{
sliceBounds[i] = 0.0;
}
//Extent (in pixels) of the image
Vector2D extent;
// Do we have a simple PlaneGeometry?
// This is the "regular" case (e.g. slicing through an image axis-parallel or even oblique)
const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( worldGeometry );
if ( planeGeometry != NULL )
{
localStorage->m_Origin = planeGeometry->GetOrigin();
localStorage->m_Right = planeGeometry->GetAxisVector( 0 ); // right = Extent of Image in mm (worldspace)
localStorage->m_Bottom = planeGeometry->GetAxisVector( 1 );
localStorage->m_Normal = planeGeometry->GetNormal();
bool inPlaneResampleExtentByGeometry = false;
GetDataNode()->GetBoolProperty("in plane resample extent by geometry", inPlaneResampleExtentByGeometry, renderer);
if ( inPlaneResampleExtentByGeometry )
{
// Resampling grid corresponds to the current world geometry. This
// means that the spacing of the output 2D image depends on the
// currently selected world geometry, and *not* on the image itself.
extent[0] = worldGeometry->GetExtent( 0 );
extent[1] = worldGeometry->GetExtent( 1 );
}
else
{
// Resampling grid corresponds to the input geometry. This means that
// the spacing of the output 2D image is directly derived from the
// associated input image, regardless of the currently selected world
// geometry.
Vector3D rightInIndex, bottomInIndex;
inputGeometry->WorldToIndex( localStorage->m_Right, rightInIndex );
inputGeometry->WorldToIndex( localStorage->m_Bottom, bottomInIndex );
extent[0] = rightInIndex.GetNorm();
extent[1] = bottomInIndex.GetNorm();
}
// Get the extent of the current world geometry and calculate resampling
// spacing therefrom.
widthInMM = worldGeometry->GetExtentInMM( 0 );
heightInMM = worldGeometry->GetExtentInMM( 1 );
localStorage->m_mmPerPixel[0] = widthInMM / extent[0];
localStorage->m_mmPerPixel[1] = heightInMM / extent[1];
localStorage->m_Right.Normalize();
localStorage->m_Bottom.Normalize();
localStorage->m_Normal.Normalize();
//transform the origin to corner based coordinates, because VTK is corner based.
localStorage->m_Origin += localStorage->m_Right * ( localStorage->m_mmPerPixel[0] * 0.5 );
localStorage->m_Origin += localStorage->m_Bottom * ( localStorage->m_mmPerPixel[1] * 0.5 );
// Use inverse transform of the input geometry for reslicing the 3D image
localStorage->m_Reslicer->SetResliceTransform(
inputGeometry->GetVtkTransform()->GetLinearInverse() );
// Set background level to TRANSLUCENT (see Geometry2DDataVtkMapper3D)
localStorage->m_Reslicer->SetBackgroundLevel( -32768 );
// Calculate the actual bounds of the transformed plane clipped by the
// dataset bounding box; this is required for drawing the texture at the
// correct position during 3D mapping.
boundsInitialized = this->CalculateClippedPlaneBounds(
worldGeometry->GetReferenceGeometry(), planeGeometry, sliceBounds );
}
else
{
// Do we have an AbstractTransformGeometry?
// This is the case for AbstractTransformGeometry's (e.g. a thin-plate-spline transform)
const mitk::AbstractTransformGeometry* abstractGeometry =
dynamic_cast< const AbstractTransformGeometry * >(worldGeometry);
if(abstractGeometry != NULL)
{
extent[0] = abstractGeometry->GetParametricExtent(0);
extent[1] = abstractGeometry->GetParametricExtent(1);
widthInMM = abstractGeometry->GetParametricExtentInMM(0);
heightInMM = abstractGeometry->GetParametricExtentInMM(1);
localStorage->m_mmPerPixel[0] = widthInMM / extent[0];
localStorage->m_mmPerPixel[1] = heightInMM / extent[1];
localStorage->m_Origin = abstractGeometry->GetPlane()->GetOrigin();
localStorage->m_Right = abstractGeometry->GetPlane()->GetAxisVector(0);
localStorage->m_Right.Normalize();
localStorage->m_Bottom = abstractGeometry->GetPlane()->GetAxisVector(1);
localStorage->m_Bottom.Normalize();
localStorage->m_Normal = abstractGeometry->GetPlane()->GetNormal();
localStorage->m_Normal.Normalize();
// Use a combination of the InputGeometry *and* the possible non-rigid
// AbstractTransformGeometry for reslicing the 3D Image
vtkGeneralTransform *composedResliceTransform = vtkGeneralTransform::New();
composedResliceTransform->Identity();
composedResliceTransform->Concatenate(
inputGeometry->GetVtkTransform()->GetLinearInverse() );
composedResliceTransform->Concatenate(
abstractGeometry->GetVtkAbstractTransform()
);
localStorage->m_Reslicer->SetResliceTransform( composedResliceTransform );
composedResliceTransform->UnRegister( NULL ); // decrease RC
// Set background level to BLACK instead of translucent, to avoid
// boundary artifacts (see Geometry2DDataVtkMapper3D)
localStorage->m_Reslicer->SetBackgroundLevel( -1023 );
}
else
{
//no geometry => we can't reslice
return;
}
}
// Make sure that the image to display has a certain minimum size.
if ( (extent[0] <= 2) && (extent[1] <= 2) )
{
return;
}
//### begin set reslice interpolation
// Initialize the interpolation mode for resampling; switch to nearest
// neighbor if the input image is too small.
if ( (input->GetDimension() >= 3) && (input->GetDimension(2) > 1) )
{
VtkResliceInterpolationProperty *resliceInterpolationProperty;
this->GetDataNode()->GetProperty(
resliceInterpolationProperty, "reslice interpolation" );
int interpolationMode = VTK_RESLICE_NEAREST;
if ( resliceInterpolationProperty != NULL )
{
interpolationMode = resliceInterpolationProperty->GetInterpolation();
}
switch ( interpolationMode )
{
case VTK_RESLICE_NEAREST:
localStorage->m_Reslicer->SetInterpolationModeToNearestNeighbor();
break;
case VTK_RESLICE_LINEAR:
localStorage->m_Reslicer->SetInterpolationModeToLinear();
break;
case VTK_RESLICE_CUBIC:
localStorage->m_Reslicer->SetInterpolationModeToCubic();
break;
}
}
else
{
localStorage->m_Reslicer->SetInterpolationModeToNearestNeighbor();
}
//### end set reslice interpolation
//Thickslicing
int thickSlicesMode = 0;
int thickSlicesNum = 1;
// Thick slices parameters
if( inputData->GetNumberOfScalarComponents() == 1 ) // for now only single component are allowed
{
DataNode *dn=renderer->GetCurrentWorldGeometry2DNode();
if(dn)
{
ResliceMethodProperty *resliceMethodEnumProperty=0;
if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty )
thickSlicesMode = resliceMethodEnumProperty->GetValueAsId();
IntProperty *intProperty=0;
if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty )
{
thickSlicesNum = intProperty->GetValue();
if(thickSlicesNum < 1) thickSlicesNum=1;
if(thickSlicesNum > 10) thickSlicesNum=10;
}
}
else
{
MITK_WARN << "no associated widget plane data tree node found";
}
}
localStorage->m_UnitSpacingImageFilter->SetInput( inputData );
localStorage->m_Reslicer->SetInput( localStorage->m_UnitSpacingImageFilter->GetOutput() );
//number of pixels per mm in x- and y-direction of the resampled
Vector2D pixelsPerMM;
pixelsPerMM[0] = 1.0 / localStorage->m_mmPerPixel[0];
pixelsPerMM[1] = 1.0 / localStorage->m_mmPerPixel[1];
//calulate the originArray and the orientations for the reslice-filter
double originArray[3];
itk2vtk( localStorage->m_Origin, originArray );
localStorage->m_Reslicer->SetResliceAxesOrigin( originArray );
double cosines[9];
// direction of the X-axis of the sampled result
vnl2vtk( localStorage->m_Right.Get_vnl_vector(), cosines );
// direction of the Y-axis of the sampled result
vnl2vtk( localStorage->m_Bottom.Get_vnl_vector(), cosines + 3 );//fill next 3 elements
// normal of the plane
vnl2vtk( localStorage->m_Normal.Get_vnl_vector(), cosines + 6 );//fill the last 3 elements
localStorage->m_Reslicer->SetResliceAxesDirectionCosines( cosines );
int xMin, xMax, yMin, yMax;
if ( boundsInitialized )
{
// Calculate output extent (integer values)
xMin = static_cast< int >( sliceBounds[0] / localStorage->m_mmPerPixel[0] + 0.5 );
xMax = static_cast< int >( sliceBounds[1] / localStorage->m_mmPerPixel[0] + 0.5 );
yMin = static_cast< int >( sliceBounds[2] / localStorage->m_mmPerPixel[1] + 0.5 );
yMax = static_cast< int >( sliceBounds[3] / localStorage->m_mmPerPixel[1] + 0.5 );
}
else
{
// If no reference geometry is available, we also don't know about the
// maximum plane size;
xMin = yMin = 0;
xMax = static_cast< int >( extent[0]
- pixelsPerMM[0] + 0.5);
yMax = static_cast< int >( extent[1]
- pixelsPerMM[1] + 0.5);
}
// Disallow huge dimensions
if ( (xMax-xMin) * (yMax-yMin) > 4096*4096 )
{
return;
}
// Calculate dataset spacing in plane z direction (NOT spacing of current
// world geometry)
double dataZSpacing = 1.0;
Vector3D normInIndex;
inputGeometry->WorldToIndex( localStorage->m_Normal, normInIndex );
if(thickSlicesMode > 0)
{
dataZSpacing = 1.0 / normInIndex.GetNorm();
localStorage->m_Reslicer->SetOutputDimensionality( 3 );
localStorage->m_Reslicer->SetOutputExtent( xMin, xMax-1, yMin, yMax-1, -thickSlicesNum, 0+thickSlicesNum );
}
else
{
localStorage->m_Reslicer->SetOutputDimensionality( 2 );
localStorage->m_Reslicer->SetOutputExtent( xMin, xMax-1, yMin, yMax-1, 0, 0 );
}
localStorage->m_Reslicer->SetOutputOrigin( 0.0, 0.0, 0.0 );
localStorage->m_Reslicer->SetOutputSpacing( localStorage->m_mmPerPixel[0], localStorage->m_mmPerPixel[1], dataZSpacing );
// xMax and yMax are meant exclusive until now, whereas
// SetOutputExtent wants an inclusive bound. Thus, we need
// to subtract 1.
//Make sure the updateExtent is equal to the wholeExtent of vtkImageReslice,
//else the updateExtent is one step ahead of the wholeExtent and vtk errors
//are thrown.
localStorage->m_Reslicer->UpdateWholeExtent();
// Do the reslicing. Modified() is called to make sure that the reslicer is
// executed even though the input geometry information did not change; this
// is necessary when the input /em data, but not the /em geometry changes.
if(thickSlicesMode>0)
{
localStorage->m_TSFilter->SetThickSliceMode( thickSlicesMode-1 );
localStorage->m_TSFilter->SetInput( localStorage->m_Reslicer->GetOutput() );
localStorage->m_TSFilter->Modified();
localStorage->m_TSFilter->Update();
localStorage->m_ReslicedImage = localStorage->m_TSFilter->GetOutput();
}
else
{
localStorage->m_Reslicer->Modified();
localStorage->m_Reslicer->Update();
localStorage->m_ReslicedImage = localStorage->m_Reslicer->GetOutput();
}
if((localStorage->m_ReslicedImage == NULL) || (localStorage->m_ReslicedImage->GetDataDimension() < 1))
{
MITK_WARN << "reslicer returned empty image";
return;
}
//get the number of scalar components to distinguish between different image types
int numberOfComponents = localStorage->m_ReslicedImage->GetNumberOfScalarComponents();
//get the binary property
bool binary = false;
bool binaryOutline = false;
this->GetDataNode()->GetBoolProperty( "binary", binary, renderer );
if(binary) //binary image
{
this->GetDataNode()->GetBoolProperty( "outline binary", binaryOutline, renderer );
if(binaryOutline) //contour rendering
{
if ( this->GetInput()->GetPixelType().GetBpe() <= 8 )
{
//generate ontours/outlines
localStorage->m_OutlinePolyData = CreateOutlinePolyData(renderer);
float binaryOutlineWidth(1.0);
if (this->GetDataNode()->GetFloatProperty( "outline width", binaryOutlineWidth, renderer ))
{
localStorage->m_Actor->GetProperty()->SetLineWidth(binaryOutlineWidth);
}
}
else
{
binaryOutline = false;
this->ApplyLookuptable(renderer);
MITK_WARN << "Type of all binary images should be (un)signed char. Outline does not work on other pixel types!";
}
}
else //standard binary image
{
if(numberOfComponents != 1)
{
MITK_ERROR << "Rendering Error: Binary Images with more then 1 component are not supported!";
}
}
this->ApplyLookuptable(renderer);
//Interpret the values as binary values
localStorage->m_Texture->MapColorScalarsThroughLookupTableOn();
}
else if( numberOfComponents == 1 ) //gray images
{
//Interpret the values as gray values
localStorage->m_Texture->MapColorScalarsThroughLookupTableOn();
this->ApplyLookuptable(renderer);
}
else if ( (numberOfComponents == 3) || (numberOfComponents == 4) ) //RBG(A) images
{
//Interpret the RGB(A) images values correctly
localStorage->m_Texture->MapColorScalarsThroughLookupTableOff();
this->ApplyLookuptable(renderer);
this->ApplyRBGALevelWindow(renderer);
}
else
{
MITK_ERROR << "2D Reindering Error: Unknown number of components!!! Please report to rendering task force or check your data!";
}
this->ApplyColor( renderer );
this->ApplyOpacity( renderer );
this->TransformActor( renderer );
//connect mapper with the data
if(binary && binaryOutline) //connect the mapper with the polyData which contains the lines
{
//We need the contour for the binary oultine property as actor
localStorage->m_Mapper->SetInput(localStorage->m_OutlinePolyData);
localStorage->m_Actor->SetTexture(NULL); //no texture for contours
}
else
{ //Connect the mapper with the input texture. This is the standard case.
//setup the textured plane
this->GeneratePlane( renderer, sliceBounds );
//set the plane as input for the mapper
localStorage->m_Mapper->SetInputConnection(localStorage->m_Plane->GetOutputPort());
//set the texture for the actor
localStorage->m_Actor->SetTexture(localStorage->m_Texture);
}
// We have been modified => save this for next Update()
localStorage->m_LastUpdateTime.Modified();
}
void mitk::ImageVtkMapper2D::ApplyColor( mitk::BaseRenderer* renderer )
{
LocalStorage *localStorage = this->GetLocalStorage( renderer );
// check for interpolation properties
bool textureInterpolation = false;
GetDataNode()->GetBoolProperty( "texture interpolation", textureInterpolation, renderer );
//set the interpolation modus according to the property
localStorage->m_Texture->SetInterpolate(textureInterpolation);
bool useColor = true;
this->GetDataNode()->GetBoolProperty( "use color", useColor, renderer );
if( useColor )
{
float rgb[3]= { 1.0f, 1.0f, 1.0f };
// check for color prop and use it for rendering if it exists
// binary image hovering & binary image selection
bool hover = false;
bool selected = false;
GetDataNode()->GetBoolProperty("binaryimage.ishovering", hover, renderer);
GetDataNode()->GetBoolProperty("selected", selected, renderer);
if(hover && !selected)
{
mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty
("binaryimage.hoveringcolor", renderer));
if(colorprop.IsNotNull())
{
memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
}
else
{
GetColor( rgb, renderer );
}
}
if(selected)
{
mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty
("binaryimage.selectedcolor", renderer));
if(colorprop.IsNotNull()) {
memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
}
else
{
GetColor( rgb, renderer );
}
}
if(!hover && !selected)
{
GetColor( rgb, renderer );
}
double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK
localStorage->m_Actor->GetProperty()->SetColor(rgbConv);
}
else
{
//If the user defines a lut, we dont want to use the color and take white instead.
localStorage->m_Actor->GetProperty()->SetColor(1.0, 1.0, 1.0);
}
}
void mitk::ImageVtkMapper2D::ApplyOpacity( mitk::BaseRenderer* renderer )
{
LocalStorage* localStorage = this->GetLocalStorage( renderer );
float opacity = 1.0f;
// check for opacity prop and use it for rendering if it exists
GetOpacity( opacity, renderer );
//set the opacity according to the properties
localStorage->m_Actor->GetProperty()->SetOpacity(opacity);
}
void mitk::ImageVtkMapper2D::ApplyLookuptable( mitk::BaseRenderer* renderer )
{
bool binary = false;
bool CTFcanBeApplied = false;
this->GetDataNode()->GetBoolProperty( "binary", binary, renderer );
LocalStorage* localStorage = this->GetLocalStorage(renderer);
//default lookuptable
localStorage->m_Texture->SetLookupTable( localStorage->m_LookupTable );
if(binary)
{
//default lookuptable for binary images
localStorage->m_Texture->GetLookupTable()->SetRange(0.0, 1.0);
}
else
{
bool useColor = true;
this->GetDataNode()->GetBoolProperty( "use color", useColor, renderer );
if((!useColor))
{
//BEGIN PROPERTY user-defined lut
//currently we do not allow a lookuptable if it is a binary image
// If lookup table use is requested...
mitk::LookupTableProperty::Pointer LookupTableProp;
LookupTableProp = dynamic_cast<mitk::LookupTableProperty*>
(this->GetDataNode()->GetProperty("LookupTable"));
//...check if there is a lookuptable provided by the user
if ( LookupTableProp.IsNotNull() )
{
// If lookup table use is requested and supplied by the user:
// only update the lut, when the properties have changed...
if( LookupTableProp->GetLookupTable()->GetMTime()
<= this->GetDataNode()->GetPropertyList()->GetMTime() )
{
LookupTableProp->GetLookupTable()->ChangeOpacityForAll( LookupTableProp->GetLookupTable()->GetVtkLookupTable()->GetAlpha()*localStorage->m_Actor->GetProperty()->GetOpacity() );
LookupTableProp->GetLookupTable()->ChangeOpacity(0, 0.0);
}
//we use the user-defined lookuptable
localStorage->m_Texture->SetLookupTable( LookupTableProp->GetLookupTable()->GetVtkLookupTable() );
}
else
{
CTFcanBeApplied = true;
}
}//END PROPERTY user-defined lut
LevelWindow levelWindow;
this->GetLevelWindow( levelWindow, renderer );
//set up the lookuptable with the level window range
localStorage->m_Texture->GetLookupTable()->SetRange( levelWindow.GetLowerWindowBound(), levelWindow.GetUpperWindowBound() );
}
//the color function can be applied if the user does not want to use color
//and does not provide a lookuptable
if(CTFcanBeApplied)
{
ApplyColorTransferFunction(renderer);
}
localStorage->m_Texture->SetInput( localStorage->m_ReslicedImage );
}
void mitk::ImageVtkMapper2D::ApplyColorTransferFunction(mitk::BaseRenderer* renderer)
{
mitk::TransferFunctionProperty::Pointer transferFunctionProperty =
dynamic_cast<mitk::TransferFunctionProperty*>(this->GetDataNode()->GetProperty("Image Rendering.Transfer Function",renderer ));
LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
if(transferFunctionProperty.IsNotNull())
{
localStorage->m_Texture->SetLookupTable(transferFunctionProperty->GetValue()->GetColorTransferFunction());
}
else
{
MITK_WARN << "Neither a lookuptable nor a transfer function is set and use color is off.";
}
}
bool mitk::ImageVtkMapper2D::LineIntersectZero( vtkPoints *points, int p1, int p2,
vtkFloatingPointType *bounds )
{
vtkFloatingPointType point1[3];
vtkFloatingPointType point2[3];
points->GetPoint( p1, point1 );
points->GetPoint( p2, point2 );
if ( (point1[2] * point2[2] <= 0.0) && (point1[2] != point2[2]) )
{
double x, y;
x = ( point1[0] * point2[2] - point1[2] * point2[0] ) / ( point2[2] - point1[2] );
y = ( point1[1] * point2[2] - point1[2] * point2[1] ) / ( point2[2] - point1[2] );
if ( x < bounds[0] ) { bounds[0] = x; }
if ( x > bounds[1] ) { bounds[1] = x; }
if ( y < bounds[2] ) { bounds[2] = y; }
if ( y > bounds[3] ) { bounds[3] = y; }
bounds[4] = bounds[5] = 0.0;
return true;
}
return false;
}
bool mitk::ImageVtkMapper2D::CalculateClippedPlaneBounds( const Geometry3D *boundingGeometry,
const PlaneGeometry *planeGeometry, vtkFloatingPointType *bounds )
{
// Clip the plane with the bounding geometry. To do so, the corner points
// of the bounding box are transformed by the inverse transformation
// matrix, and the transformed bounding box edges derived therefrom are
// clipped with the plane z=0. The resulting min/max values are taken as
// bounds for the image reslicer.
const mitk::BoundingBox *boundingBox = boundingGeometry->GetBoundingBox();
mitk::BoundingBox::PointType bbMin = boundingBox->GetMinimum();
mitk::BoundingBox::PointType bbMax = boundingBox->GetMaximum();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
if(boundingGeometry->GetImageGeometry())
{
points->InsertPoint( 0, bbMin[0]-0.5, bbMin[1]-0.5, bbMin[2]-0.5 );
points->InsertPoint( 1, bbMin[0]-0.5, bbMin[1]-0.5, bbMax[2]-0.5 );
points->InsertPoint( 2, bbMin[0]-0.5, bbMax[1]-0.5, bbMax[2]-0.5 );
points->InsertPoint( 3, bbMin[0]-0.5, bbMax[1]-0.5, bbMin[2]-0.5 );
points->InsertPoint( 4, bbMax[0]-0.5, bbMin[1]-0.5, bbMin[2]-0.5 );
points->InsertPoint( 5, bbMax[0]-0.5, bbMin[1]-0.5, bbMax[2]-0.5 );
points->InsertPoint( 6, bbMax[0]-0.5, bbMax[1]-0.5, bbMax[2]-0.5 );
points->InsertPoint( 7, bbMax[0]-0.5, bbMax[1]-0.5, bbMin[2]-0.5 );
}
else
{
points->InsertPoint( 0, bbMin[0], bbMin[1], bbMin[2] );
points->InsertPoint( 1, bbMin[0], bbMin[1], bbMax[2] );
points->InsertPoint( 2, bbMin[0], bbMax[1], bbMax[2] );
points->InsertPoint( 3, bbMin[0], bbMax[1], bbMin[2] );
points->InsertPoint( 4, bbMax[0], bbMin[1], bbMin[2] );
points->InsertPoint( 5, bbMax[0], bbMin[1], bbMax[2] );
points->InsertPoint( 6, bbMax[0], bbMax[1], bbMax[2] );
points->InsertPoint( 7, bbMax[0], bbMax[1], bbMin[2] );
}
vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
transform->Identity();
transform->Concatenate( planeGeometry->GetVtkTransform()->GetLinearInverse() );
transform->Concatenate( boundingGeometry->GetVtkTransform() );
transform->TransformPoints( points, newPoints );
bounds[0] = bounds[2] = 10000000.0;
bounds[1] = bounds[3] = -10000000.0;
bounds[4] = bounds[5] = 0.0;
this->LineIntersectZero( newPoints, 0, 1, bounds );
this->LineIntersectZero( newPoints, 1, 2, bounds );
this->LineIntersectZero( newPoints, 2, 3, bounds );
this->LineIntersectZero( newPoints, 3, 0, bounds );
this->LineIntersectZero( newPoints, 0, 4, bounds );
this->LineIntersectZero( newPoints, 1, 5, bounds );
this->LineIntersectZero( newPoints, 2, 6, bounds );
this->LineIntersectZero( newPoints, 3, 7, bounds );
this->LineIntersectZero( newPoints, 4, 5, bounds );
this->LineIntersectZero( newPoints, 5, 6, bounds );
this->LineIntersectZero( newPoints, 6, 7, bounds );
this->LineIntersectZero( newPoints, 7, 4, bounds );
if ( (bounds[0] > 9999999.0) || (bounds[2] > 9999999.0)
|| (bounds[1] < -9999999.0) || (bounds[3] < -9999999.0) )
{
return false;
}
else
{
// The resulting bounds must be adjusted by the plane spacing, since we
// we have so far dealt with index coordinates
const float *planeSpacing = planeGeometry->GetFloatSpacing();
bounds[0] *= planeSpacing[0];
bounds[1] *= planeSpacing[0];
bounds[2] *= planeSpacing[1];
bounds[3] *= planeSpacing[1];
bounds[4] *= planeSpacing[2];
bounds[5] *= planeSpacing[2];
return true;
}
}
void mitk::ImageVtkMapper2D::ApplyRBGALevelWindow( mitk::BaseRenderer* renderer )
{
LocalStorage* localStorage = this->GetLocalStorage( renderer );
//pass the LuT to the RBG filter
localStorage->m_LevelWindowToRGBFilterObject->SetLookupTable(localStorage->m_Texture->GetLookupTable());
mitk::LevelWindow opacLevelWindow;
if( this->GetLevelWindow( opacLevelWindow, renderer, "opaclevelwindow" ) )
{//pass the opaque level window to the filter
localStorage->m_LevelWindowToRGBFilterObject->SetMinOpacity(opacLevelWindow.GetLowerWindowBound());
localStorage->m_LevelWindowToRGBFilterObject->SetMaxOpacity(opacLevelWindow.GetUpperWindowBound());
}
else
{//no opaque level window
localStorage->m_LevelWindowToRGBFilterObject->SetMinOpacity(0.0);
localStorage->m_LevelWindowToRGBFilterObject->SetMaxOpacity(255.0);
}
localStorage->m_LevelWindowToRGBFilterObject->SetInput(localStorage->m_ReslicedImage);
//connect the texture with the output of the RGB filter
localStorage->m_Texture->SetInputConnection(localStorage->m_LevelWindowToRGBFilterObject->GetOutputPort());
}
void mitk::ImageVtkMapper2D::Update(mitk::BaseRenderer* renderer)
{
if ( !this->IsVisible( renderer ) )
{
return;
}
mitk::Image* data = const_cast<mitk::Image *>( this->GetInput() );
if ( data == NULL )
{
return;
}
// Calculate time step of the input data for the specified renderer (integer value)
this->CalculateTimeStep( renderer );
// Check if time step is valid
const TimeSlicedGeometry *dataTimeGeometry = data->GetTimeSlicedGeometry();
if ( ( dataTimeGeometry == NULL )
|| ( dataTimeGeometry->GetTimeSteps() == 0 )
|| ( !dataTimeGeometry->IsValidTime( this->GetTimestep() ) ) )
{
return;
}
const DataNode *node = this->GetDataNode();
data->UpdateOutputInformation();
LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
//check if something important has changed and we need to rerender
if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified?
|| (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified?
|| (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified?
|| (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime())
|| (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified?
|| (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) )
{
this->GenerateDataForRenderer( renderer );
}
// since we have checked that nothing important has changed, we can set
// m_LastUpdateTime to the current time
localStorage->m_LastUpdateTime.Modified();
}
void mitk::ImageVtkMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(node->GetData());
// Properties common for both images and segmentations
node->AddProperty( "use color", mitk::BoolProperty::New( true ), renderer, overwrite );
node->AddProperty( "depthOffset", mitk::FloatProperty::New( 0.0 ), renderer, overwrite );
node->AddProperty( "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite );
node->AddProperty( "outline width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite );
if(image->IsRotated()) node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New(VTK_RESLICE_CUBIC) );
else node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() );
node->AddProperty( "texture interpolation", mitk::BoolProperty::New( mitk::DataNodeFactory::m_TextureInterpolationActive ) ); // set to user configurable default value (see global options)
node->AddProperty( "in plane resample extent by geometry", mitk::BoolProperty::New( false ) );
node->AddProperty( "bounding box", mitk::BoolProperty::New( false ) );
std::string modality;
if ( node->GetStringProperty( "dicom.series.Modality", modality ) )
{
// modality provided by DICOM or other reader
if ( modality == "PT") // NOT a typo, PT is the abbreviation for PET used in DICOM
{
node->SetProperty( "use color", mitk::BoolProperty::New( false ), renderer );
node->SetProperty( "opacity", mitk::FloatProperty::New( 0.5 ), renderer );
}
}
bool isBinaryImage(false);
if ( ! node->GetBoolProperty("binary", isBinaryImage) )
{
// ok, property is not set, use heuristic to determine if this
// is a binary image
mitk::Image::Pointer centralSliceImage;
ScalarType minValue = 0.0;
ScalarType maxValue = 0.0;
ScalarType min2ndValue = 0.0;
ScalarType max2ndValue = 0.0;
mitk::ImageSliceSelector::Pointer sliceSelector = mitk::ImageSliceSelector::New();
sliceSelector->SetInput(image);
sliceSelector->SetSliceNr(image->GetDimension(2)/2);
sliceSelector->SetTimeNr(image->GetDimension(3)/2);
sliceSelector->SetChannelNr(image->GetDimension(4)/2);
sliceSelector->Update();
centralSliceImage = sliceSelector->GetOutput();
if ( centralSliceImage.IsNotNull() && centralSliceImage->IsInitialized() )
{
minValue = centralSliceImage->GetStatistics()->GetScalarValueMin();
maxValue = centralSliceImage->GetStatistics()->GetScalarValueMax();
min2ndValue = centralSliceImage->GetStatistics()->GetScalarValue2ndMin();
max2ndValue = centralSliceImage->GetStatistics()->GetScalarValue2ndMax();
}
if ( minValue == maxValue )
{
// centralSlice is strange, lets look at all data
minValue = image->GetStatistics()->GetScalarValueMin();
maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute();
min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute();
max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute();
}
isBinaryImage = ( maxValue == min2ndValue && minValue == max2ndValue );
}
// some more properties specific for a binary...
if (isBinaryImage)
{
node->AddProperty( "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite );
node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binaryimage.selectedcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binaryimage.selectedannotationcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binaryimage.hoveringcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binaryimage.hoveringannotationcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
node->AddProperty( "binary", mitk::BoolProperty::New( true ), renderer, overwrite );
node->AddProperty("layer", mitk::IntProperty::New(10), renderer, overwrite);
}
else //...or image type object
{
node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite );
node->AddProperty( "color", ColorProperty::New(1.0,1.0,1.0), renderer, overwrite );
node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite );
node->AddProperty("layer", mitk::IntProperty::New(0), renderer, overwrite);
}
if(image.IsNotNull() && image->IsInitialized())
{
if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL))
{
/* initialize level/window from DICOM tags */
std::string sLevel;
std::string sWindow;
if ( node->GetStringProperty( "dicom.voilut.WindowCenter", sLevel )
&& node->GetStringProperty( "dicom.voilut.WindowWidth", sWindow ) )
{
float level = atof( sLevel.c_str() );
float window = atof( sWindow.c_str() );
mitk::LevelWindow contrast;
std::string sSmallestPixelValueInSeries;
std::string sLargestPixelValueInSeries;
if ( node->GetStringProperty( "dicom.series.SmallestPixelValueInSeries", sSmallestPixelValueInSeries )
&& node->GetStringProperty( "dicom.series.LargestPixelValueInSeries", sLargestPixelValueInSeries ) )
{
float smallestPixelValueInSeries = atof( sSmallestPixelValueInSeries.c_str() );
float largestPixelValueInSeries = atof( sLargestPixelValueInSeries.c_str() );
contrast.SetRangeMinMax( smallestPixelValueInSeries-1, largestPixelValueInSeries+1 ); // why not a little buffer?
// might remedy some l/w widget challenges
}
else
{
contrast.SetAuto( static_cast<mitk::Image*>(node->GetData()), false, true ); // we need this as a fallback
}
contrast.SetLevelWindow( level, window);
node->SetProperty( "levelwindow", LevelWindowProperty::New( contrast ), renderer );
}
}
if(((overwrite) || (node->GetProperty("opaclevelwindow", renderer)==NULL))
&& image->GetPixelType().GetPixelTypeId() == typeid(itk::RGBAPixel<unsigned char>))
{
mitk::LevelWindow opaclevwin;
opaclevwin.SetRangeMinMax(0,255);
opaclevwin.SetWindowBounds(0,255);
mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(opaclevwin);
node->SetProperty( "opaclevelwindow", prop, renderer );
}
if((overwrite) || (node->GetProperty("LookupTable", renderer)==NULL))
{
// add a default rainbow lookup table for color mapping
mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New();
vtkLookupTable* vtkLut = mitkLut->GetVtkLookupTable();
vtkLut->SetHueRange(0.6667, 0.0);
vtkLut->SetTableRange(0.0, 20.0);
vtkLut->Build();
mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New();
mitkLutProp->SetLookupTable(mitkLut);
node->SetProperty( "LookupTable", mitkLutProp );
}
}
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
mitk::ImageVtkMapper2D::LocalStorage* mitk::ImageVtkMapper2D::GetLocalStorage(mitk::BaseRenderer* renderer)
{
return m_LSH.GetLocalStorage(renderer);
}
vtkSmartPointer<vtkPolyData> mitk::ImageVtkMapper2D::CreateOutlinePolyData(mitk::BaseRenderer* renderer ){
LocalStorage* localStorage = this->GetLocalStorage(renderer);
//get the min and max index values of each direction
int* extent = localStorage->m_ReslicedImage->GetExtent();
int xMin = extent[0];
int xMax = extent[1];
int yMin = extent[2];
int yMax = extent[3];
int* dims = localStorage->m_ReslicedImage->GetDimensions(); //dimensions of the image
int line = dims[0]; //how many pixels per line?
int x = xMin; //pixel index x
int y = yMin; //pixel index y
char* currentPixel;
//get the depth for each contour
float depth = CalculateLayerDepth(renderer);
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); //the points to draw
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); //the lines to connect the points
while (y <= yMax)
{
currentPixel = static_cast<char*>(localStorage->m_ReslicedImage->GetScalarPointer(x, y, 0));
//if the current pixel value is set to something
if ((currentPixel) && (*currentPixel != 0))
{
//check in which direction a line is necessary
//a line is added if the neighbor of the current pixel has the value 0
//and if the pixel is located at the edge of the image
//if vvvvv not the first line vvvvv
if (y > yMin && *(currentPixel-line) == 0)
{ //x direction - bottom edge of the pixel
//add the 2 points
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
//add the line between both points
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv not the last line vvvvv
if (y < yMax && *(currentPixel+line) == 0)
{ //x direction - top edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv not the first pixel vvvvv
if ( (x > xMin || y > yMin) && *(currentPixel-1) == 0)
{ //y direction - left edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv not the last pixel vvvvv
if ( (y < yMax || (x < xMax) ) && *(currentPixel+1) == 0)
{ //y direction - right edge of the pixel
vtkIdType p1 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
/* now consider pixels at the edge of the image */
//if vvvvv left edge of image vvvvv
if (x == xMin)
{ //draw left edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv right edge of image vvvvv
if (x == xMax)
{ //draw right edge of the pixel
vtkIdType p1 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv bottom edge of image vvvvv
if (y == yMin)
{ //draw bottom edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
//if vvvvv top edge of image vvvvv
if (y == yMax)
{ //draw top edge of the pixel
vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
lines->InsertNextCell(2);
lines->InsertCellPoint(p1);
lines->InsertCellPoint(p2);
}
}//end if currentpixel is set
x++;
if (x > xMax)
{ //reached end of line
x = xMin;
y++;
}
}//end of while
// Create a polydata to store everything in
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
// Add the points to the dataset
polyData->SetPoints(points);
// Add the lines to the dataset
polyData->SetLines(lines);
return polyData;
}
void mitk::ImageVtkMapper2D::TransformActor(mitk::BaseRenderer* renderer)
{
LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
//get the transformation matrix of the reslicer in order to render the slice as transversal, coronal or saggital
vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
vtkSmartPointer<vtkMatrix4x4> matrix = localStorage->m_Reslicer->GetResliceAxes();
trans->SetMatrix(matrix);
//transform the plane/contour (the actual actor) to the corresponding view (transversal, coronal or saggital)
localStorage->m_Actor->SetUserTransform(trans);
//transform the origin to center based coordinates, because MITK is center based.
localStorage->m_Actor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0);
}
mitk::ImageVtkMapper2D::LocalStorage::LocalStorage()
{
//Do as much actions as possible in here to avoid double executions.
m_Plane = vtkSmartPointer<vtkPlaneSource>::New();
m_Texture = vtkSmartPointer<vtkTexture>::New();
m_LookupTable = vtkSmartPointer<vtkLookupTable>::New();
m_Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
m_Actor = vtkSmartPointer<vtkActor>::New();
m_Reslicer = vtkSmartPointer<vtkImageReslice>::New();
m_TSFilter = vtkSmartPointer<vtkMitkThickSlicesFilter>::New();
m_UnitSpacingImageFilter = vtkSmartPointer<vtkImageChangeInformation>::New();
m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();
m_ReslicedImage = vtkSmartPointer<vtkImageData>::New();
//the following actions are always the same and thus can be performed
//in the constructor for each image (i.e. the image-corresponding local storage)
m_TSFilter->ReleaseDataFlagOn();
m_Reslicer->ReleaseDataFlagOn();
m_UnitSpacingImageFilter->SetOutputSpacing( 1.0, 1.0, 1.0 );
//built a default lookuptable
m_LookupTable->SetRampToLinear();
m_LookupTable->SetSaturationRange( 0.0, 0.0 );
m_LookupTable->SetHueRange( 0.0, 0.0 );
m_LookupTable->SetValueRange( 0.0, 1.0 );
m_LookupTable->Build();
//map all black values to transparent
m_LookupTable->SetTableValue(0, 0.0, 0.0, 0.0, 0.0);
//do not repeat the texture (the image)
m_Texture->RepeatOff();
//set the mapper for the actor
m_Actor->SetMapper(m_Mapper);
//filter for RGB(A) images
m_LevelWindowToRGBFilterObject = new vtkMitkApplyLevelWindowToRGBFilter();
}
diff --git a/Core/Code/Rendering/mitkImageVtkMapper2D.h b/Core/Code/Rendering/mitkImageVtkMapper2D.h
index ded80f35b7..2c10a08a21 100644
--- a/Core/Code/Rendering/mitkImageVtkMapper2D.h
+++ b/Core/Code/Rendering/mitkImageVtkMapper2D.h
@@ -1,277 +1,282 @@
-/*=========================================================================
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+/*===================================================================
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
+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 MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E
#define MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E
//MITK
#include <mitkCommon.h>
//MITK Rendering
#include "mitkBaseRenderer.h"
#include "mitkVtkMapper2D.h"
//VTK
#include <vtkSmartPointer.h>
class vtkActor;
class vtkPolyDataMapper;
class vtkPlaneSource;
class vtkImageData;
class vtkLookupTable;
class vtkImageReslice;
class vtkImageChangeInformation;
class vtkPoints;
class vtkMitkThickSlicesFilter;
class vtkPolyData;
class vtkMitkApplyLevelWindowToRGBFilter;
namespace mitk {
/** \brief Mapper to resample and display 2D slices of a 3D image.
*
* The following image gives a brief overview of the mapping and the involved parts.
*
* \image html imageVtkMapper2Darchitecture.png
*
* First, the image is resliced by means of vtkImageReslice. The volume image
* serves as input to the mapper in addition to spatial placement of the slice and a few other
* properties such as thick slices. This code was already present in the old version
* (mitkImageMapperGL2D).
*
* Next, the obtained slice (m_ReslicedImage) is used to create a texture
* (m_Texture) and a plane onto which the texture is rendered (m_Plane). For
* mapping purposes, a vtkPolyDataMapper (m_Mapper) is utilized. Orthographic
* projection is applied to create the effect of a 2D image. The mapper and the
* texture are assigned to the actor (m_Actor) which is passed to the VTK rendering
* pipeline via the method GetVtkProp().
*
* In order to transform the textured plane to the correct position in space, the
* same transformation as used for reslicing is applied to both the camera and the
* vtkActor. All important steps are explained in more detail below. The resulting
* 2D image (by reslicing the underlying 3D input image appropriately) can either
* be directly rendered in a 2D view or just be calculated to be used later by another
* rendering entity, e.g. in texture mapping in a 3D view.
*
* Properties that can be set for images and influence the imageMapper2D are:
*
* - \b "opacity": (FloatProperty) Opacity of the image
* - \b "color": (ColorProperty) Color of the image
* - \b "use color": (BoolProperty) Use the color of the image or not
* - \b "binary": (BoolProperty) is the image a binary image or not
* - \b "outline binary": (BoolProperty) show outline of the image or not
* - \b "texture interpolation": (BoolProperty) texture interpolation of the image
* - \b "reslice interpolation": (VtkResliceInterpolationProperty) reslice interpolation of the image
* - \b "in plane resample extent by geometry": (BoolProperty) Do it or not
* - \b "bounding box": (BoolProperty) Is the Bounding Box of the image shown or not
* - \b "layer": (IntProperty) Layer of the image
* - \b "volume annotation color": (ColorProperty) color of the volume annotation, TODO has to be reimplemented
* - \b "volume annotation unit": (StringProperty) annotation unit as string (does not implicit convert the unit!)
unit is ml or cm3, TODO has to be reimplemented
* The default properties are:
* - \b "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite )
* - \b "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite )
* - \b "use color", mitk::BoolProperty::New( true ), renderer, overwrite )
* - \b "binary", mitk::BoolProperty::New( true ), renderer, overwrite )
* - \b "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite )
* - \b "texture interpolation", mitk::BoolProperty::New( mitk::DataNodeFactory::m_TextureInterpolationActive ) )
* - \b "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() )
* - \b "in plane resample extent by geometry", mitk::BoolProperty::New( false ) )
* - \b "bounding box", mitk::BoolProperty::New( false ) )
* - \b "layer", mitk::IntProperty::New(10), renderer, overwrite)
* If the modality-property is set for an image, the mapper uses modality-specific default properties,
* e.g. color maps, if they are defined.
* \ingroup Mapper
*/
class MITK_CORE_EXPORT ImageVtkMapper2D : public VtkMapper2D
{
public:
/** Standard class typedefs. */
mitkClassMacro( ImageVtkMapper2D,VtkMapper2D );
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** \brief Get the Image to map */
const mitk::Image *GetInput(void);
/** \brief Checks whether this mapper needs to update itself and generate
* data. */
virtual void Update(mitk::BaseRenderer * renderer);
//### methods of MITK-VTK rendering pipeline
virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer);
virtual void MitkRenderOverlay(BaseRenderer* renderer);
virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer);
virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer);
virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer);
//### end of methods of MITK-VTK rendering pipeline
/** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */
/**
* To render transveral, coronal, and sagittal, the mapper is called three times.
* For performance reasons, the corresponding data for each view is saved in the
* internal helper class LocalStorage. This allows rendering n views with just
* 1 mitkMapper using n vtkMapper.
* */
class MITK_CORE_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage
{
public:
/** \brief Actor of a 2D render window. */
vtkSmartPointer<vtkActor> m_Actor;
/** \brief Mapper of a 2D render window. */
vtkSmartPointer<vtkPolyDataMapper> m_Mapper;
/** \brief Current slice of a 2D render window. */
vtkSmartPointer<vtkImageData> m_ReslicedImage;
/** \brief Plane on which the slice is rendered as texture. */
vtkSmartPointer<vtkPlaneSource> m_Plane;
/** \brief The texture which is used to render the current slice. */
vtkSmartPointer<vtkTexture> m_Texture;
/** \brief The lookuptable for colors and level window */
vtkSmartPointer<vtkLookupTable> m_LookupTable;
/** \brief The actual reslicer (one per renderer) */
vtkSmartPointer<vtkImageReslice> m_Reslicer;
/** \brief Thickslices post filtering. */
vtkSmartPointer<vtkMitkThickSlicesFilter> m_TSFilter;
/** \brief Using unit spacing for resampling makes life easier TODO improve docu ...*/
vtkSmartPointer<vtkImageChangeInformation> m_UnitSpacingImageFilter;
/** \brief PolyData object containg all lines/points needed for outlining the contour.
This container is used to save a computed contour for the next rendering execution.
For instance, if you zoom or pann, there is no need to recompute the contour. */
vtkSmartPointer<vtkPolyData> m_OutlinePolyData;
/** \brief Timestamp of last update of stored data. */
itk::TimeStamp m_LastUpdateTime;
/** \brief Origin of the 2D geometry. */
mitk::Point3D m_Origin;
/** \brief Bottom end point of the y-axis of the 2D geometry. */
mitk::Vector3D m_Bottom;
/** \brief Right end point of the x-axis of the 2D geometry. */
mitk::Vector3D m_Right;
/** \brief Normal of the 2D geometry. */
mitk::Vector3D m_Normal;
/** \brief mmPerPixel relation between pixel and mm. (World spacing).*/
mitk::ScalarType m_mmPerPixel[2];
/** \brief This filter is used to apply the level window to RBG(A) images. */
vtkMitkApplyLevelWindowToRGBFilter* m_LevelWindowToRGBFilterObject;
/** \brief Default constructor of the local storage. */
LocalStorage();
/** \brief Default deconstructor of the local storage. */
~LocalStorage()
{
}
};
/** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */
mitk::Mapper::LocalStorageHandler<LocalStorage> m_LSH;
/** \brief Get the LocalStorage corresponding to the current renderer. */
LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer);
/** \brief Set the default properties for general image rendering. */
static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false);
protected:
/** \brief Transforms the actor to the actual position in 3D.
* \param renderer The current renderer corresponding to the render window.
*/
void TransformActor(mitk::BaseRenderer* renderer);
/** \brief Generates a plane according to the size of the resliced image in milimeters.
*
* \image html texturedPlane.png
*
* In VTK a vtkPlaneSource is defined through three points. The origin and two
* points defining the axes of the plane (see VTK documentation). The origin is
* set to (xMin; yMin; Z), where xMin and yMin are the minimal bounds of the
* resliced image in space. Z is relevant for blending and the layer property.
* The center of the plane (C) is also the center of the view plane (cf. the image above).
*
* \note For the standard MITK view with three 2D render windows showing three
* different slices, three such planes are generated. All these planes are generated
* in the XY-plane (even if they depict a YZ-slice of the volume).
*
*/
void GeneratePlane(mitk::BaseRenderer* renderer, vtkFloatingPointType planeBounds[6]);
/** \brief Generates a vtkPolyData object containing the outline of a given binary slice.
\param binarySlice - The binary image slice. (Volumes are not supported.)
\param mmPerPixel - Spacing of the binary image slice. Hence it's 2D, only in x/y-direction.
\note This code has been taken from the deprecated library iil.
*/
vtkSmartPointer<vtkPolyData> CreateOutlinePolyData(mitk::BaseRenderer* renderer);
/** Default constructor */
ImageVtkMapper2D();
/** Default deconstructor */
virtual ~ImageVtkMapper2D();
/** \brief Does the actual resampling, without rendering the image yet.
* All the data is generated inside this method. The vtkProp (or Actor)
* is filled with content (i.e. the resliced image).
*
* After generation, a 4x4 transformation matrix(t) of the current slice is obtained
* from the vtkResliceImage object via GetReslicesAxis(). This matrix is
* applied to each textured plane (actor->SetUserTransform(t)) to transform everything
* to the actual 3D position (cf. the following image).
*
* \image html cameraPositioning3D.png
*
*/
virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer);
/** \brief Internal helper method for intersection testing used only in CalculateClippedPlaneBounds() */
bool LineIntersectZero( vtkPoints *points, int p1, int p2,
vtkFloatingPointType *bounds );
/** \brief Calculate the bounding box of the resliced image. This is necessary for
arbitrarily rotated planes in an image volume. A rotated plane (e.g. in swivel mode)
will have a new bounding box, which needs to be calculated. */
bool CalculateClippedPlaneBounds( const Geometry3D *boundingGeometry,
const PlaneGeometry *planeGeometry, vtkFloatingPointType *bounds );
/** \brief This method uses the vtkCamera clipping range and the layer property
* to calcualte the depth of the object (e.g. image or contour). The depth is used
* to keep the correct order for the final VTK rendering.*/
float CalculateLayerDepth(mitk::BaseRenderer* renderer);
/** \brief This method applies a level window on RBG(A) images.
* It should only be called for internally for RGB(A) images. */
void ApplyRBGALevelWindow( mitk::BaseRenderer* renderer );
/** \brief This method applies (or modifies) the lookuptable for all types of images. */
void ApplyLookuptable( mitk::BaseRenderer* renderer );
/** \brief This method applies a color transfer function, if no LookuptableProperty is set.
Internally, a vtkColorTransferFunction is used. This is usefull for coloring continous
images (e.g. float) */
void ApplyColorTransferFunction(mitk::BaseRenderer* renderer);
/** \brief Set the color of the image/polydata */
void ApplyColor( mitk::BaseRenderer* renderer );
/** \brief Set the opacity of the actor. */
void ApplyOpacity( mitk::BaseRenderer* renderer );
};
} // namespace mitk
#endif /* MITKIMAGEVTKMAPPER2D_H_HEADER_INCLUDED_C10E906E */
diff --git a/Core/Code/Rendering/mitkManufacturerLogo.cpp b/Core/Code/Rendering/mitkManufacturerLogo.cpp
index 9810b79da0..d2fcd3b8df 100644
--- a/Core/Code/Rendering/mitkManufacturerLogo.cpp
+++ b/Core/Code/Rendering/mitkManufacturerLogo.cpp
@@ -1,381 +1,380 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkManufacturerLogo.h"
#include "mitkVtkLayerController.h"
#include <mitkStandardFileLocations.h>
#include <mitkConfig.h>
#include <itkObject.h>
#include <itkMacro.h>
#include <itksys/SystemTools.hxx>
#include <vtkImageImport.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkMapper.h>
#include <vtkImageActor.h>
#include <vtkImageMapper.h>
#include <vtkPolyData.h>
#include <vtkCamera.h>
#include <vtkObjectFactory.h>
#include <vtkRendererCollection.h>
#include <vtkPNGReader.h>
#include <vtkImageData.h>
#include <vtkConfigure.h>
#include <vtkImageFlip.h>
#include <mbilogo.h>
#include <algorithm>
mitk::ManufacturerLogo::ManufacturerLogo()
:m_ImageData(NULL)
{
m_RenderWindow = NULL;
m_Renderer = vtkRenderer::New();
m_Actor = vtkImageActor::New();
m_Mapper = vtkImageMapper::New();
m_PngReader = vtkPNGReader::New();
m_VtkImageImport = vtkImageImport::New();
m_LogoPosition = mitk::ManufacturerLogo::LowerRight;
m_IsEnabled = false;
m_ForceShowMBIDepartmentLogo = false;
m_ZoomFactor = 1.15;
m_Opacity = 0.5;
m_FileName = "";
m_PngReader->SetFileName(m_FileName.c_str());
}
mitk::ManufacturerLogo::~ManufacturerLogo()
{
if ( m_RenderWindow != NULL )
if ( this->IsEnabled() )
this->Disable();
if ( m_Mapper != NULL )
m_Mapper->Delete();
if ( m_Actor!=NULL )
m_Actor->Delete();
if ( m_Renderer != NULL )
m_Renderer->Delete();
if ( m_PngReader != NULL )
m_PngReader->Delete();
if ( m_VtkImageImport != NULL )
m_VtkImageImport->Delete();
if ( m_ImageData != NULL)
delete[] m_ImageData;
}
/**
* Sets the renderwindow, in which the logo
* will be shown. Make sure, you have called this function
* before calling Enable()
*/
void mitk::ManufacturerLogo::SetRenderWindow( vtkRenderWindow* renderWindow )
{
m_RenderWindow = renderWindow;
}
/**
* Returns the vtkRenderWindow, which is used
* for displaying the logo
*/
vtkRenderWindow* mitk::ManufacturerLogo::GetRenderWindow()
{
return m_RenderWindow;
}
/**
* Returns the renderer responsible for
* rendering the logo into the
* vtkRenderWindow
*/
vtkRenderer* mitk::ManufacturerLogo::GetVtkRenderer()
{
return m_Renderer;
}
/**
* Returns the actor associated with the logo
*/
vtkImageActor* mitk::ManufacturerLogo::GetActor()
{
return m_Actor;
}
/**
* Returns the mapper associated with the
* logo.
*/
vtkImageMapper* mitk::ManufacturerLogo::GetMapper()
{
return m_Mapper;
}
void mitk::ManufacturerLogo::SetLogoSource(const char* filename)
{
std::string file = filename;
if(file.length() != 0)
{
m_FileName = filename;
m_PngReader->SetFileName(m_FileName.c_str());
}
}
/**
* Enables drawing of the logo.
* If you want to disable it, call the Disable() function.
*/
void mitk::ManufacturerLogo::Enable()
{
if(m_IsEnabled)
return;
if(m_RenderWindow != NULL)
{
if(itksys::SystemTools::FileExists(m_FileName.c_str()) && !m_ForceShowMBIDepartmentLogo)
{
m_PngReader->Update();
m_Actor->SetInput(m_PngReader->GetOutput());
}
else // either logo file not found or logo renderer is forced to show the MBI logo
{
m_VtkImageImport->SetDataScalarTypeToUnsignedChar();
m_VtkImageImport->SetNumberOfScalarComponents(mbiLogo_NumberOfScalars);
m_VtkImageImport->SetWholeExtent(0,mbiLogo_Width-1,0,mbiLogo_Height-1,0,1-1);
m_VtkImageImport->SetDataExtentToWholeExtent();
// flip mbi logo around y axis and change color order
m_ImageData = new char[mbiLogo_Height*mbiLogo_Width*mbiLogo_NumberOfScalars];
unsigned int column, row;
char * dest = m_ImageData;
char * source = (char*) &mbiLogo_Data[0];;
char r, g, b, a;
for (column = 0; column < mbiLogo_Height; column++)
for (row = 0; row < mbiLogo_Width; row++)
{ //change r with b
b = *source++;
g = *source++;
r = *source++;
a = *source++;
*dest++ = r;
*dest++ = g;
*dest++ = b;
*dest++ = a;
}
m_VtkImageImport->SetImportVoidPointer(m_ImageData);
m_VtkImageImport->Modified();
m_VtkImageImport->Update();
m_Actor->SetInput(m_VtkImageImport->GetOutput());
}
m_Actor->SetOpacity(m_Opacity);
m_Renderer->AddActor( m_Actor );
m_Renderer->InteractiveOff();
SetupCamera();
SetupPosition();
mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertForegroundRenderer(m_Renderer,false);
m_IsEnabled = true;
}
}
void mitk::ManufacturerLogo::SetupCamera()
{
// set the vtk camera in way that stretches the logo all over the renderwindow
vtkImageData * image = m_Actor->GetInput();
m_Camera = m_Renderer->GetActiveCamera();
m_Camera->SetClippingRange(1,100000);
if ( !image )
return;
double spacing[3];
double origin[3];
int dimensions[3];
image->GetSpacing(spacing);
image->GetOrigin(origin);
image->GetDimensions(dimensions);
double focalPoint[3];
double position[3];
for ( unsigned int cc = 0; cc < 3; cc++)
{
focalPoint[cc] = origin[cc] + ( spacing[cc] * dimensions[cc] ) / 2.0;
position[cc] = focalPoint[cc];
}
m_Camera->SetViewUp (0,1,0);
int idx = 2;
const double distanceToFocalPoint = 1000;
position[idx] = distanceToFocalPoint;
m_Camera->ParallelProjectionOn();
m_Camera->SetPosition (position);
m_Camera->SetFocalPoint (focalPoint);
int d1 = (idx + 1) % 3;
int d2 = (idx + 2) % 3;
double max = std::max(dimensions[d1],dimensions[d2]);
m_Camera->SetParallelScale( max / 2 );
}
void mitk::ManufacturerLogo::SetupPosition()
{ // Position and Scale of the logo
double newPos[4];
int dimensions[3];
vtkImageData * image = m_Actor->GetInput();
image->GetDimensions(dimensions);
// normalize image dimensions
double max = std::max(dimensions[0],dimensions[1]);
double normX = dimensions[0] / max;
double normY = dimensions[1] / max;
double buffer = 0; // buffer to the boarder of the renderwindow
switch(m_LogoPosition)
{
case mitk::ManufacturerLogo::LowerLeft:
{
newPos[0] = (0 + buffer);
newPos[1] = (0 + buffer);
newPos[2] = 0.2 * normX * m_ZoomFactor;
newPos[3] = 0.2 * normY * m_ZoomFactor;
break;
}
case mitk::ManufacturerLogo::LowerRight:
{
newPos[0] = (1 - buffer) - 0.2 * normX * m_ZoomFactor;
newPos[1] = 0.0;
newPos[2] = (1 - buffer);
newPos[3] = 0.2 * normY * m_ZoomFactor;
break;
}
case mitk::ManufacturerLogo::UpperLeft:
{
newPos[0] = (0 + buffer);
newPos[1] = (1 - buffer) - 0.2 * normY * m_ZoomFactor;
newPos[2] = 0.2 * normX * m_ZoomFactor;
newPos[3] = (1 - buffer);
break;
}
case mitk::ManufacturerLogo::UpperRight:
{
newPos[0] = (1 - buffer) - 0.2 * normX * m_ZoomFactor;
newPos[1] = (1 - buffer) - 0.2 * normY * m_ZoomFactor;
newPos[2] = (1 - buffer);
newPos[3] = (1 - buffer);
break;
}
case mitk::ManufacturerLogo::Middle:
default:
{
newPos[0] = 0.5 - 0.2 * normX * m_ZoomFactor;
newPos[1] = 0.5 + 0.2 * normY * m_ZoomFactor;
newPos[2] = 0.5 - 0.2 * normX * m_ZoomFactor;
newPos[3] = 0.5 + 0.2 * normY * m_ZoomFactor;
break;
}
}
m_Renderer->SetViewport(newPos);
}
void mitk::ManufacturerLogo::ForceMBILogoVisible(bool visible)
{
m_ForceShowMBIDepartmentLogo = visible;
}
void mitk::ManufacturerLogo::SetZoomFactor( double factor )
{
m_ZoomFactor = factor;
}
void mitk::ManufacturerLogo::SetOpacity(double opacity)
{
m_Opacity = opacity;
}
/**
* Disables drawing of the logo.
* If you want to enable it, call the Enable() function.
*/
void mitk::ManufacturerLogo::Disable()
{
if ( this->IsEnabled() && !m_ForceShowMBIDepartmentLogo )
{
mitk::VtkLayerController::GetInstance(m_RenderWindow)->RemoveRenderer(m_Renderer);
m_IsEnabled = false;
}
}
/**
* Checks, if the logo is currently
* enabled (visible)
*/
bool mitk::ManufacturerLogo::IsEnabled()
{
return m_IsEnabled;
}
void mitk::ManufacturerLogo::SetRequestedRegionToLargestPossibleRegion()
{
//nothing to do
}
bool mitk::ManufacturerLogo::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::ManufacturerLogo::VerifyRequestedRegion()
{
return true;
}
void mitk::ManufacturerLogo::SetRequestedRegion(itk::DataObject*)
{
//nothing to do
}
diff --git a/Core/Code/Rendering/mitkManufacturerLogo.h b/Core/Code/Rendering/mitkManufacturerLogo.h
index 8662ab2551..d76894c344 100644
--- a/Core/Code/Rendering/mitkManufacturerLogo.h
+++ b/Core/Code/Rendering/mitkManufacturerLogo.h
@@ -1,183 +1,182 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/ for details.
+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 the above copyright notices for more information.
+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 _vtk_Logo_Rendering_h_
#define _vtk_Logo_Rendering_h_
#include <mitkBaseData.h>
class vtkRenderer;
class vtkRenderWindow;
class vtkMapper;
class vtkCamera;
class vtkImageActor;
class vtkImageMapper;
class vtkLookupTable;
class vtkPolyData;
class vtkPNGReader;
class vtkImageImport;
namespace mitk {
class RenderWindow;
/**
* Renders a company logo in the foreground
* of a vtkRenderWindow.
*/
class MITK_CORE_EXPORT ManufacturerLogo : public BaseData
{
public:
mitkClassMacro( ManufacturerLogo, BaseData );
itkNewMacro( Self );
enum LogoPosition{ UpperLeft, UpperRight, LowerLeft, LowerRight, Middle };
/**
* Sets the renderwindow, in which the logo
* will be shown. Make sure, you have called this function
* before calling Enable()
*/
virtual void SetRenderWindow( vtkRenderWindow* renderWindow );
/**
* Sets the source file for the logo.
*/
virtual void SetLogoSource(const char* filename);
/**
* Sets the opacity level of the logo.
*/
virtual void SetOpacity(double opacity);
/**
* Specifies the logo size, values from 0...10,
* where 1 is a nice little logo
*/
virtual void SetZoomFactor( double factor );
/**
* Enables drawing of the logo.
* If you want to disable it, call the Disable() function.
*/
virtual void Enable();
/**
* Disables drawing of the logo.
* If you want to enable it, call the Enable() function.
*/
virtual void Disable();
/**
* Checks, if the logo is currently
* enabled (visible)
*/
virtual bool IsEnabled();
/**
* Empty implementation, since the ManufacturerLogo doesn't
* support the requested region concept
*/
virtual void SetRequestedRegionToLargestPossibleRegion();
/**
* Empty implementation, since the ManufacturerLogo doesn't
* support the requested region concept
*/
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
/**
* Empty implementation, since the ManufacturerLogo doesn't
* support the requested region concept
*/
virtual bool VerifyRequestedRegion();
/**
* Empty implementation, since the ManufacturerLogo doesn't
* support the requested region concept
*/
virtual void SetRequestedRegion(itk::DataObject*);
/**
* Returns the vtkRenderWindow, which is used
* for displaying the logo
*/
virtual vtkRenderWindow* GetRenderWindow();
/**
* Returns the renderer responsible for
* rendering the logo into the
* vtkRenderWindow
*/
virtual vtkRenderer* GetVtkRenderer();
/**
* Returns the actor associated with the logo
*/
virtual vtkImageActor* GetActor();
/**
* Returns the mapper associated with the logo
*/
virtual vtkImageMapper* GetMapper();
/**
* If set true, this method forces the logo rendering mechanism that it always
* renders the MBI department logo, independent from mainapp option settings.
*/
virtual void ForceMBILogoVisible(bool visible);
protected:
void SetupCamera();
void SetupPosition();
/**
* Constructor
*/
ManufacturerLogo();
/**
* Destructor
*/
~ManufacturerLogo();
vtkRenderWindow* m_RenderWindow;
vtkRenderer* m_Renderer;
vtkImageActor* m_Actor;
vtkImageMapper* m_Mapper;
vtkPNGReader* m_PngReader;
vtkCamera* m_Camera;
vtkImageImport* m_VtkImageImport;
std::string m_FileName;
bool m_IsEnabled;
bool m_ForceShowMBIDepartmentLogo;
LogoPosition m_LogoPosition;
double m_ZoomFactor;
double m_Opacity;
char * m_ImageData;
};
} //end of namespace mitk
#endif
diff --git a/Core/Code/Rendering/mitkMapper.cpp b/Core/Code/Rendering/mitkMapper.cpp
index edd8d9be1f..e13ad03a9a 100644
--- a/Core/Code/Rendering/mitkMapper.cpp
+++ b/Core/Code/Rendering/mitkMapper.cpp
@@ -1,158 +1,157 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkMapper.h"
#include "mitkDataNode.h"
#include "mitkBaseRenderer.h"
#include "mitkProperties.h"
mitk::Mapper::Mapper()
:m_TimeStep( 0 )
{
}
mitk::Mapper::~Mapper()
{
}
mitk::BaseData* mitk::Mapper::GetData() const
{
return m_DataNode->GetData();
}
mitk::DataNode* mitk::Mapper::GetDataNode() const
{
itkDebugMacro("returning DataNode address " << this->m_DataNode );
return this->m_DataNode.GetPointer();
}
bool mitk::Mapper::GetColor(float rgb[3], mitk::BaseRenderer* renderer, const char* name) const
{
const mitk::DataNode* node=GetDataNode();
if(node==NULL)
return false;
return node->GetColor(rgb, renderer, name);
}
bool mitk::Mapper::GetVisibility(bool &visible, mitk::BaseRenderer* renderer, const char* name) const
{
const mitk::DataNode* node=GetDataNode();
if(node==NULL)
return false;
return node->GetVisibility(visible, renderer, name);
}
bool mitk::Mapper::GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* name) const
{
const mitk::DataNode* node=GetDataNode();
if(node==NULL)
return false;
return node->GetOpacity(opacity, renderer, name);
}
bool mitk::Mapper::GetLevelWindow(mitk::LevelWindow& levelWindow, mitk::BaseRenderer* renderer, const char* name) const
{
const mitk::DataNode* node=GetDataNode();
if(node==NULL)
return false;
return node->GetLevelWindow(levelWindow, renderer, name);
}
bool mitk::Mapper::IsVisible(mitk::BaseRenderer* renderer, const char* name) const
{
bool visible=true;
GetVisibility(visible, renderer, name);
return visible;
}
void mitk::Mapper::GenerateData()
{
}
void mitk::Mapper::GenerateDataForRenderer(mitk::BaseRenderer* /*renderer*/)
{
}
void mitk::Mapper::CalculateTimeStep( mitk::BaseRenderer *renderer )
{
if ( ( renderer != NULL ) && ( m_DataNode.GetPointer() != NULL ) )
{
m_TimeStep = renderer->GetTimeStep(m_DataNode->GetData());
}
else
{
m_TimeStep = 0;
}
}
void mitk::Mapper::Update(mitk::BaseRenderer *renderer)
{
const DataNode* node = GetDataNode();
assert(node!=NULL);
//safety cause there are datatreenodes that have no defined data (video-nodes and root)
unsigned int dataMTime = 0;
mitk::BaseData::Pointer data = static_cast<mitk::BaseData *>(node->GetData());
if (data.IsNotNull())
{
dataMTime = data->GetMTime();
}
// Calculate time step of the input data for the specified renderer (integer value)
this->CalculateTimeStep( renderer );
// Check if time step is valid
const TimeSlicedGeometry *dataTimeGeometry = data->GetTimeSlicedGeometry();
if ( ( dataTimeGeometry == NULL )
|| ( dataTimeGeometry->GetTimeSteps() == 0 )
|| ( !dataTimeGeometry->IsValidTime( m_TimeStep ) ) )
{
// TimeSlicedGeometry or time step is not valid for this data:
// reset mapper so that nothing is displayed
this->ResetMapper( renderer );
return;
}
if(
(m_LastUpdateTime < GetMTime()) ||
(m_LastUpdateTime < node->GetDataReferenceChangedTime()) ||
(m_LastUpdateTime < dataMTime) ||
(renderer && (m_LastUpdateTime < renderer->GetTimeStepUpdateTime()))
)
{
this->GenerateData();
m_LastUpdateTime.Modified();
}
this->GenerateDataForRenderer(renderer);
}
void mitk::Mapper::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty( "visible", mitk::BoolProperty::New(true), renderer, overwrite );
node->AddProperty( "layer", mitk::IntProperty::New(0), renderer, overwrite);
node->AddProperty( "name", mitk::StringProperty::New("No Name!"), renderer, overwrite );
}
diff --git a/Core/Code/Rendering/mitkMapper.h b/Core/Code/Rendering/mitkMapper.h
index aa709684dd..89a86cd338 100644
--- a/Core/Code/Rendering/mitkMapper.h
+++ b/Core/Code/Rendering/mitkMapper.h
@@ -1,283 +1,282 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MAPPER_H_HEADER_INCLUDED_C1E6EA08
#define MAPPER_H_HEADER_INCLUDED_C1E6EA08
#include <MitkExports.h>
#include "mitkBaseRenderer.h"
#include "mitkLevelWindow.h"
#include <itkObject.h>
#include <itkWeakPointer.h>
//Just included to get VTK version
#include <vtkConfigure.h>
class vtkWindow;
class vtkProp;
namespace mitk {
class BaseRenderer;
class BaseData;
class DataNode;
/** \brief Interface for accessing (templated) LocalStorageHandler instances.
*/
class BaseLocalStorageHandler
{
public:
virtual ~BaseLocalStorageHandler() {}
virtual void ClearLocalStorage(mitk::BaseRenderer *renderer,bool unregisterFromBaseRenderer=true )=0;
};
//##Documentation
//## @brief Base class of all mappers, 2D as well as 3D
//##
//## Base class of all Mappers, 2D as well as 3D.
//## Subclasses of mitk::Mapper control the creation of rendering primitives
//## that interface to the graphics library (e.g., OpenGL, vtk).
//## @todo Should Mapper be a subclass of ImageSource?
//## @ingroup Mapper
class MITK_CORE_EXPORT Mapper : public itk::Object
{
public:
mitkClassMacro(Mapper, itk::Object);
//##Documentation
//## @brief Set the DataNode containing the data to map
itkSetObjectMacro(DataNode, DataNode);
//##Documentation
//## @brief Get the data to map
//##
//## Returns the mitk::BaseData object associated with this mapper.
//## @returns the mitk::BaseData associated with this mapper.
BaseData* GetData() const;
//##Documentation
//## @brief Get the DataNode containing the data to map
virtual DataNode* GetDataNode() const;
//##Documentation
//## @brief Convenience access method for color properties (instances of
//## ColorProperty)
//## @return @a true property was found
virtual bool GetColor(float rgb[3], BaseRenderer* renderer, const char* name = "color") const;
//##Documentation
//## @brief Convenience access method for visibility properties (instances
//## of BoolProperty)
//## @return @a true property was found
//## @sa IsVisible
virtual bool GetVisibility(bool &visible, BaseRenderer* renderer, const char* name = "visible") const;
//##Documentation
//## @brief Convenience access method for opacity properties (instances of
//## FloatProperty)
//## @return @a true property was found
virtual bool GetOpacity(float &opacity, BaseRenderer* renderer, const char* name = "opacity") const;
//##Documentation
//## @brief Convenience access method for color properties (instances of
//## LevelWindoProperty)
//## @return @a true property was found
virtual bool GetLevelWindow(LevelWindow &levelWindow, BaseRenderer* renderer, const char* name = "levelwindow") const;
//##Documentation
//## @brief Convenience access method for visibility properties (instances
//## of BoolProperty). Return value is the visibility. Default is
//## visible==true, i.e., true is returned even if the property (@a
//## propertyKey) is not found.
//##
//## Thus, the return value has a different meaning than in the
//## GetVisibility method!
//## @sa GetVisibility
virtual bool IsVisible(BaseRenderer* renderer, const char* name = "visible") const;
virtual void Update(BaseRenderer* renderer);
virtual void MitkRenderOverlay(BaseRenderer* renderer) = 0;
virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer) = 0;
virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer) = 0;
virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer) = 0;
/**
* \brief Returns whether this is an vtk-based mapper
*/
virtual bool IsVtkBased() const = 0;
/** \brief Returns true if this mapper owns the specified vtkProp for
* the given BaseRenderer.
*
* Note: returns false by default; should be implemented for VTK-based
* Mapper subclasses. */
virtual bool HasVtkProp( const vtkProp* /*prop*/, BaseRenderer* /*renderer*/ )
{
return false;
}
/**
* \brief Release vtk-based graphics resources. Must be overwritten in
* subclasses if vtkProps are used.
*/
virtual void ReleaseGraphicsResources(vtkWindow*) { };
/** \brief Set default values of properties used by this mapper
* to \a node
*
* \param node The node for which the properties are set
* \param overwrite overwrite existing properties (default: \a false)
* \param renderer defines which property list of node is used
* (default: \a NULL, i.e. default property list)
*/
static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false);
/** \brief Returns the current time step as calculated from the renderer */
int GetTimestep() const {return m_TimeStep;};
/** Returns true if this Mapper currently allows for Level-of-Detail rendering.
* This reflects whether this Mapper currently invokes StartEvent, EndEvent, and
* ProgressEvent on BaseRenderer. */
virtual bool IsLODEnabled( BaseRenderer * /*renderer*/ ) const { return false; }
protected:
Mapper();
virtual ~Mapper();
//##Documentation
//## @brief Generate the data needed for rendering (independent of a specific renderer)
virtual void GenerateData();
//##Documentation
//## @brief Generate the data needed for rendering into @a renderer
virtual void GenerateDataForRenderer(BaseRenderer* renderer);
//## Updates the time step, which is sometimes needed in subclasses
virtual void CalculateTimeStep( BaseRenderer* renderer );
//## Reset the mapper (i.e., make sure that nothing is displayed) if no
//## valid data is present.
//##
//## To be implemented in sub-classes.
virtual void ResetMapper( BaseRenderer* /*renderer*/ ) { };
itk::WeakPointer<DataNode> m_DataNode;
//##Documentation
//## @brief timestamp of last update of stored data
itk::TimeStamp m_LastUpdateTime;
private:
//## The current time step of the dataset to be rendered, for use in subclasses
//## The momentary timestep can be accessed via the GetTimestep() method.
int m_TimeStep;
public:
/** \brief Base class for mapper specific rendering ressources.
*/
class BaseLocalStorage
{
};
/** \brief Templated class for management of LocalStorage implementations in Mappers.
*
* The LocalStorageHandler is responsible for providing a LocalStorage to a
* concrete mitk::Mapper subclass. Each RenderWindow / mitk::BaseRenderer is
* assigned its own LocalStorage instance so that all contained ressources
* (actors, shaders, textures, ...) are provided individually per window.
*
*/
template<class L> class LocalStorageHandler : public mitk::BaseLocalStorageHandler
{
protected:
std::map<mitk::BaseRenderer *,L*> m_BaseRenderer2LS;
public:
/** \brief deallocates a local storage for a specifc BaseRenderer (if the
* BaseRenderer is itself deallocating it in its destructor, it has to set
* unregisterFromBaseRenderer=false)
*/
virtual void ClearLocalStorage(mitk::BaseRenderer *renderer,bool unregisterFromBaseRenderer=true )
{
//MITK_INFO << "deleting a localstorage on a mapper request";
if(unregisterFromBaseRenderer)
renderer->UnregisterLocalStorageHandler( this );
L *l = m_BaseRenderer2LS[renderer];
m_BaseRenderer2LS.erase( renderer );
delete l;
}
/** \brief Retrieves a LocalStorage for a specific BaseRenderer.
*
* Should be used by mappers in GenerateData() and ApplyProperties()
*/
L *GetLocalStorage(mitk::BaseRenderer *forRenderer)
{
L *l = m_BaseRenderer2LS[ forRenderer ];
if(!l)
{
//MITK_INFO << "creating new localstorage";
l = new L;
m_BaseRenderer2LS[ forRenderer ] = l;
forRenderer->RegisterLocalStorageHandler( this );
}
return l;
}
~LocalStorageHandler()
{
typename std::map<mitk::BaseRenderer *,L*>::iterator it;
for ( it=m_BaseRenderer2LS.begin() ; it != m_BaseRenderer2LS.end(); it++ )
{
(*it).first->UnregisterLocalStorageHandler(this);
delete (*it).second;
}
m_BaseRenderer2LS.clear();
}
};
};
} // namespace mitk
#endif /* MAPPER_H_HEADER_INCLUDED_C1E6EA08 */
diff --git a/Core/Code/Rendering/mitkMapper2D.cpp b/Core/Code/Rendering/mitkMapper2D.cpp
index 7e1c053060..2aa4ab48ef 100644
--- a/Core/Code/Rendering/mitkMapper2D.cpp
+++ b/Core/Code/Rendering/mitkMapper2D.cpp
@@ -1,33 +1,32 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkMapper2D.h"
mitk::Mapper2D::Mapper2D()
{
}
mitk::Mapper2D::~Mapper2D()
{
}
void mitk::Mapper2D::SetGeometry3D(const mitk::Geometry3D* aGeometry3D)
{
m_Geometry3D = aGeometry3D;
Modified();
}
diff --git a/Core/Code/Rendering/mitkMapper2D.h b/Core/Code/Rendering/mitkMapper2D.h
index a85b022a1e..b2030c771e 100644
--- a/Core/Code/Rendering/mitkMapper2D.h
+++ b/Core/Code/Rendering/mitkMapper2D.h
@@ -1,64 +1,63 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MAPPER2D_H_HEADER_INCLUDED_C1C5453B
#define MAPPER2D_H_HEADER_INCLUDED_C1C5453B
#include "mitkMapper.h"
#include "mitkGeometry3D.h"
namespace mitk {
//##Documentation
//## @brief Base class of all Mappers for 2D display
//##
//## Base class of all Mappers for 2D display, i.e., a frontal view on a plane
//## display area, so nothing rotated in 3D space as, e.g., a plane in 3D space
//## (such things are done by subclasses of Mapper3D).
//## @note [not yet used:] SetGeometry3D() tells the Mapper2D which slices will
//## potentially be requested.
//## @ingroup Mapper
class MITK_CORE_EXPORT Mapper2D : public Mapper
{
public:
mitkClassMacro(Mapper2D,Mapper);
//##Documentation
//## @brief Set Geometry3D containing the all possible Geometry2D that may be requested for mapping
//## @sa m_Geometry3D
virtual void SetGeometry3D(const mitk::Geometry3D* aGeometry3D);
protected:
Mapper2D();
virtual ~Mapper2D();
//##Documentation
//## @brief Set Geometry3D containing the all possible Geometry2D that may be requested for mapping
//## @note not yet implemented
//## The idea was that this allows storing/pre-fetching of data required for mapping.
//## Should be called by SliceNavigationController.
//## @todo check design and implement when implementing (sub-)classes of SliceNavigationController
Geometry3D::ConstPointer m_Geometry3D;
};
} // namespace mitk
#endif /* MAPPER2D_H_HEADER_INCLUDED_C1C5453B */
diff --git a/Core/Code/Rendering/mitkMapper3D.cpp b/Core/Code/Rendering/mitkMapper3D.cpp
index 9e4d778b17..b4d3005800 100644
--- a/Core/Code/Rendering/mitkMapper3D.cpp
+++ b/Core/Code/Rendering/mitkMapper3D.cpp
@@ -1,28 +1,27 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkMapper3D.h"
mitk::Mapper3D::Mapper3D()
{
}
mitk::Mapper3D::~Mapper3D()
{
}
diff --git a/Core/Code/Rendering/mitkMapper3D.h b/Core/Code/Rendering/mitkMapper3D.h
index bb38c5f78b..eb43e5cd70 100644
--- a/Core/Code/Rendering/mitkMapper3D.h
+++ b/Core/Code/Rendering/mitkMapper3D.h
@@ -1,45 +1,44 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MAPPER3D_H_HEADER_INCLUDED_C1C517B9
#define MAPPER3D_H_HEADER_INCLUDED_C1C517B9
#include "mitkMapper.h"
namespace mitk {
//##Documentation
//## @brief Base class of all mappers for 3D display
//## @ingroup Mapper
class MITK_CORE_EXPORT Mapper3D : public Mapper
{
public:
mitkClassMacro(Mapper3D,Mapper);
protected:
Mapper3D();
virtual ~Mapper3D();
};
} // namespace mitk
#endif /* MAPPER3D_H_HEADER_INCLUDED_C1C517B9 */
diff --git a/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp b/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp
index cd80954d3b..f7817e3e3b 100644
--- a/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp
+++ b/Core/Code/Rendering/mitkPointSetGLMapper2D.cpp
@@ -1,497 +1,496 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetGLMapper2D.h"
#include "mitkPointSet.h"
#include "mitkPlaneGeometry.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "vtkLinearTransform.h"
#include "mitkStringProperty.h"
#include "mitkPointSet.h"
#include "mitkVtkPropRenderer.h"
#include "mitkGL.h"
//const float selectedColor[]={1.0,0.0,0.6}; //for selected!
mitk::PointSetGLMapper2D::PointSetGLMapper2D()
: m_Polygon(false),
m_ShowPoints(true),
m_ShowDistances(false),
m_DistancesDecimalDigits(1),
m_ShowAngles(false),
m_ShowDistantLines(true),
m_LineWidth(1)
{
}
mitk::PointSetGLMapper2D::~PointSetGLMapper2D()
{
}
const mitk::PointSet *mitk::PointSetGLMapper2D::GetInput(void)
{
return static_cast<const mitk::PointSet * > ( GetData() );
}
void mitk::PointSetGLMapper2D::ApplyProperties(mitk::BaseRenderer* renderer)
{
GLMapper2D::ApplyProperties( renderer );
const mitk::DataNode* node=GetDataNode();
if( node == NULL )
return;
node->GetBoolProperty("show contour", m_Polygon);
node->GetBoolProperty("show points", m_ShowPoints);
node->GetBoolProperty("show distances", m_ShowDistances);
node->GetIntProperty("distance decimal digits", m_DistancesDecimalDigits);
node->GetBoolProperty("show angles", m_ShowAngles);
node->GetBoolProperty("show distant lines", m_ShowDistantLines);
node->GetIntProperty("line width", m_LineWidth);
node->GetIntProperty("point line width", m_PointLineWidth);
node->GetIntProperty("point 2D size", m_Point2DSize);
}
static bool makePerpendicularVector2D(const mitk::Vector2D& in, mitk::Vector2D& out)
{
if((fabs(in[0])>0) && ( (fabs(in[0])>fabs(in[1])) || (in[1] == 0) ) )
{
out[0]=-in[1]/in[0];
out[1]=1;
out.Normalize();
return true;
}
else
if(fabs(in[1])>0)
{
out[0]=1;
out[1]=-in[0]/in[1];
out.Normalize();
return true;
}
else
return false;
}
void mitk::PointSetGLMapper2D::Paint( mitk::BaseRenderer *renderer )
{
const mitk::DataNode* node=GetDataNode();
if( node == NULL )
return;
const int text2dDistance = 10;
if(IsVisible(renderer)==false) return;
// @FIXME: Logik fuer update
bool updateNeccesary=true;
if (updateNeccesary)
{
// ok, das ist aus GenerateData kopiert
mitk::PointSet::Pointer input = const_cast<mitk::PointSet*>(this->GetInput());
// Get the TimeSlicedGeometry of the input object
const TimeSlicedGeometry* inputTimeGeometry = input->GetTimeSlicedGeometry();
if (( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) )
{
return;
}
//
// get the world time
//
const Geometry2D* worldGeometry = renderer->GetCurrentWorldGeometry2D();
assert( worldGeometry != NULL );
ScalarType time = worldGeometry->GetTimeBounds()[ 0 ];
//
// convert the world time in time steps of the input object
//
int timeStep=0;
if ( time > ScalarTypeNumericTraits::NonpositiveMin() )
timeStep = inputTimeGeometry->MSToTimeStep( time );
if ( inputTimeGeometry->IsValidTime( timeStep ) == false )
{
return;
}
mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timeStep );
if ( itkPointSet.GetPointer() == NULL)
{
return;
}
mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
assert(displayGeometry.IsNotNull());
//apply color and opacity read from the PropertyList
ApplyProperties(renderer);
vtkLinearTransform* transform = GetDataNode()->GetVtkTransform();
//List of the Points
PointSet::DataType::PointsContainerConstIterator it, end;
it = itkPointSet->GetPoints()->Begin();
end = itkPointSet->GetPoints()->End();
//iterator on the additional data of each point
PointSet::DataType::PointDataContainerIterator selIt, selEnd;
bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size());
selIt = itkPointSet->GetPointData()->Begin();
selEnd = itkPointSet->GetPointData()->End();
int counter = 0;
//for writing text
int j = 0;
//for switching back to old color after using selected color
float recallColor[4];
glGetFloatv(GL_CURRENT_COLOR,recallColor);
//get the properties for coloring the points
float unselectedColor[4] = {1.0, 1.0, 0.0, 1.0};//yellow
//check if there is an unselected property
if (dynamic_cast<mitk::ColorProperty*>(node->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != NULL)
{
mitk::Color tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor"))->GetValue();
unselectedColor[0] = tmpColor[0];
unselectedColor[1] = tmpColor[1];
unselectedColor[2] = tmpColor[2];
unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value
}
else if (dynamic_cast<mitk::ColorProperty*>(node->GetPropertyList(NULL)->GetProperty("unselectedcolor")) != NULL)
{
mitk::Color tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor"))->GetValue();
unselectedColor[0] = tmpColor[0];
unselectedColor[1] = tmpColor[1];
unselectedColor[2] = tmpColor[2];
unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value
}
else
{
//get the color from the dataNode
node->GetColor(unselectedColor, NULL);
}
//get selected property
float selectedColor[4] = {1.0, 0.0, 0.6, 1.0};
if (dynamic_cast<mitk::ColorProperty*>(node->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL)
{
mitk::Color tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue();
selectedColor[0] = tmpColor[0];
selectedColor[1] = tmpColor[1];
selectedColor[2] = tmpColor[2];
selectedColor[3] = 1.0f;
}
else if (dynamic_cast<mitk::ColorProperty*>(node->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL)
{
mitk::Color tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue();
selectedColor[0] = tmpColor[0];
selectedColor[1] = tmpColor[1];
selectedColor[2] = tmpColor[2];
selectedColor[3] = 1.0f;
}
//check if there is an pointLineWidth property
if (dynamic_cast<mitk::IntProperty*>(node->GetPropertyList(renderer)->GetProperty("point line width")) != NULL)
{
m_PointLineWidth = dynamic_cast<mitk::IntProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("point line width"))->GetValue();
}
else if (dynamic_cast<mitk::IntProperty*>(node->GetPropertyList(NULL)->GetProperty("point line width")) != NULL)
{
m_PointLineWidth = dynamic_cast<mitk::IntProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("point line width"))->GetValue();
}
//check if there is an point 2D size property
if (dynamic_cast<mitk::IntProperty*>(node->GetPropertyList(renderer)->GetProperty("point 2D size")) != NULL)
{
m_Point2DSize = dynamic_cast<mitk::IntProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("point 2D size"))->GetValue();
}
else if (dynamic_cast<mitk::IntProperty*>(node->GetPropertyList(NULL)->GetProperty("point 2D size")) != NULL)
{
m_Point2DSize = dynamic_cast<mitk::IntProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("point 2D size"))->GetValue();
}
Point3D p; // currently visited point
Point3D lastP; // last visited point
Vector3D vec; // p - lastP
Vector3D lastVec; // lastP - point before lastP
vec.Fill(0);
mitk::Point3D projected_p; // p projected on viewplane
Point2D pt2d; // projected_p in display coordinates
Point2D lastPt2d; // last projected_p in display coordinates
Point2D preLastPt2d;// projected_p in display coordinates before lastPt2d
while(it!=end) // iterate over all points
{
lastP = p; // valid only for counter > 0
lastVec = vec; // valid only for counter > 1
preLastPt2d = lastPt2d; // valid only for counter > 1
lastPt2d = pt2d; // valid only for counter > 0
float vtkp[3];
itk2vtk(it->Value(), vtkp);
transform->TransformPoint(vtkp, vtkp);
vtk2itk(vtkp,p);
vec = p-lastP; // valid only for counter > 0
displayGeometry->Project(p, projected_p);
Vector3D diff=p-projected_p;
ScalarType scalardiff = diff.GetSquaredNorm();
//MouseOrientation
bool isInputDevice=false;
bool isRendererSlice = scalardiff < 0.00001; //cause roundoff error
if(this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice && !isRendererSlice )
{
displayGeometry->Map(projected_p, pt2d);
displayGeometry->WorldToDisplay(pt2d, pt2d);
//Point size depending of distance to slice
/*float p_size = (1/scalardiff)*10*m_Point2DSize;
if(p_size < m_Point2DSize * 0.6 )
p_size = m_Point2DSize * 0.6 ;
else if ( p_size > m_Point2DSize )
p_size = m_Point2DSize;*/
float p_size = (1/scalardiff)*100.0;
if(p_size < 6.0 )
p_size = 6.0 ;
else if ( p_size > 10.0 )
p_size = 10.0;
//draw Point
float opacity = (p_size<8)?0.3:1.0;//don't get the opacity from the node? Feature not a bug! Otehrwise the 2D cross is hardly seen.
glColor4f(unselectedColor[0],unselectedColor[1],unselectedColor[2],opacity);
glPointSize(p_size);
//glShadeModel(GL_FLAT);
glBegin (GL_POINTS);
glVertex2fv(&pt2d[0]);
glEnd ();
}
//for point set
if(!isInputDevice && ( (scalardiff<4.0) || (m_Polygon)))
{
Point2D tmp;
displayGeometry->Map(projected_p, pt2d);
displayGeometry->WorldToDisplay(pt2d, pt2d);
Vector2D horz,vert;
horz[0]=(float)m_Point2DSize-scalardiff*2; horz[1]=0;
vert[0]=0; vert[1]=(float)m_Point2DSize-scalardiff*2;
// now paint text if available
if (dynamic_cast<mitk::StringProperty *>(this->GetDataNode()
->GetProperty("label")) != NULL)
{
const char * pointLabel = dynamic_cast<mitk::StringProperty *>(
this->GetDataNode()->GetProperty("label"))->GetValue();
std::string l = pointLabel;
if (input->GetSize()>1)
{
// char buffer[20];
// sprintf(buffer,"%d",it->Index());
std::stringstream ss;
ss << it->Index();
l.append(ss.str());
}
if (unselectedColor != NULL)
{
mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast<mitk::VtkPropRenderer*>( renderer );
float rgb[3];//yellow
rgb[0] = unselectedColor[0]; rgb[1] = unselectedColor[1]; rgb[2] = unselectedColor[2];
OpenGLrenderer->WriteSimpleText(l, pt2d[0] + text2dDistance, pt2d[1] + text2dDistance,rgb[0], rgb[1],rgb[2]);
}
else
{
mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast<mitk::VtkPropRenderer*>( renderer );
OpenGLrenderer->WriteSimpleText(l, pt2d[0] + text2dDistance, pt2d[1] + text2dDistance,0.0,1.0,0.0);
}
}
if((m_ShowPoints) && (scalardiff<4.0))
{
//check if the point is to be marked as selected
if(selIt != selEnd || pointDataBroken)
{
bool addAsSelected = false;
if (pointDataBroken)
addAsSelected = false;
else if (selIt->Value().selected)
addAsSelected = true;
else
addAsSelected = false;
if (addAsSelected)
{
horz[0]=(float)m_Point2DSize;
vert[1]=(float)m_Point2DSize;
glColor3f(selectedColor[0],selectedColor[1],selectedColor[2]);
glLineWidth(m_PointLineWidth);
//a diamond around the point with the selected color
glBegin (GL_LINE_LOOP);
tmp=pt2d-horz; glVertex2fv(&tmp[0]);
tmp=pt2d+vert; glVertex2fv(&tmp[0]);
tmp=pt2d+horz; glVertex2fv(&tmp[0]);
tmp=pt2d-vert; glVertex2fv(&tmp[0]);
glEnd ();
glLineWidth(1);
//the actual point in the specified color to see the usual color of the point
glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]);
glPointSize(1);
glBegin (GL_POINTS);
tmp=pt2d; glVertex2fv(&tmp[0]);
glEnd ();
}
else //if not selected
{
glColor3f(unselectedColor[0],unselectedColor[1],unselectedColor[2]);
glLineWidth(m_PointLineWidth);
//drawing crosses
glBegin (GL_LINES);
tmp=pt2d-horz; glVertex2fv(&tmp[0]);
tmp=pt2d+horz; glVertex2fv(&tmp[0]);
tmp=pt2d-vert; glVertex2fv(&tmp[0]);
tmp=pt2d+vert; glVertex2fv(&tmp[0]);
glEnd ();
glLineWidth(1);
}
}
}
bool drawLinesEtc = true;
if (!m_ShowDistantLines && counter > 0) // check, whether this line should be drawn
{
ScalarType currentDistance = displayGeometry->GetWorldGeometry()->SignedDistance(p);
ScalarType lastDistance = displayGeometry->GetWorldGeometry()->SignedDistance(lastP);
if ( currentDistance * lastDistance > 0.5 ) // points on same side of plane
drawLinesEtc = false;
}
if ( m_Polygon && counter > 0 && drawLinesEtc) // draw a line
{
//get contour color property
float contourColor[4] = {unselectedColor[0], unselectedColor[1], unselectedColor[2], unselectedColor[3]};//so if no property set, then use unselected color
if (dynamic_cast<mitk::ColorProperty*>(node->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL)
{
mitk::Color tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue();
contourColor[0] = tmpColor[0];
contourColor[1] = tmpColor[1];
contourColor[2] = tmpColor[2];
contourColor[3] = 1.0f;
}
else if (dynamic_cast<mitk::ColorProperty*>(node->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL)
{
mitk::Color tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue();
contourColor[0] = tmpColor[0];
contourColor[1] = tmpColor[1];
contourColor[2] = tmpColor[2];
contourColor[3] = 1.0f;
}
//set this color
glColor3f(contourColor[0],contourColor[1],contourColor[2]);
glLineWidth( m_LineWidth );
glBegin (GL_LINES);
glVertex2fv(&pt2d[0]);
glVertex2fv(&lastPt2d[0]);
glEnd ();
glLineWidth(1.0);
if(m_ShowDistances) // calculate and print a distance
{
std::stringstream buffer;
float distance = vec.GetNorm();
buffer<<std::fixed <<std::setprecision(m_DistancesDecimalDigits)<<distance<<" mm";
Vector2D vec2d = pt2d-lastPt2d;
makePerpendicularVector2D(vec2d, vec2d);
Vector2D pos2d = (lastPt2d.GetVectorFromOrigin()+pt2d)*0.5+vec2d*text2dDistance;
mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast<mitk::VtkPropRenderer*>( renderer );
OpenGLrenderer->WriteSimpleText(buffer.str(), pos2d[0], pos2d[1]);
//this->WriteTextXY(pos2d[0], pos2d[1], buffer.str(),renderer);
}
if(m_ShowAngles && counter > 1 ) // calculate and print the angle btw. two lines
{
std::stringstream buffer;
//buffer << angle(vec.Get_vnl_vector(), -lastVec.Get_vnl_vector())*180/vnl_math::pi << "�";
buffer << angle(vec.Get_vnl_vector(), -lastVec.Get_vnl_vector())*180/vnl_math::pi << (char)176;
Vector2D vec2d = pt2d-lastPt2d;
vec2d.Normalize();
Vector2D lastVec2d = lastPt2d-preLastPt2d;
lastVec2d.Normalize();
vec2d=vec2d-lastVec2d;
vec2d.Normalize();
Vector2D pos2d = lastPt2d.GetVectorFromOrigin()+vec2d*text2dDistance*text2dDistance;
mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast<mitk::VtkPropRenderer*>( renderer );
OpenGLrenderer->WriteSimpleText(buffer.str(), pos2d[0], pos2d[1]);
//this->WriteTextXY(pos2d[0], pos2d[1], buffer.str(),renderer);
}
}
counter++;
}
++it;
if(selIt != selEnd && !pointDataBroken)
++selIt;
j++;
}
//recall the color to the same color before this drawing
glColor3f(recallColor[0],recallColor[1],recallColor[2]);
}
}
void mitk::PointSetGLMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); // width of the line from one point to another
node->AddProperty( "point line width", mitk::IntProperty::New(1), renderer, overwrite ); //width of the cross marking a point
node->AddProperty( "point 2D size", mitk::IntProperty::New(8), renderer, overwrite ); // length of the cross marking a point // length of an edge of the box marking a point
node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); // contour of the line between points
node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); //show or hide points
node->AddProperty( "show distances", mitk::BoolProperty::New(false), renderer, overwrite ); //show or hide distance measure (not always available)
node->AddProperty( "distance decimal digits", mitk::IntProperty::New(2), renderer, overwrite ); //set the number of decimal digits to be shown
node->AddProperty( "show angles", mitk::BoolProperty::New(false), renderer, overwrite ); //show or hide angle measurement (not always available)
node->AddProperty( "show distant lines", mitk::BoolProperty::New(false), renderer, overwrite ); //show the line between to points from a distant view (equals "always on top" option)
node->AddProperty( "layer", mitk::IntProperty::New(1), renderer, overwrite ); // default to draw pointset above images (they have a default layer of 0)
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
diff --git a/Core/Code/Rendering/mitkPointSetGLMapper2D.h b/Core/Code/Rendering/mitkPointSetGLMapper2D.h
index af86f391a9..87ebda60e7 100644
--- a/Core/Code/Rendering/mitkPointSetGLMapper2D.h
+++ b/Core/Code/Rendering/mitkPointSetGLMapper2D.h
@@ -1,94 +1,93 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPointSetMAPPER2D_H_HEADER_INCLUDED
#define MITKPointSetMAPPER2D_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkGLMapper2D.h"
namespace mitk {
class BaseRenderer;
class PointSet;
/**
* @brief OpenGL-based mapper to display a mitk::PointSet in a 2D window.
*
* This mapper can actually more than just draw a number of points of a
* mitk::PointSet. If you set the right properties of the mitk::DataNode,
* which contains the point set, then this mapper will also draw lines
* connecting the points, and calculate and display distances and angles
* between adjacent points. Here is a complete list of boolean properties,
* which might be of interest:
*
* - \b "show contour": Draw not only the points but also the connections between
* them (default false)
* - \b "line width": IntProperty which gives the width of the contour lines
* - \b "show points": Wheter or not to draw the actual points (default true)
* - \b "show distances": Wheter or not to calculate and print the distance
* between adjacent points (default false)
* - \b "show angles": Wheter or not to calculate and print the angle between
* adjacent points (default false)
* - \b "show distant lines": When true, the mapper will also draw contour
* lines that are far away form the current slice (default true)
* - \b "label": StringProperty with a label for this point set
*
* BUG 1321 - possible new features:
* point-2d-size (length of lines in cross/diamond)
* point-linewidth
*
* @ingroup Mapper
*/
class MITK_CORE_EXPORT PointSetGLMapper2D : public GLMapper2D
{
public:
mitkClassMacro(PointSetGLMapper2D, GLMapper2D);
itkNewMacro(Self);
/** @brief Get the PointDataList to map */
virtual const mitk::PointSet * GetInput(void);
virtual void Paint(mitk::BaseRenderer * renderer);
virtual void ApplyProperties(mitk::BaseRenderer* renderer);
static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false);
protected:
PointSetGLMapper2D();
virtual ~PointSetGLMapper2D();
bool m_Polygon;
bool m_ShowPoints;
bool m_ShowDistances;
int m_DistancesDecimalDigits;
bool m_ShowAngles;
bool m_ShowDistantLines;
int m_LineWidth;
int m_PointLineWidth;
int m_Point2DSize;
};
} // namespace mitk
#endif /* MITKPointSetMapper2D_H_HEADER_INCLUDED */
diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp b/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp
index 8ffcb44e28..765a37df65 100644
--- a/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp
+++ b/Core/Code/Rendering/mitkPointSetVtkMapper3D.cpp
@@ -1,635 +1,634 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetVtkMapper3D.h"
#include "mitkDataNode.h"
#include "mitkProperties.h"
#include "mitkColorProperty.h"
#include "mitkVtkPropRenderer.h"
#include "mitkPointSet.h"
#include <vtkActor.h>
#include <vtkAppendPolyData.h>
#include <vtkPropAssembly.h>
#include <vtkTubeFilter.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkCubeSource.h>
#include <vtkConeSource.h>
#include <vtkCylinderSource.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkCellArray.h>
#include <vtkVectorText.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkPolyDataAlgorithm.h>
#include <stdlib.h>
const mitk::PointSet* mitk::PointSetVtkMapper3D::GetInput()
{
return static_cast<const mitk::PointSet * > ( GetData() );
}
mitk::PointSetVtkMapper3D::PointSetVtkMapper3D()
: m_vtkSelectedPointList(NULL),
m_vtkUnselectedPointList(NULL),
m_VtkSelectedPolyDataMapper(NULL),
m_VtkUnselectedPolyDataMapper(NULL),
m_vtkTextList(NULL),
m_NumberOfSelectedAdded(0),
m_NumberOfUnselectedAdded(0),
m_PointSize(1.0),
m_ContourRadius(0.5)
{
//propassembly
m_PointsAssembly = vtkSmartPointer<vtkPropAssembly>::New();
//creating actors to be able to set transform
m_SelectedActor = vtkSmartPointer<vtkActor>::New();
m_UnselectedActor = vtkSmartPointer<vtkActor>::New();
m_ContourActor = vtkSmartPointer<vtkActor>::New();
}
mitk::PointSetVtkMapper3D::~PointSetVtkMapper3D()
{
}
void mitk::PointSetVtkMapper3D::ReleaseGraphicsResources(vtkWindow *renWin)
{
m_PointsAssembly->ReleaseGraphicsResources(renWin);
m_SelectedActor->ReleaseGraphicsResources(renWin);
m_UnselectedActor->ReleaseGraphicsResources(renWin);
m_ContourActor->ReleaseGraphicsResources(renWin);
}
void mitk::PointSetVtkMapper3D::CreateVTKRenderObjects()
{
m_vtkSelectedPointList = vtkSmartPointer<vtkAppendPolyData>::New();
m_vtkUnselectedPointList = vtkSmartPointer<vtkAppendPolyData>::New();
m_PointsAssembly->VisibilityOn();
if(m_PointsAssembly->GetParts()->IsItemPresent(m_SelectedActor))
m_PointsAssembly->RemovePart(m_SelectedActor);
if(m_PointsAssembly->GetParts()->IsItemPresent(m_UnselectedActor))
m_PointsAssembly->RemovePart(m_UnselectedActor);
if(m_PointsAssembly->GetParts()->IsItemPresent(m_ContourActor))
m_PointsAssembly->RemovePart(m_ContourActor);
// exceptional displaying for PositionTracker -> MouseOrientationTool
int mapperID;
bool isInputDevice=false;
if( this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice )
{
if( this->GetDataNode()->GetIntProperty("BaseRendererMapperID",mapperID) && mapperID == 2)
return; //The event for the PositionTracker came from the 3d widget and not needs to be displayed
}
// get and update the PointSet
mitk::PointSet::Pointer input = const_cast<mitk::PointSet*>(this->GetInput());
/* only update the input data, if the property tells us to */
bool update = true;
this->GetDataNode()->GetBoolProperty("updateDataOnRender", update);
if (update == true)
input->Update();
int timestep = this->GetTimestep();
mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep );
if ( itkPointSet.GetPointer() == NULL)
{
m_PointsAssembly->VisibilityOff();
return;
}
mitk::PointSet::PointsContainer::Iterator pointsIter;
mitk::PointSet::PointDataContainer::Iterator pointDataIter;
int j;
m_NumberOfSelectedAdded = 0;
m_NumberOfUnselectedAdded = 0;
//create contour
bool makeContour = false;
this->GetDataNode()->GetBoolProperty("show contour", makeContour);
if (makeContour)
{
this->CreateContour(NULL);
}
//now fill selected and unselected pointList
//get size of Points in Property
m_PointSize = 2;
mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("pointsize"));
if ( pointSizeProp.IsNotNull() )
m_PointSize = pointSizeProp->GetValue();
//get the property for creating a label onto every point only once
bool showLabel = true;
this->GetDataNode()->GetBoolProperty("show label", showLabel);
const char * pointLabel=NULL;
if(showLabel)
{
if(dynamic_cast<mitk::StringProperty *>(this->GetDataNode()->GetPropertyList()->GetProperty("label")) != NULL)
pointLabel =dynamic_cast<mitk::StringProperty *>(this->GetDataNode()->GetPropertyList()->GetProperty("label"))->GetValue();
else
showLabel = false;
}
//check if the list for the PointDataContainer is the same size as the PointsContainer. Is not, then the points were inserted manually and can not be visualized according to the PointData (selected/unselected)
bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size());
//now add an object for each point in data
pointDataIter = itkPointSet->GetPointData()->Begin();
for (j=0, pointsIter=itkPointSet->GetPoints()->Begin();
pointsIter!=itkPointSet->GetPoints()->End();
pointsIter++, j++)
{
//check for the pointtype in data and decide which geom-object to take and then add to the selected or unselected list
int pointType;
if(itkPointSet->GetPointData()->size() == 0 || pointDataBroken)
pointType = mitk::PTUNDEFINED;
else
pointType = pointDataIter.Value().pointSpec;
vtkSmartPointer<vtkPolyDataAlgorithm> source;
switch (pointType)
{
case mitk::PTUNDEFINED:
{
vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
sphere->SetRadius(m_PointSize);
itk::Point<float> point1 = pointsIter->Value();
sphere->SetCenter(point1[0],point1[1],point1[2]);
//sphere->SetCenter(pointsIter.Value()[0],pointsIter.Value()[1],pointsIter.Value()[2]);
//MouseOrientation Tool (PositionTracker)
if(isInputDevice)
{
sphere->SetThetaResolution(10);
sphere->SetPhiResolution(10);
}
else
{
sphere->SetThetaResolution(20);
sphere->SetPhiResolution(20);
}
source = sphere;
}
break;
case mitk::PTSTART:
{
vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
cube->SetXLength(m_PointSize/2);
cube->SetYLength(m_PointSize/2);
cube->SetZLength(m_PointSize/2);
itk::Point<float> point1 = pointsIter->Value();
cube->SetCenter(point1[0],point1[1],point1[2]);
source = cube;
}
break;
case mitk::PTCORNER:
{
vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
cone->SetRadius(m_PointSize);
itk::Point<float> point1 = pointsIter->Value();
cone->SetCenter(point1[0],point1[1],point1[2]);
cone->SetResolution(20);
source = cone;
}
break;
case mitk::PTEDGE:
{
vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New();
cylinder->SetRadius(m_PointSize);
itk::Point<float> point1 = pointsIter->Value();
cylinder->SetCenter(point1[0],point1[1],point1[2]);
cylinder->SetResolution(20);
source = cylinder;
}
break;
case mitk::PTEND:
{
vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
sphere->SetRadius(m_PointSize);
//itk::Point<float> point1 = pointsIter->Value();
sphere->SetThetaResolution(20);
sphere->SetPhiResolution(20);
source = sphere;
}
break;
default:
{
vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
sphere->SetRadius(m_PointSize);
itk::Point<float> point1 = pointsIter->Value();
sphere->SetCenter(point1[0],point1[1],point1[2]);
sphere->SetThetaResolution(20);
sphere->SetPhiResolution(20);
source = sphere;
}
break;
}
if (!pointDataBroken)
{
if (pointDataIter.Value().selected)
{
m_vtkSelectedPointList->AddInput(source->GetOutput());
++m_NumberOfSelectedAdded;
}
else
{
m_vtkUnselectedPointList->AddInput(source->GetOutput());
++m_NumberOfUnselectedAdded;
}
}
else
{
m_vtkUnselectedPointList->AddInput(source->GetOutput());
++m_NumberOfUnselectedAdded;
}
if (showLabel)
{
char buffer[20];
std::string l = pointLabel;
if ( input->GetSize()>1 )
{
sprintf(buffer,"%d",j+1);
l.append(buffer);
}
// Define the text for the label
vtkSmartPointer<vtkVectorText> label = vtkSmartPointer<vtkVectorText>::New();
label->SetText(l.c_str());
//# Set up a transform to move the label to a new position.
vtkSmartPointer<vtkTransform> aLabelTransform = vtkSmartPointer<vtkTransform>::New();
aLabelTransform->Identity();
itk::Point<float> point1 = pointsIter->Value();
aLabelTransform->Translate(point1[0]+2,point1[1]+2,point1[2]);
aLabelTransform->Scale(5.7,5.7,5.7);
//# Move the label to a new position.
vtkSmartPointer<vtkTransformPolyDataFilter> labelTransform = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
labelTransform->SetTransform(aLabelTransform);
labelTransform->SetInput(label->GetOutput());
//add it to the wright PointList
if (pointType)
{
m_vtkSelectedPointList->AddInput(labelTransform->GetOutput());
++m_NumberOfSelectedAdded;
}
else
{
m_vtkUnselectedPointList->AddInput(labelTransform->GetOutput());
++m_NumberOfUnselectedAdded;
}
}
if(pointDataIter != itkPointSet->GetPointData()->End())
pointDataIter++;
} // end FOR
//now according to number of elements added to selected or unselected, build up the rendering pipeline
if (m_NumberOfSelectedAdded > 0)
{
m_VtkSelectedPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
m_VtkSelectedPolyDataMapper->SetInput(m_vtkSelectedPointList->GetOutput());
//create a new instance of the actor
m_SelectedActor = vtkSmartPointer<vtkActor>::New();
m_SelectedActor->SetMapper(m_VtkSelectedPolyDataMapper);
m_PointsAssembly->AddPart(m_SelectedActor);
}
if (m_NumberOfUnselectedAdded > 0)
{
m_VtkUnselectedPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
m_VtkUnselectedPolyDataMapper->SetInput(m_vtkUnselectedPointList->GetOutput());
//create a new instance of the actor
m_UnselectedActor = vtkSmartPointer<vtkActor>::New();
m_UnselectedActor->SetMapper(m_VtkUnselectedPolyDataMapper);
m_PointsAssembly->AddPart(m_UnselectedActor);
}
}
void mitk::PointSetVtkMapper3D::GenerateData()
{
//create new vtk render objects (e.g. sphere for a point)
this->CreateVTKRenderObjects();
//apply props
this->ApplyProperties(m_ContourActor,NULL);
}
void mitk::PointSetVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer )
{
SetVtkMapperImmediateModeRendering(m_VtkSelectedPolyDataMapper);
SetVtkMapperImmediateModeRendering(m_VtkUnselectedPolyDataMapper);
mitk::FloatProperty::Pointer pointSizeProp = dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("pointsize"));
mitk::FloatProperty::Pointer contourSizeProp = dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("contoursize"));
// only create new vtk render objects if property values were changed
if ( pointSizeProp.IsNotNull() && contourSizeProp.IsNotNull() )
{
if (m_PointSize!=pointSizeProp->GetValue() || m_ContourRadius!= contourSizeProp->GetValue())
{
this->CreateVTKRenderObjects();
}
}
this->ApplyProperties(m_ContourActor,renderer);
if(IsVisible(renderer)==false)
{
m_UnselectedActor->VisibilityOff();
m_SelectedActor->VisibilityOff();
m_ContourActor->VisibilityOff();
return;
}
bool showPoints = true;
this->GetDataNode()->GetBoolProperty("show points", showPoints);
if(showPoints)
{
m_UnselectedActor->VisibilityOn();
m_SelectedActor->VisibilityOn();
}
else
{
m_UnselectedActor->VisibilityOff();
m_SelectedActor->VisibilityOff();
}
if(dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("opacity")) != NULL)
{
mitk::FloatProperty::Pointer pointOpacity =dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("opacity"));
float opacity = pointOpacity->GetValue();
m_ContourActor->GetProperty()->SetOpacity(opacity);
m_UnselectedActor->GetProperty()->SetOpacity(opacity);
m_SelectedActor->GetProperty()->SetOpacity(opacity);
}
bool makeContour = false;
this->GetDataNode()->GetBoolProperty("show contour", makeContour);
if (makeContour)
{
m_ContourActor->VisibilityOn();
}
else
{
m_ContourActor->VisibilityOff();
}
}
void mitk::PointSetVtkMapper3D::ResetMapper( BaseRenderer* /*renderer*/ )
{
m_PointsAssembly->VisibilityOff();
}
vtkProp* mitk::PointSetVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/)
{
return m_PointsAssembly;
}
void mitk::PointSetVtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer * /*renderer*/)
{
vtkSmartPointer<vtkLinearTransform> vtktransform =
this->GetDataNode()->GetVtkTransform(this->GetTimestep());
m_SelectedActor->SetUserTransform(vtktransform);
m_UnselectedActor->SetUserTransform(vtktransform);
m_ContourActor->SetUserTransform(vtktransform);
}
void mitk::PointSetVtkMapper3D::ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer)
{
Superclass::ApplyProperties(actor,renderer);
//check for color props and use it for rendering of selected/unselected points and contour
//due to different params in VTK (double/float) we have to convert!
//vars to convert to
vtkFloatingPointType unselectedColor[4]={1.0f,1.0f,0.0f,1.0f};//yellow
vtkFloatingPointType selectedColor[4]={1.0f,0.0f,0.0f,1.0f};//red
vtkFloatingPointType contourColor[4]={1.0f,0.0f,0.0f,1.0f};//red
//different types for color!!!
mitk::Color tmpColor;
double opacity = 1.0;
//check if there is an unselected property
if (dynamic_cast<mitk::ColorProperty*>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor")) != NULL)
{
tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("unselectedcolor"))->GetValue();
unselectedColor[0] = tmpColor[0];
unselectedColor[1] = tmpColor[1];
unselectedColor[2] = tmpColor[2];
unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value
}
else if (dynamic_cast<mitk::ColorProperty*>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor")) != NULL)
{
tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("unselectedcolor"))->GetValue();
unselectedColor[0] = tmpColor[0];
unselectedColor[1] = tmpColor[1];
unselectedColor[2] = tmpColor[2];
unselectedColor[3] = 1.0f; //!!define a new ColorProp to be able to pass alpha value
}
else
{
//check if the node has a color
float unselectedColorTMP[4]={1.0f,1.0f,0.0f,1.0f};//yellow
m_DataNode->GetColor(unselectedColorTMP, NULL);
unselectedColor[0] = unselectedColorTMP[0];
unselectedColor[1] = unselectedColorTMP[1];
unselectedColor[2] = unselectedColorTMP[2];
//unselectedColor[3] stays 1.0f
}
//get selected property
if (dynamic_cast<mitk::ColorProperty*>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL)
{
tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue();
selectedColor[0] = tmpColor[0];
selectedColor[1] = tmpColor[1];
selectedColor[2] = tmpColor[2];
selectedColor[3] = 1.0f;
}
else if (dynamic_cast<mitk::ColorProperty*>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL)
{
tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue();
selectedColor[0] = tmpColor[0];
selectedColor[1] = tmpColor[1];
selectedColor[2] = tmpColor[2];
selectedColor[3] = 1.0f;
}
//get contour property
if (dynamic_cast<mitk::ColorProperty*>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL)
{
tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue();
contourColor[0] = tmpColor[0];
contourColor[1] = tmpColor[1];
contourColor[2] = tmpColor[2];
contourColor[3] = 1.0f;
}
else if (dynamic_cast<mitk::ColorProperty*>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL)
{
tmpColor = dynamic_cast<mitk::ColorProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue();
contourColor[0] = tmpColor[0];
contourColor[1] = tmpColor[1];
contourColor[2] = tmpColor[2];
contourColor[3] = 1.0f;
}
if(dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity")) != NULL)
{
mitk::FloatProperty::Pointer pointOpacity =dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("opacity"));
opacity = pointOpacity->GetValue();
}
else if(dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity")) != NULL)
{
mitk::FloatProperty::Pointer pointOpacity =dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("opacity"));
opacity = pointOpacity->GetValue();
}
//finished color / opacity fishing!
//check if a contour shall be drawn
bool makeContour = false;
this->GetDataNode()->GetBoolProperty("show contour", makeContour, renderer);
int visibleBefore = m_ContourActor->GetVisibility();
if(makeContour && (m_ContourActor != NULL) )
{
if ( visibleBefore == 0)
{//was not visible before, so create it.
this->CreateContour(renderer);
}
m_ContourActor->GetProperty()->SetColor(contourColor);
m_ContourActor->GetProperty()->SetOpacity(opacity);
}
m_SelectedActor->GetProperty()->SetColor(selectedColor);
m_SelectedActor->GetProperty()->SetOpacity(opacity);
m_UnselectedActor->GetProperty()->SetColor(unselectedColor);
m_UnselectedActor->GetProperty()->SetOpacity(opacity);
}
void mitk::PointSetVtkMapper3D::CreateContour(mitk::BaseRenderer* renderer)
{
vtkSmartPointer<vtkAppendPolyData> vtkContourPolyData = vtkSmartPointer<vtkAppendPolyData>::New();
vtkSmartPointer<vtkPolyDataMapper> vtkContourPolyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
mitk::PointSet::PointsContainer::Iterator pointsIter;
// mitk::PointSet::PointDataContainer::Iterator pointDataIter;
int j;
// get and update the PointSet
mitk::PointSet::Pointer input = const_cast<mitk::PointSet*>(this->GetInput());
int timestep = this->GetTimestep();
mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep );
if ( itkPointSet.GetPointer() == NULL)
{
return;
}
for (j=0, pointsIter=itkPointSet->GetPoints()->Begin(); pointsIter!=itkPointSet->GetPoints()->End() ; pointsIter++,j++)
{
vtkIdType cell[2] = {j-1,j};
itk::Point<float> point1 = pointsIter->Value();
points->InsertPoint(j,point1[0],point1[1],point1[2]);
if (j>0)
polys->InsertNextCell(2,cell);
}
bool close;
if (dynamic_cast<mitk::BoolProperty *>(this->GetDataNode()->GetPropertyList()->GetProperty("close contour"), renderer) == NULL)
close = false;
else
close = dynamic_cast<mitk::BoolProperty *>(this->GetDataNode()->GetPropertyList()->GetProperty("close contour"), renderer)->GetValue();
if (close)
{
vtkIdType cell[2] = {j-1,0};
polys->InsertNextCell(2,cell);
}
vtkSmartPointer<vtkPolyData> contour = vtkSmartPointer<vtkPolyData>::New();
contour->SetPoints(points);
contour->SetLines(polys);
contour->Update();
vtkSmartPointer<vtkTubeFilter> tubeFilter = vtkSmartPointer<vtkTubeFilter>::New();
tubeFilter->SetNumberOfSides( 12 );
tubeFilter->SetInput(contour);
//check for property contoursize.
m_ContourRadius = 0.5;
mitk::FloatProperty::Pointer contourSizeProp = dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("contoursize") );
if (contourSizeProp.IsNotNull())
m_ContourRadius = contourSizeProp->GetValue();
tubeFilter->SetRadius( m_ContourRadius );
tubeFilter->Update();
//add to pipeline
vtkContourPolyData->AddInput(tubeFilter->GetOutput());
vtkContourPolyDataMapper->SetInput(vtkContourPolyData->GetOutput());
m_ContourActor->SetMapper(vtkContourPolyDataMapper);
m_PointsAssembly->AddPart(m_ContourActor);
}
void mitk::PointSetVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite );
node->AddProperty( "pointsize", mitk::FloatProperty::New(1.0), renderer, overwrite);
node->AddProperty( "selectedcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite); //red
node->AddProperty( "color", mitk::ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite); //yellow
node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite );
node->AddProperty( "contourcolor", mitk::ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite);
node->AddProperty( "contoursize", mitk::FloatProperty::New(0.5), renderer, overwrite );
node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite );
node->AddProperty( "updateDataOnRender", mitk::BoolProperty::New(true), renderer, overwrite );
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper3D.h b/Core/Code/Rendering/mitkPointSetVtkMapper3D.h
index 929c1b5c6c..ca748b2305 100644
--- a/Core/Code/Rendering/mitkPointSetVtkMapper3D.h
+++ b/Core/Code/Rendering/mitkPointSetVtkMapper3D.h
@@ -1,153 +1,152 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273
#define MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273
#include <MitkExports.h>
#include "mitkVtkMapper3D.h"
#include "mitkBaseRenderer.h"
#include <vtkSmartPointer.h>
class vtkActor;
class vtkPropAssembly;
class vtkAppendPolyData;
class vtkPolyData;
class vtkTubeFilter;
class vtkPolyDataMapper;
namespace mitk {
class PointSet;
/**
* @brief Vtk-based mapper for PointSet
*
* Due to the need of different colors for selected
* and unselected points and the facts, that we also have a contour and
* labels for the points, the vtk structure is build up the following way:
*
* We have two AppendPolyData, one selected, and one unselected and one
* for a contour between the points. Each one is connected to an own
* PolyDaraMapper and an Actor. The different color for the unselected and
* selected state and for the contour is read from properties.
*
* "unselectedcolor", "selectedcolor" and "contourcolor" are the strings,
* that are looked for. Pointlabels are added besides the selected or the
* deselected points.
*
* Then the three Actors are combined inside a vtkPropAssembly and this
* object is returned in GetProp() and so hooked up into the rendering
* pipeline.
* Properties that can be set for point sets and influence the PointSetVTKMapper3D are:
*
* - \b "color": (ColorProperty*) Color of the point set
* - \b "Opacity": (FloatProperty) Opacity of the point set
* - \b "show contour": (BoolProperty) If the contour of the points are visible
* - \b "contourSizeProp":(FloatProperty) Contour size of the points
The default properties are:
* - \b "line width": (IntProperty::New(2), renderer, overwrite )
* - \b "pointsize": (FloatProperty::New(1.0), renderer, overwrite)
* - \b "selectedcolor": (ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite) //red
* - \b "color": (ColorProperty::New(1.0f, 1.0f, 0.0f), renderer, overwrite) //yellow
* - \b "show contour": (BoolProperty::New(false), renderer, overwrite )
* - \b "contourcolor": (ColorProperty::New(1.0f, 0.0f, 0.0f), renderer, overwrite)
* - \b "contoursize": (FloatProperty::New(0.5), renderer, overwrite )
* - \b "close contour": (BoolProperty::New(false), renderer, overwrite )
* - \b "show points": (BoolProperty::New(true), renderer, overwrite )
* - \b "updateDataOnRender": (BoolProperty::New(true), renderer, overwrite )
*Other properties looked for are:
*
* - \b "show contour": if set to on, lines between the points are shown
* - \b "close contour": if set to on, the open strip is closed (first point
* connected with last point)
* - \b "pointsize": size of the points mapped
* - \b "label": text of the Points to show besides points
* - \b "contoursize": size of the contour drawn between the points
* (if not set, the pointsize is taken)
*
* @ingroup Mapper
*/
class MITK_CORE_EXPORT PointSetVtkMapper3D : public VtkMapper3D
{
public:
mitkClassMacro(PointSetVtkMapper3D, VtkMapper3D);
itkNewMacro(Self);
virtual const mitk::PointSet* GetInput();
//overwritten from VtkMapper3D to be able to return a
//m_PointsAssembly which is much faster than a vtkAssembly
virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer);
virtual void UpdateVtkTransform(mitk::BaseRenderer* renderer);
static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false);
void ReleaseGraphicsResources(vtkWindow *renWin);
protected:
PointSetVtkMapper3D();
virtual ~PointSetVtkMapper3D();
virtual void GenerateData();
virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer);
virtual void ResetMapper( BaseRenderer* renderer );
virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer);
virtual void CreateContour(mitk::BaseRenderer* renderer);
virtual void CreateVTKRenderObjects();
vtkSmartPointer<vtkAppendPolyData> m_vtkSelectedPointList;
vtkSmartPointer<vtkAppendPolyData> m_vtkUnselectedPointList;
vtkSmartPointer<vtkPolyDataMapper> m_VtkSelectedPolyDataMapper;
vtkSmartPointer<vtkPolyDataMapper> m_VtkUnselectedPolyDataMapper;
vtkSmartPointer<vtkActor> m_SelectedActor;
vtkSmartPointer<vtkActor> m_UnselectedActor;
vtkSmartPointer<vtkActor> m_ContourActor;
vtkSmartPointer<vtkPropAssembly> m_PointsAssembly;
//help for contour between points
vtkSmartPointer<vtkAppendPolyData> m_vtkTextList;
//variables to be able to log, how many inputs have been added to PolyDatas
unsigned int m_NumberOfSelectedAdded;
unsigned int m_NumberOfUnselectedAdded;
//variables to check if an update of the vtk objects is needed
ScalarType m_PointSize;
ScalarType m_ContourRadius;
};
} // namespace mitk
#endif /* MITKPointSetVtkMAPPER3D_H_HEADER_INCLUDED_C1907273 */
diff --git a/Core/Code/Rendering/mitkPolyDataGLMapper2D.cpp b/Core/Code/Rendering/mitkPolyDataGLMapper2D.cpp
index af696cda42..92eeefb8a1 100644
--- a/Core/Code/Rendering/mitkPolyDataGLMapper2D.cpp
+++ b/Core/Code/Rendering/mitkPolyDataGLMapper2D.cpp
@@ -1,275 +1,274 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkGL.h>
#include "mitkPolyDataGLMapper2D.h"
#include "mitkBaseRenderer.h"
#include "mitkPlaneGeometry.h"
#include "mitkSurface.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkAbstractTransformGeometry.h"
#include "mitkVtkMapper3D.h"
#include <vtkPolyData.h>
#include <vtkPolyDataSource.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkLookupTable.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDataArray.h>
#include <vtkPolyData.h>
#include <vtkLinearTransform.h>
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkScalarsToColors.h>
#include <itkProcessObject.h>
void mitk::PolyDataGLMapper2D::Paint( mitk::BaseRenderer * renderer )
{
if ( IsVisible( renderer ) == false )
return ;
// ok, das ist aus GenerateData kopiert
mitk::BaseData::Pointer input = const_cast<mitk::BaseData*>( GetData() );
assert( input );
input->Update();
vtkPolyData * vtkpolydata = this->GetVtkPolyData();
assert( vtkpolydata );
vtkLinearTransform * vtktransform = GetDataNode() ->GetVtkTransform();
if (vtktransform)
{
vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();
Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() );
if ( vtkpolydata != NULL )
{
Point3D point;
Vector3D normal;
if(worldPlaneGeometry.IsNotNull())
{
// set up vtkPlane according to worldGeometry
point=worldPlaneGeometry->GetOrigin();
normal=worldPlaneGeometry->GetNormal(); normal.Normalize();
m_Plane->SetTransform((vtkAbstractTransform*)NULL);
}
else
{
//@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"?
return;
AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldGeometry2D());
if(worldAbstractGeometry.IsNotNull())
{
// set up vtkPlane according to worldGeometry
point=const_cast<mitk::BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum();
FillVector3D(normal, 0, 0, 1);
m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse());
}
else
return;
}
vtkFloatingPointType vp[ 3 ], vnormal[ 3 ];
vnl2vtk(point.Get_vnl_vector(), vp);
vnl2vtk(normal.Get_vnl_vector(), vnormal);
//normally, we would need to transform the surface and cut the transformed surface with the cutter.
//This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
//@todo It probably does not work for scaling operations yet:scaling operations have to be
//dealed with after the cut is performed by scaling the contour.
inversetransform->TransformPoint( vp, vp );
inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal );
m_Plane->SetOrigin( vp );
m_Plane->SetNormal( vnormal );
// set data into cutter
m_Cutter->SetInput( vtkpolydata );
// m_Cutter->GenerateCutScalarsOff();
// m_Cutter->SetSortByToSortByCell();
// calculate the cut
m_Cutter->Update();
// fetch geometry
mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
assert( displayGeometry );
// float toGL=displayGeometry->GetSizeInDisplayUnits()[1];
//apply color and opacity read from the PropertyList
ApplyProperties( renderer );
// traverse the cut contour
vtkPolyData * contour = m_Cutter->GetOutput();
vtkPoints *vpoints = contour->GetPoints();
vtkCellArray *vpolys = contour->GetLines();
vtkPointData *vpointdata = contour->GetPointData();
vtkDataArray* vscalars = vpointdata->GetScalars();
vtkCellData *vcelldata = contour->GetCellData();
vtkDataArray* vcellscalars = vcelldata->GetScalars();
int i, numberOfCells = vpolys->GetNumberOfCells();
Point3D p;
Point2D p2d, last, first;
vpolys->InitTraversal();
vtkScalarsToColors* lut = GetVtkLUT();
assert ( lut != NULL );
for ( i = 0;i < numberOfCells;++i )
{
vtkIdType *cell(NULL);
vtkIdType cellSize(0);
vpolys->GetNextCell( cellSize, cell );
if ( m_ColorByCellData )
{ // color each cell according to cell data
vtkFloatingPointType* color = lut->GetColor( vcellscalars->GetComponent( i, 0 ) );
glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
}
if ( m_ColorByPointData )
{
vtkFloatingPointType* color = lut->GetColor( vscalars->GetComponent( cell[0], 0 ) );
glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
}
glBegin ( GL_LINE_LOOP );
for ( int j = 0;j < cellSize;++j )
{
vpoints->GetPoint( cell[ j ], vp );
//take transformation via vtktransform into account
vtktransform->TransformPoint( vp, vp );
vtk2itk( vp, p );
//convert 3D point (in mm) to 2D point on slice (also in mm)
worldGeometry->Map( p, p2d );
//convert point (until now mm and in worldcoordinates) to display coordinates (units )
displayGeometry->WorldToDisplay( p2d, p2d );
//convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left )
//p2d[1]=toGL-p2d[1];
//add the current vertex to the line
glVertex2f( p2d[0], p2d[1] );
}
glEnd ();
}
}
}
}
vtkPolyDataMapper* mitk::PolyDataGLMapper2D::GetVtkPolyDataMapper()
{
return NULL;
/*
mitk::DataNode::ConstPointer node = this->GetDataNode();
if ( node.IsNull() )
return NULL;
mitk::VtkMapper3D::Pointer mitkMapper = dynamic_cast< mitk::VtkMapper3D* > ( node->GetMapper( 2 ) );
if ( mitkMapper.IsNull() )
return NULL;
mitkMapper->Update(NULL);
vtkActor* actor = dynamic_cast<vtkActor*>( mitkMapper->GetVtkProp(0) );
if ( actor == NULL )
return NULL;
return dynamic_cast<vtkPolyDataMapper*>( actor->GetMapper() );
*/
}
vtkPolyData* mitk::PolyDataGLMapper2D::GetVtkPolyData( )
{
vtkPolyDataMapper * polyDataMapper = GetVtkPolyDataMapper();
if ( polyDataMapper == NULL )
return NULL;
else
return polyDataMapper->GetInput();
}
vtkScalarsToColors* mitk::PolyDataGLMapper2D::GetVtkLUT( )
{
vtkPolyDataMapper * polyDataMapper = GetVtkPolyDataMapper();
if ( polyDataMapper == NULL )
return NULL;
else
return polyDataMapper->GetLookupTable();
}
bool mitk::PolyDataGLMapper2D::IsConvertibleToVtkPolyData()
{
return ( GetVtkPolyDataMapper() != NULL );
}
mitk::PolyDataGLMapper2D::PolyDataGLMapper2D()
{
m_Plane = vtkPlane::New();
m_Cutter = vtkCutter::New();
m_Cutter->SetCutFunction( m_Plane );
m_Cutter->GenerateValues( 1, 0, 1 );
m_ColorByCellData = false;
m_ColorByPointData = false;
//m_LUT = vtkLookupTable::New();
//m_LUT->SetTableRange( 0, 255 );
//m_LUT->SetNumberOfColors( 255 );
//m_LUT->SetRampToLinear ();
//m_LUT->Build();
}
mitk::PolyDataGLMapper2D::~PolyDataGLMapper2D()
{}
diff --git a/Core/Code/Rendering/mitkPolyDataGLMapper2D.h b/Core/Code/Rendering/mitkPolyDataGLMapper2D.h
index 2f1d34be09..bec27067cb 100644
--- a/Core/Code/Rendering/mitkPolyDataGLMapper2D.h
+++ b/Core/Code/Rendering/mitkPolyDataGLMapper2D.h
@@ -1,110 +1,109 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MitkPolyDataGLMapper2D_H
#define MitkPolyDataGLMapper2D_H
#include <MitkExports.h>
#include "mitkGLMapper2D.h"
class vtkCutter;
class vtkPlane;
class vtkLookupTable;
class vtkPolyData;
class vtkScalarsToColors;
class vtkPolyDataMapper;
namespace mitk
{
class BaseRenderer;
/**
* @brief OpenGL-based mapper to display a 2d cut through a poly data
* OpenGL-based mapper to display a 2D cut through a poly data. The result is
* normally a line. This class can be added to any data object, which is
* rendered in 3D via a vtkPolyData.
*/
class MITK_CORE_EXPORT PolyDataGLMapper2D : public GLMapper2D
{
public:
mitkClassMacro( PolyDataGLMapper2D, GLMapper2D );
itkNewMacro( Self );
/**
* Sets if the cut lines are colored by mapping cell data
*/
itkSetMacro( ColorByCellData, bool );
/**
* Sets if the cut lines are colored by mapping point data
*/
itkSetMacro( ColorByPointData, bool );
/**
* Renders a cut through a poly-data by lines.
* @param renderer the render to render in.
*/
virtual void Paint( mitk::BaseRenderer * renderer );
protected:
PolyDataGLMapper2D();
virtual ~PolyDataGLMapper2D();
/**
* Determines, if the associated BaseData is mapped three-dimensionally (mapper-slot id 2)
* with a class convertable to vtkPolyDataMapper().
* @returns NULL if it is not convertable or the appropriate PolyDataMapper otherwise
*/
virtual vtkPolyDataMapper* GetVtkPolyDataMapper();
/**
* Determines the poly data object to be cut.
* returns the poly data if possible, otherwise NULL.
*/
virtual vtkPolyData* GetVtkPolyData( );
/**
* Determines the LookupTable used by the associated vtkMapper.
* returns the LUT if possible, otherwise NULL.
*/
virtual vtkScalarsToColors* GetVtkLUT( );
/**
* Checks if this mapper can be used to generate cuts through the associated
* base data.
* @return true if yes or false if not.
*/
virtual bool IsConvertibleToVtkPolyData();
vtkPlane* m_Plane;
vtkCutter* m_Cutter;
bool m_ColorByCellData;
bool m_ColorByPointData;
};
} // namespace mitk
#endif /* MitkPolyDataGLMapper2D_H */
diff --git a/Core/Code/Rendering/mitkRenderWindow.cpp b/Core/Code/Rendering/mitkRenderWindow.cpp
index cadd2206e0..763a5c8f31 100644
--- a/Core/Code/Rendering/mitkRenderWindow.cpp
+++ b/Core/Code/Rendering/mitkRenderWindow.cpp
@@ -1,89 +1,88 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-07-05 09:49:37 +0200 (Mo, 05 Jul 2010) $
-Version: $Revision: 24298 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRenderWindow.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkVtkLayerController.h"
#include "mitkRenderingManager.h"
#include "vtkRenderer.h"
#include "vtkRenderWindowInteractor.h"
#include "mitkVtkEventProvider.h"
mitk::RenderWindow::RenderWindow(vtkRenderWindow* renWin, const char* name, mitk::RenderingManager* rm )
: m_vtkRenderWindow(renWin)
{
if(m_vtkRenderWindow == NULL)
m_vtkRenderWindow = vtkRenderWindow::New();
if ( m_vtkRenderWindow->GetSize()[0] <= 10
|| m_vtkRenderWindow->GetSize()[0] <= 10 )
{
m_vtkRenderWindow->SetSize( 100, 100 );
}
m_vtkRenderWindowInteractor = vtkRenderWindowInteractor::New();
m_vtkRenderWindowInteractor->SetRenderWindow(m_vtkRenderWindow);
m_vtkRenderWindowInteractor->Initialize();
// initialize from RenderWindowBase
Initialize(rm,name);
m_vtkMitkEventProvider = vtkEventProvider::New();
m_vtkMitkEventProvider->SetInteractor(this->GetVtkRenderWindowInteractor());
m_vtkMitkEventProvider->SetMitkRenderWindow(this);
m_vtkMitkEventProvider->SetEnabled(1);
}
mitk::RenderWindow::~RenderWindow()
{
Destroy();
m_vtkRenderWindow->Delete();
m_vtkRenderWindowInteractor->Delete();
m_vtkMitkEventProvider->Delete();
}
vtkRenderWindow* mitk::RenderWindow::GetVtkRenderWindow()
{
return m_vtkRenderWindow;
}
vtkRenderWindowInteractor* mitk::RenderWindow::GetVtkRenderWindowInteractor()
{
return m_vtkRenderWindowInteractor;
}
void mitk::RenderWindow::SetSize( int width, int height )
{
this->GetVtkRenderWindow()->SetSize( width, height );
this->resizeMitkEvent( width, height );
}
void mitk::RenderWindow::ReinitEventProvider()
{
m_vtkMitkEventProvider->SetEnabled(0);
m_vtkMitkEventProvider->SetInteractor(this->GetVtkRenderWindowInteractor());
m_vtkMitkEventProvider->SetMitkRenderWindow(this);
m_vtkMitkEventProvider->SetEnabled(1);
}
diff --git a/Core/Code/Rendering/mitkRenderWindow.h b/Core/Code/Rendering/mitkRenderWindow.h
index 565050075b..ed45237fcd 100644
--- a/Core/Code/Rendering/mitkRenderWindow.h
+++ b/Core/Code/Rendering/mitkRenderWindow.h
@@ -1,108 +1,107 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-06-30 15:12:34 +0200 (Mi, 30. Jun 2010) $
-Version: $Revision: 24176 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66ASDF
#define MITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66ASDF
#include <MitkExports.h>
#include "mitkRenderWindowBase.h"
namespace mitk
{
class vtkEventProvider;
/**
* \brief mitkRenderWindow integrates the MITK rendering mechanism into VTK and
* is NOT QT dependent
*
*
* \ingroup Renderer
*/
class MITK_CORE_EXPORT RenderWindow: public mitk::RenderWindowBase, public itk::Object
{
public:
mitkClassMacro(RenderWindow, itk::Object);
itkNewMacro(Self);
mitkNewMacro1Param(Self, vtkRenderWindow*);
mitkNewMacro2Param(Self, vtkRenderWindow*, const char*);
mitkNewMacro3Param(Self, vtkRenderWindow*, const char*, mitk::RenderingManager*);
virtual ~RenderWindow();
virtual vtkRenderWindow* GetVtkRenderWindow();
virtual vtkRenderWindowInteractor* GetVtkRenderWindowInteractor();
// Set Layout Index to define the Layout Type
void SetLayoutIndex( unsigned int layoutIndex );
// Get Layout Index to define the Layout Type
unsigned int GetLayoutIndex();
//MenuWidget need to update the Layout Design List when Layout had changed
void LayoutDesignListChanged( int layoutDesignIndex );
void FullScreenMode( bool state );
/**
* \brief Convenience method to set the size of an mitkRenderWindow.
*
* This method sets the size of the vtkRenderWindow and tells the
* rendering that the size has changed -> adapts displayGeometry, etc.
*/
void SetSize( int width, int height );
/**
* \brief Initializes the mitkVtkEventProvider to listen to the
* currently used vtkInteractorStyle.
*
* This method makes sure that the internal mitkVtkEventProvider
* listens to the correct vtkInteractorStyle.
* This makes sure that VTK-Events are correctly translated into
* MITK-Events.
*
* \warn This method needs to be called MANUALLY as soon as the MapperID
* for this RenderWindow is changed or the vtkInteractorStyle is modified
* somehow else!
*/
void ReinitEventProvider();
protected:
RenderWindow(vtkRenderWindow * existingRenderWindow = NULL , const char* name = "unnamed renderer", mitk::RenderingManager* rm = NULL );
void ResetView();
vtkRenderWindow * m_vtkRenderWindow;
vtkRenderWindowInteractor * m_vtkRenderWindowInteractor;
vtkEventProvider * m_vtkMitkEventProvider;
private:
};
} //namespace
#endif /* MITKRENDERWINDOW_H_HEADER_INCLUDED_C1C40D66ASDF */
diff --git a/Core/Code/Rendering/mitkRenderWindowBase.cpp b/Core/Code/Rendering/mitkRenderWindowBase.cpp
index 99c2ce1dc4..9301f68c2e 100644
--- a/Core/Code/Rendering/mitkRenderWindowBase.cpp
+++ b/Core/Code/Rendering/mitkRenderWindowBase.cpp
@@ -1,209 +1,208 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-07-05 09:49:37 +0200 (Mo, 05 Jul 2010) $
-Version: $Revision: 24298 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRenderWindowBase.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkVtkLayerController.h"
#include "mitkRenderingManager.h"
#include "vtkRenderer.h"
mitk::RenderWindowBase::RenderWindowBase( )
: m_ProcessWheelEvents(true),
m_InvertScrollingDirection(false)
{
}
/*
* "Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). When a
* virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data member) or from
* a destructor, and the object to which the call applies is the object under construction or destruction, the function called is
* the one defined in the constructor or destructor’s own class or in one of its bases, but not a function overriding it in a class
* derived from the constructor or destructor’s class, or overriding it in one of the other base classes of the most derived object[..]"
* or short: within constructors and destructors classes are not polymorph.
*/
void mitk::RenderWindowBase::Initialize( mitk::RenderingManager* renderingManager, const char* name )
{
if ( renderingManager == NULL )
{
renderingManager = mitk::RenderingManager::GetInstance();
}
if(m_Renderer.IsNull())
{
m_Renderer = mitk::VtkPropRenderer::New( name , GetVtkRenderWindow(), renderingManager );
}
m_Renderer->InitRenderer(this->GetVtkRenderWindow());
mitk::BaseRenderer::AddInstance(GetVtkRenderWindow(),m_Renderer);
renderingManager->AddRenderWindow(GetVtkRenderWindow());
m_RenderProp = vtkMitkRenderProp::New();
m_RenderProp->SetPropRenderer(m_Renderer);
m_Renderer->GetVtkRenderer()->AddViewProp(m_RenderProp);
if((this->GetVtkRenderWindow()->GetSize()[0] > 10)
&& (this->GetVtkRenderWindow()->GetSize()[1] > 10))
m_Renderer->InitSize(this->GetVtkRenderWindow()->GetSize()[0], this->GetVtkRenderWindow()->GetSize()[1]);
m_InResize = false;
}
void mitk::RenderWindowBase::Destroy()
{
m_Renderer->GetRenderingManager()->RemoveRenderWindow(GetVtkRenderWindow());
mitk::BaseRenderer::RemoveInstance(GetVtkRenderWindow());
m_Renderer->GetVtkRenderer()->RemoveViewProp(m_RenderProp);
m_RenderProp->Delete();
}
mitk::RenderWindowBase::~RenderWindowBase()
{
}
void mitk::RenderWindowBase::mousePressMitkEvent(mitk::MouseEvent *me)
{
if (m_Renderer.IsNotNull())
m_Renderer->MousePressEvent(me);
}
void mitk::RenderWindowBase::mouseReleaseMitkEvent(mitk::MouseEvent *me)
{
if(m_Renderer.IsNotNull())
m_Renderer->MouseReleaseEvent(me);
}
void mitk::RenderWindowBase::mouseMoveMitkEvent(mitk::MouseEvent *me)
{
if (m_Renderer.IsNotNull())
m_Renderer->MouseMoveEvent(me);
}
void mitk::RenderWindowBase::wheelMitkEvent(mitk::WheelEvent *we)
{
if ( !m_ProcessWheelEvents )
{
if(m_Renderer.IsNotNull())
m_Renderer->WheelEvent(we);
return;
}
if ( !GetSliceNavigationController()->GetSliceLocked() )
{
mitk::Stepper* stepper = GetSliceNavigationController()->GetSlice();
if (stepper->GetSteps() <= 1)
{
stepper = GetSliceNavigationController()->GetTime();
}
// get the desired delta
int delta = we->GetDelta();
if ( m_InvertScrollingDirection )
delta *= -1; // If we want to invert the scrolling direction -> delta * -1
if ( delta < 0 )
{
stepper->Next();
}
else
{
stepper->Previous();
}
//also send to Renderer to send if to MITK interaction mechanism
if(m_Renderer.IsNotNull())
m_Renderer->WheelEvent(we);
}
}
void mitk::RenderWindowBase::keyPressMitkEvent(mitk::KeyEvent* mke)
{
if (m_Renderer.IsNotNull())
m_Renderer->KeyPressEvent(mke);
}
void mitk::RenderWindowBase::resizeMitkEvent(int width, int height)
{
if(m_InResize) //@FIXME CRITICAL probably related to VtkSizeBug
return;
m_InResize = true;
if(m_Renderer.IsNotNull())
{
m_Renderer->Resize(width, height);
}
m_InResize = false;
}
mitk::SliceNavigationController * mitk::RenderWindowBase::GetSliceNavigationController()
{
return mitk::BaseRenderer::GetInstance(this->GetVtkRenderWindow())->GetSliceNavigationController();
}
mitk::CameraRotationController * mitk::RenderWindowBase::GetCameraRotationController()
{
return mitk::BaseRenderer::GetInstance(this->GetVtkRenderWindow())->GetCameraRotationController();
}
mitk::BaseController * mitk::RenderWindowBase::GetController()
{
mitk::BaseRenderer * renderer = mitk::BaseRenderer::GetInstance(GetVtkRenderWindow());
switch ( renderer->GetMapperID() )
{
case mitk::BaseRenderer::Standard2D:
return GetSliceNavigationController();
case mitk::BaseRenderer::Standard3D:
return GetCameraRotationController();
default:
return GetSliceNavigationController();
}
}
mitk::VtkPropRenderer* mitk::RenderWindowBase::GetRenderer()
{
return m_Renderer;
}
void mitk::RenderWindowBase::SetProcessWheelEvents( bool state )
{
m_ProcessWheelEvents = state;
}
bool mitk::RenderWindowBase::GetProcessWheelEvents()
{
return m_ProcessWheelEvents;
}
void mitk::RenderWindowBase::SetInvertScrollingDirection( bool invert )
{
m_InvertScrollingDirection = invert;
}
diff --git a/Core/Code/Rendering/mitkRenderWindowBase.h b/Core/Code/Rendering/mitkRenderWindowBase.h
index 46de2865a6..0828ae6131 100644
--- a/Core/Code/Rendering/mitkRenderWindowBase.h
+++ b/Core/Code/Rendering/mitkRenderWindowBase.h
@@ -1,101 +1,100 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-06-30 15:12:34 +0200 (Mi, 30. Jun 2010) $
-Version: $Revision: 24176 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKRENDERWINDOWBASE_H_HEADER_INCLUDED_C1C40D66ASDF
#define MITKRENDERWINDOWBASE_H_HEADER_INCLUDED_C1C40D66ASDF
#include <MitkExports.h>
#include "mitkVtkPropRenderer.h"
#include "vtkMitkRenderProp.h"
#include "mitkSliceNavigationController.h"
#include "mitkCameraRotationController.h"
namespace mitk
{
/**
* \brief Base class of MITK RenderWindows
*
* This class sets up the MITK rendering mechanism and it's integration into VTK.
*
* Currently, there are two specific implementations of this abstract class:
* QmitkRenderWindow, inerhits from the QVTKWidget and is the matured way for MITK rendering
* mitkRenderWindow is a new, QT-independent RenderWindow implementation
*
* \ingroup Renderer
*/
class MITK_CORE_EXPORT RenderWindowBase
{
public:
//mitkClassMacro(RenderWindowBase,itk::Object);
//itkNewMacro(Self);
virtual ~RenderWindowBase();
void InitRenderer();
virtual mitk::SliceNavigationController * GetSliceNavigationController();
virtual mitk::CameraRotationController * GetCameraRotationController();
virtual mitk::BaseController * GetController();
virtual mitk::VtkPropRenderer* GetRenderer();
virtual vtkRenderWindow* GetVtkRenderWindow() = 0;
virtual vtkRenderWindowInteractor* GetVtkRenderWindowInteractor() = 0;
void SetProcessWheelEvents( bool state );
bool GetProcessWheelEvents();
void SetInvertScrollingDirection( bool );
virtual void mousePressMitkEvent(mitk::MouseEvent *me);
virtual void mouseReleaseMitkEvent(mitk::MouseEvent *me);
virtual void mouseMoveMitkEvent(mitk::MouseEvent *me);
virtual void wheelMitkEvent(mitk::WheelEvent *we);
virtual void keyPressMitkEvent(mitk::KeyEvent* mke);
virtual void resizeMitkEvent(int width, int height);
protected:
RenderWindowBase();
// helper functions: within constructors and destructors classes are not polymorph.
void Initialize( mitk::RenderingManager* renderingManager = NULL, const char* name = "unnamed renderer" );
void Destroy();
mitk::VtkPropRenderer::Pointer m_Renderer;
vtkMitkRenderProp* m_RenderProp;
bool m_InResize;
bool m_ProcessWheelEvents;
bool m_InvertScrollingDirection;
private:
};
}
#endif /* MITKRENDERWINDOWBASE_H_HEADER_INCLUDED_C1C40D66ASDF */
diff --git a/Core/Code/Rendering/mitkRenderWindowFrame.cpp b/Core/Code/Rendering/mitkRenderWindowFrame.cpp
index e3068771b8..a02faf37f5 100644
--- a/Core/Code/Rendering/mitkRenderWindowFrame.cpp
+++ b/Core/Code/Rendering/mitkRenderWindowFrame.cpp
@@ -1,151 +1,150 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: $
-Version: $Revision: $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRenderWindowFrame.h"
#include "mitkVtkLayerController.h"
#include <mitkStandardFileLocations.h>
#include <mitkConfig.h>
#include <itkObject.h>
#include <itkMacro.h>
#include <itksys/SystemTools.hxx>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkObjectFactory.h>
#include <vtkConfigure.h>
#include <vtkMitkRectangleProp.h>
mitk::RenderWindowFrame::RenderWindowFrame()
{
m_RenderWindow = NULL;
m_RectangleRenderer = vtkRenderer::New();
m_IsEnabled = false;
}
mitk::RenderWindowFrame::~RenderWindowFrame()
{
if ( m_RenderWindow != NULL )
if ( this->IsEnabled() )
this->Disable();
if ( m_RectangleRenderer != NULL )
m_RectangleRenderer->Delete();
}
/**
* Sets the renderwindow, in which the text
* will be shown. Make sure, you have called this function
* before calling Enable()
*/
void mitk::RenderWindowFrame::SetRenderWindow( vtkRenderWindow* renderWindow )
{
m_RenderWindow = renderWindow;
}
/**
* Returns the vtkRenderWindow, which is used
* for displaying the text
*/
vtkRenderWindow* mitk::RenderWindowFrame::GetRenderWindow()
{
return m_RenderWindow;
}
/**
* Returns the renderer responsible for
* rendering the text into the
* vtkRenderWindow
*/
vtkRenderer* mitk::RenderWindowFrame::GetVtkRenderer()
{
return m_RectangleRenderer;
}
/**
* Disables drawing of the text label collection.
* If you want to enable it, call the Enable() function.
*/
void mitk::RenderWindowFrame::Disable()
{
if ( this->IsEnabled())
{
m_RectangleRenderer->EraseOn();
mitk::VtkLayerController::GetInstance(m_RenderWindow)->RemoveRenderer(m_RectangleRenderer);
m_IsEnabled = false;
}
}
/**
* Enables drawing of the text label collection.
* If you want to disable it, call the Disable() function.
*/
void mitk::RenderWindowFrame::Enable(float col1, float col2, float col3)
{
vtkMitkRectangleProp* rect = vtkMitkRectangleProp::New();
rect->SetRenderWindow(m_RenderWindow);
rect->SetColor(col1, col2, col3);
m_RectangleRenderer->AddViewProp(rect);
rect->Delete();
if(!mitk::VtkLayerController::GetInstance(m_RenderWindow)->IsRendererInserted( m_RectangleRenderer ))
{
m_RectangleRenderer->EraseOff();
m_RectangleRenderer->SetInteractive(0);
mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertForegroundRenderer(m_RectangleRenderer,true);
m_IsEnabled = true;
}
}
/**
* Checks, if the text is currently
* enabled (visible)
*/
bool mitk::RenderWindowFrame::IsEnabled()
{
return m_IsEnabled;
}
void mitk::RenderWindowFrame::SetRequestedRegionToLargestPossibleRegion()
{
//nothing to do
}
bool mitk::RenderWindowFrame::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::RenderWindowFrame::VerifyRequestedRegion()
{
return true;
}
void mitk::RenderWindowFrame::SetRequestedRegion(itk::DataObject*)
{
//nothing to do
}
diff --git a/Core/Code/Rendering/mitkRenderWindowFrame.h b/Core/Code/Rendering/mitkRenderWindowFrame.h
index 900bf7161e..fe1891710c 100644
--- a/Core/Code/Rendering/mitkRenderWindowFrame.h
+++ b/Core/Code/Rendering/mitkRenderWindowFrame.h
@@ -1,133 +1,132 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-07-13 17:30:13 +0200 (Fr, 13 Jul 2007) $
-Version: $Revision: 11283 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/ for details.
+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 the above copyright notices for more information.
+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 _vtk_Colored_Rectangle_Rendering_h_
#define _vtk_Colored_Rectangle_Rendering_h_
#include <vtkSystemIncludes.h>
#include <mitkBaseData.h>
#include <vector>
#include <map>
class vtkRenderer;
class vtkRenderWindow;
class vtkCamera;
class vtkTextProperty;
class vtkTextActor;
namespace mitk {
/**
* This is a simple class for rendering colored rectangles
* at the boarders of vtkRenderWindows.
* The rectangle rendering itself is performed by means of a
* vtkProp (vtkMitkRectangleProp).
* This class instantiates the vtkProp and a corresponding vtkRenderer instance.
*/
class MITK_CORE_EXPORT RenderWindowFrame : public BaseData
{
public:
mitkClassMacro( RenderWindowFrame, BaseData );
itkNewMacro( Self );
/**
* Sets the renderwindow, in which colored rectangle boarders will be shown.
* Make sure, you have called this function
* before calling Enable()
*/
virtual void SetRenderWindow( vtkRenderWindow* renderWindow );
/**
* Enables drawing of the colored rectangle.
* If you want to disable it, call the Disable() function.
*/
virtual void Enable(float col1, float col2, float col3);
/**
* Disables drawing of the colored rectangle.
* If you want to enable it, call the Enable() function.
*/
virtual void Disable();
/**
* Checks, if the text is currently
* enabled (visible)
*/
virtual bool IsEnabled();
/**
* Empty implementation, since the rectangle rendering doesn't
* support the requested region concept
*/
virtual void SetRequestedRegionToLargestPossibleRegion();
/**
* Empty implementation, since the rectangle rendering doesn't
* support the requested region concept
*/
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
/**
* Empty implementation, since the rectangle rendering doesn't
* support the requested region concept
*/
virtual bool VerifyRequestedRegion();
/**
* Empty implementation, since the rectangle rendering doesn't
* support the requested region concept
*/
virtual void SetRequestedRegion(itk::DataObject*);
/**
* Returns the vtkRenderWindow, which is used
* for displaying the text
*/
virtual vtkRenderWindow* GetRenderWindow();
/**
* Returns the renderer responsible for
* rendering the text into the
* vtkRenderWindow
*/
virtual vtkRenderer* GetVtkRenderer();
protected:
/**
* Constructor
*/
RenderWindowFrame();
/**
* Destructor
*/
~RenderWindowFrame();
vtkRenderWindow* m_RenderWindow;
vtkRenderer* m_RectangleRenderer;
bool m_IsEnabled;
};
} //end of namespace mitk
#endif
diff --git a/Core/Code/Rendering/mitkShaderRepository.cpp b/Core/Code/Rendering/mitkShaderRepository.cpp
index 302c9ae79a..c8ea8173e6 100644
--- a/Core/Code/Rendering/mitkShaderRepository.cpp
+++ b/Core/Code/Rendering/mitkShaderRepository.cpp
@@ -1,426 +1,425 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-04-18 12:03:52 +0200 (Sat, 18 Apr 2009) $
-Version: $Revision: 16883 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#define SR_INFO MITK_INFO("shader.repository")
#define SR_WARN MITK_WARN("shader.repository")
#define SR_ERROR MITK_ERROR("shader.repository")
#include "mitkShaderRepository.h"
#include "mitkShaderProperty.h"
#include "mitkProperties.h"
#include <vtkProperty.h>
#include <vtkXMLMaterial.h>
#include <vtkXMLShader.h>
#include <vtkXMLDataElement.h>
#include <itkDirectory.h>
#include <itksys/SystemTools.hxx>
#include "mitkStandardFileLocations.h"
mitk::ShaderRepository::ShaderRepository()
{
LoadShaders();
}
mitk::ShaderRepository::~ShaderRepository()
{
}
mitk::ShaderRepository *mitk::ShaderRepository::GetGlobalShaderRepository()
{
static mitk::ShaderRepository::Pointer i;
if(i.IsNull())
{
i=mitk::ShaderRepository::New();
}
return i;
}
void mitk::ShaderRepository::LoadShaders()
{
itk::Directory::Pointer dir = itk::Directory::New();
std::string mitkLighting = mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderLighting.xml", "Core/Code/Rendering");
std::string dirPath = "./vtk_shader";
if(mitkLighting.size() > 0)
{
// we found the default shader
dirPath = itksys::SystemTools::GetFilenamePath( mitkLighting );
SR_INFO << "found default mitk shader at '" << dirPath << "'";
}
if( dir->Load( dirPath.c_str() ) )
{
int n = dir->GetNumberOfFiles();
for(int r=0;r<n;r++)
{
const char *filename = dir->GetFile( r );
std::string extension = itksys::SystemTools::GetFilenameExtension(filename);
if(extension.compare(".xml")==0)
{
Shader::Pointer element=Shader::New();
element->name = itksys::SystemTools::GetFilenameWithoutExtension(filename);
element->path = dirPath + std::string("/") + element->name + std::string(".xml");
SR_INFO << "found shader '" << element->name << "'";
element->LoadPropertiesFromPath();
shaders.push_back(element);
}
}
}
}
void mitk::ShaderRepository::LoadShader(std::string filename)
{
std::string extension = itksys::SystemTools::GetFilenameExtension(filename);
if (extension.compare(".xml")==0)
{
Shader::Pointer element=Shader::New();
element->name = itksys::SystemTools::GetFilenameWithoutExtension(filename);
element->path = filename;
element->LoadPropertiesFromPath();
shaders.push_back(element);
SR_INFO << "found shader '" << element->name << "'";
}
else
{
SR_INFO << "Error: no xml shader file!";
}
}
mitk::ShaderRepository::Shader::Shader()
{
}
mitk::ShaderRepository::Shader::~Shader()
{
}
void mitk::ShaderRepository::Shader::LoadPropertiesFromPath()
{
vtkProperty *p;
p = vtkProperty::New();
p->LoadMaterial(path.c_str());
vtkXMLMaterial *m=p->GetMaterial();
// Vertexshader uniforms
{
vtkXMLShader *s=m->GetVertexShader();
vtkXMLDataElement *x=s->GetRootElement();
int n=x->GetNumberOfNestedElements();
for(int r=0;r<n;r++)
{
vtkXMLDataElement *y=x->GetNestedElement(r);
if(!strcmp(y->GetName(),"ApplicationUniform"))
{
Uniform::Pointer element=Uniform::New();
element->LoadFromXML(y);
uniforms.push_back(element);
}
}
}
// Fragmentshader uniforms
{
vtkXMLShader *s=m->GetFragmentShader();
vtkXMLDataElement *x=s->GetRootElement();
int n=x->GetNumberOfNestedElements();
for(int r=0;r<n;r++)
{
vtkXMLDataElement *y=x->GetNestedElement(r);
if(!strcmp(y->GetName(),"ApplicationUniform"))
{
Uniform::Pointer element=Uniform::New();
element->LoadFromXML(y);
uniforms.push_back(element);
}
}
}
p->Delete();
}
mitk::ShaderRepository::Shader::Uniform::Uniform()
{
}
mitk::ShaderRepository::Shader::Uniform::~Uniform()
{
}
mitk::ShaderRepository::Shader *mitk::ShaderRepository::GetShader(const char *id)
{
std::list<Shader::Pointer>::const_iterator i = shaders.begin();
while( i != shaders.end() )
{
if( (*i)->name.compare(id) == 0)
return (*i);
i++;
}
return 0;
}
void mitk::ShaderRepository::Shader::Uniform::LoadFromXML(vtkXMLDataElement *y)
{
//MITK_INFO << "found uniform '" << y->GetAttribute("name") << "' type=" << y->GetAttribute("type");// << " default=" << y->GetAttribute("value");
name = y->GetAttribute("name");
const char *sType=y->GetAttribute("type");
if(!strcmp(sType,"float"))
type=glsl_float;
else if(!strcmp(sType,"vec2"))
type=glsl_vec2;
else if(!strcmp(sType,"vec3"))
type=glsl_vec3;
else if(!strcmp(sType,"vec4"))
type=glsl_vec4;
else if(!strcmp(sType,"int"))
type=glsl_int;
else if(!strcmp(sType,"ivec2"))
type=glsl_ivec2;
else if(!strcmp(sType,"ivec3"))
type=glsl_ivec3;
else if(!strcmp(sType,"ivec4"))
type=glsl_ivec4;
else
{
type=glsl_none;
SR_WARN << "unknown type for uniform '" << name << "'" ;
}
defaultFloat[0]=defaultFloat[1]=defaultFloat[2]=defaultFloat[3]=0;
/*
const char *sDefault=y->GetAttribute("value");
switch(type)
{
case glsl_float:
sscanf(sDefault,"%f",&defaultFloat[0]);
break;
case glsl_vec2:
sscanf(sDefault,"%f %f",&defaultFloat[0],&defaultFloat[1]);
break;
case glsl_vec3:
sscanf(sDefault,"%f %f %f",&defaultFloat[0],&defaultFloat[1],&defaultFloat[2]);
break;
case glsl_vec4:
sscanf(sDefault,"%f %f %f %f",&defaultFloat[0],&defaultFloat[1],&defaultFloat[2],&defaultFloat[3]);
break;
} */
}
void mitk::ShaderRepository::AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty( "shader", mitk::ShaderProperty::New(), renderer, overwrite );
std::list<Shader::Pointer>::const_iterator i = shaders.begin();
while( i != shaders.end() )
{
std::list<Shader::Uniform::Pointer> *l = (*i)->GetUniforms();
std::string shaderName = (*i)->name;
std::list<Shader::Uniform::Pointer>::const_iterator j = l->begin();
while( j != l->end() )
{
std::string propertyName = "shader." + shaderName + "." + (*j)->name;
switch( (*j)->type )
{
case Shader::Uniform::glsl_float:
node->AddProperty( propertyName.c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_vec2:
node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_vec3:
node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite );
break;
case Shader::Uniform::glsl_vec4:
node->AddProperty( (propertyName+".x").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[0] ), renderer, overwrite );
node->AddProperty( (propertyName+".y").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[1] ), renderer, overwrite );
node->AddProperty( (propertyName+".z").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[2] ), renderer, overwrite );
node->AddProperty( (propertyName+".w").c_str(), mitk::FloatProperty::New( (*j)->defaultFloat[3] ), renderer, overwrite );
break;
default:
break;
}
j++;
}
i++;
}
}
void mitk::ShaderRepository::ApplyProperties(mitk::DataNode* node, vtkActor *actor, mitk::BaseRenderer* renderer,itk::TimeStamp &MTime)
{
bool setMTime = false;
vtkProperty* property = actor->GetProperty();
unsigned long ts = MTime.GetMTime();
mitk::ShaderProperty *sep=(mitk::ShaderProperty *)node->GetProperty("shader",renderer);
if(!sep)
{
property->ShadingOff();
return;
}
std::string shader=sep->GetValueAsString();
// Need update pipeline mode
if(sep->GetMTime() > ts)
{
if(shader.compare("fixed")==0)
{
//MITK_INFO << "disabling shader";
property->ShadingOff();
}
else
{
Shader *s=GetShader(shader.c_str());
if(s)
{
//MITK_INFO << "enabling shader";
property->ShadingOn();
property->LoadMaterial(s->path.c_str());
}
}
setMTime = true;
}
if(shader.compare("fixed")!=0)
{
Shader *s=GetShader(shader.c_str());
if(!s)
return;
std::list<Shader::Uniform::Pointer>::const_iterator j = s->uniforms.begin();
while( j != s->uniforms.end() )
{
std::string propertyName = "shader." + s->name + "." + (*j)->name;
// MITK_INFO << "querying property: " << propertyName;
// mitk::BaseProperty *p = node->GetProperty( propertyName.c_str(), renderer );
// if( p && p->GetMTime() > MTime.GetMTime() )
{
float fval[4];
// MITK_INFO << "copying property " << propertyName << " ->->- " << (*j)->name << " type=" << (*j)->type ;
switch( (*j)->type )
{
case Shader::Uniform::glsl_float:
node->GetFloatProperty( propertyName.c_str(), fval[0], renderer );
property->AddShaderVariable( (*j)->name.c_str(), 1 , fval );
break;
case Shader::Uniform::glsl_vec2:
node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
property->AddShaderVariable( (*j)->name.c_str(), 2 , fval );
break;
case Shader::Uniform::glsl_vec3:
node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer );
property->AddShaderVariable( (*j)->name.c_str(), 3 , fval );
break;
case Shader::Uniform::glsl_vec4:
node->GetFloatProperty( (propertyName+".x").c_str(), fval[0], renderer );
node->GetFloatProperty( (propertyName+".y").c_str(), fval[1], renderer );
node->GetFloatProperty( (propertyName+".z").c_str(), fval[2], renderer );
node->GetFloatProperty( (propertyName+".w").c_str(), fval[3], renderer );
property->AddShaderVariable( (*j)->name.c_str(), 4 , fval );
break;
default:
break;
}
//setMTime=true;
}
j++;
}
}
if(setMTime)
MTime.Modified();
}
diff --git a/Core/Code/Rendering/mitkShaderRepository.h b/Core/Code/Rendering/mitkShaderRepository.h
index cf5321d7cf..de83e5f14e 100644
--- a/Core/Code/Rendering/mitkShaderRepository.h
+++ b/Core/Code/Rendering/mitkShaderRepository.h
@@ -1,167 +1,166 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-08 13:23:19 +0100 (Fri, 08 Feb 2008) $
-Version: $Revision: 13561 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 _MITKSHADERREPOSITORY_H_
#define _MITKSHADERREPOSITORY_H_
#include <MitkExports.h>
#include "itkObject.h"
#include "itkObjectFactory.h"
#include <vtkXMLDataElement.h>
#include "mitkBaseRenderer.h"
#include "mitkDataNode.h"
namespace mitk {
/**
* \brief Management class for vtkShader XML descriptions.
*
* Looks for all XML shader files in a given directory and adds default properties
* for each shader object (shader uniforms) to the specified mitk::DataNode.
*
* Additionally, it provides a utility function for applying properties for shaders
* in mappers.
*/
class MITK_CORE_EXPORT ShaderRepository : public itk::Object
{
public:
mitkClassMacro( ShaderRepository, itk::Object );
itkNewMacro( Self );
static ShaderRepository *GetGlobalShaderRepository();
class Shader : public itk::Object
{
public:
mitkClassMacro( Shader, itk::Object );
itkNewMacro( Self );
class Uniform : public itk::Object
{
public:
mitkClassMacro( Uniform, itk::Object );
itkNewMacro( Self );
enum Type
{
glsl_none,
glsl_float,
glsl_vec2,
glsl_vec3,
glsl_vec4,
glsl_int,
glsl_ivec2,
glsl_ivec3,
glsl_ivec4
};
/**
* Constructor
*/
Uniform();
/**
* Destructor
*/
~Uniform();
Type type;
std::string name;
int defaultInt[4];
float defaultFloat[4];
void LoadFromXML(vtkXMLDataElement *e);
};
std::list<Uniform::Pointer> uniforms;
/**
* Constructor
*/
Shader();
/**
* Destructor
*/
~Shader();
std::string name;
std::string path;
void LoadPropertiesFromPath();
Uniform *GetUniform(char * /*id*/) { return 0; }
std::list<Uniform::Pointer> *GetUniforms()
{
return &uniforms;
}
};
protected:
std::list<Shader::Pointer> shaders;
void LoadShaders();
/**
* Constructor
*/
ShaderRepository();
/**
* Destructor
*/
~ShaderRepository();
public:
std::list<Shader::Pointer> *GetShaders()
{
return &shaders;
}
Shader *GetShader(const char *id);
/** \brief Adds all parsed shader uniforms to property list of the given DataNode;
* used by mappers.
*/
void AddDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite);
/** \brief Applies shader and shader specific variables of the specified DataNode
* to the VTK object by updating the shader variables of its vtkProperty.
*/
void ApplyProperties(mitk::DataNode* node, vtkActor *actor, mitk::BaseRenderer* renderer,itk::TimeStamp &MTime);
/** \brief Loads a shader from a given file. Make sure that this file is in the XML shader format.
*/
void LoadShader(std::string filename);
};
} //end of namespace mitk
#endif
diff --git a/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp b/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp
index d0e2343b99..2c55ae9d3a 100644
--- a/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp
+++ b/Core/Code/Rendering/mitkSurfaceGLMapper2D.cpp
@@ -1,543 +1,542 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkGL.h>
#include "mitkSurfaceGLMapper2D.h"
#include "mitkBaseRenderer.h"
#include "mitkPlaneGeometry.h"
#include "mitkSurface.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkVtkScalarModeProperty.h"
#include "mitkAbstractTransformGeometry.h"
#include "mitkLookupTableProperty.h"
#include <vtkPolyData.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkLookupTable.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDataArray.h>
#include <vtkLinearTransform.h>
#include <vtkAbstractMapper.h>
#include <vtkPKdTree.h>
#include <vtkStripper.h>
mitk::SurfaceGLMapper2D::SurfaceGLMapper2D()
: m_Plane( vtkPlane::New() ),
m_Cutter( vtkCutter::New() ),
m_LUT( vtkLookupTable::New() ),
m_PointLocator( vtkPKdTree::New() ),
m_Stripper( vtkStripper::New() ),
m_DrawNormals(false),
m_FrontNormalLengthInPixels(10.0),
m_BackNormalLengthInPixels(10.0)
{
// default for normals on front side = green
m_FrontSideColor[0] = 0.0;
m_FrontSideColor[1] = 1.0;
m_FrontSideColor[2] = 0.0;
m_FrontSideColor[3] = 1.0;
// default for normals on back side = red
m_BackSideColor[0] = 1.0;
m_BackSideColor[1] = 0.0;
m_BackSideColor[2] = 0.0;
m_BackSideColor[3] = 1.0;
// default for line color = yellow
m_LineColor[0] = 1.0;
m_LineColor[1] = 1.0;
m_LineColor[2] = 0.0;
m_LineColor[3] = 1.0;
m_Cutter->SetCutFunction(m_Plane);
m_Cutter->GenerateValues(1,0,1);
m_LUT->SetTableRange(0,255);
m_LUT->SetNumberOfColors(255);
m_LUT->SetRampToLinear();
m_LUT->Build();
}
mitk::SurfaceGLMapper2D::~SurfaceGLMapper2D()
{
m_Plane->Delete();
m_Cutter->Delete();
m_LUT->Delete();
m_PointLocator->Delete();
m_Stripper->Delete();
}
const mitk::Surface *mitk::SurfaceGLMapper2D::GetInput(void)
{
if(m_Surface.IsNotNull())
return m_Surface;
return static_cast<const Surface * > ( GetData() );
}
void mitk::SurfaceGLMapper2D::SetDataNode( mitk::DataNode* node )
{
Superclass::SetDataNode( node );
bool useCellData;
if (dynamic_cast<BoolProperty *>(node->GetProperty("deprecated useCellDataForColouring")) == NULL)
useCellData = false;
else
useCellData = dynamic_cast<BoolProperty *>(node->GetProperty("deprecated useCellDataForColouring"))->GetValue();
if (!useCellData)
{
// search min/max point scalars over all time steps
vtkFloatingPointType dataRange[2] = {0,0};
vtkFloatingPointType range[2];
Surface::Pointer input = const_cast< Surface* >(dynamic_cast<const Surface*>( this->GetDataNode()->GetData() ));
if(input.IsNull()) return;
const TimeSlicedGeometry::Pointer inputTimeGeometry = input->GetTimeSlicedGeometry();
if(( inputTimeGeometry.IsNull() ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) ) return;
for (unsigned int timestep=0; timestep<inputTimeGeometry->GetTimeSteps(); timestep++)
{
vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep );
if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 )) continue;
vtkDataArray *vpointscalars = vtkpolydata->GetPointData()->GetScalars();
if (vpointscalars) {
vpointscalars->GetRange( range, 0 );
if (dataRange[0]==0 && dataRange[1]==0) {
dataRange[0] = range[0];
dataRange[1] = range[1];
}
else {
if (range[0] < dataRange[0]) dataRange[0] = range[0];
if (range[1] > dataRange[1]) dataRange[1] = range[1];
}
}
}
if (dataRange[1] - dataRange[0] > 0) {
m_LUT->SetTableRange( dataRange );
m_LUT->Build();
}
}
}
void mitk::SurfaceGLMapper2D::Paint(mitk::BaseRenderer * renderer)
{
if(IsVisible(renderer)==false) return;
Surface::Pointer input = const_cast<Surface*>(this->GetInput());
if(input.IsNull())
return;
//
// get the TimeSlicedGeometry of the input object
//
const TimeSlicedGeometry* inputTimeGeometry = input->GetTimeSlicedGeometry();
if(( inputTimeGeometry == NULL ) || ( inputTimeGeometry->GetTimeSteps() == 0 ) )
return;
if (dynamic_cast<IntProperty *>(this->GetDataNode()->GetProperty("line width")) == NULL)
m_LineWidth = 1;
else
m_LineWidth = dynamic_cast<IntProperty *>(this->GetDataNode()->GetProperty("line width"))->GetValue();
//
// get the world time
//
Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
assert( worldGeometry.IsNotNull() );
ScalarType time = worldGeometry->GetTimeBounds()[ 0 ];
int timestep=0;
if( time > ScalarTypeNumericTraits::NonpositiveMin() )
timestep = inputTimeGeometry->MSToTimeStep( time );
// int timestep = this->GetTimestep();
if( inputTimeGeometry->IsValidTime( timestep ) == false )
return;
vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep );
if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 ))
return;
PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>(worldGeometry.GetPointer());
//apply color and opacity read from the PropertyList
ApplyProperties(renderer);
if (m_DrawNormals)
{
m_PointLocator->SetDataSet( vtkpolydata );
m_PointLocator->BuildLocatorFromPoints( vtkpolydata->GetPoints() );
}
if(vtkpolydata!=NULL)
{
Point3D point;
Vector3D normal;
//Check if Lookup-Table is already given, else use standard one.
vtkFloatingPointType* scalarLimits = m_LUT->GetTableRange();
vtkFloatingPointType scalarsMin = scalarLimits[0], scalarsMax = scalarLimits[1];
vtkLookupTable *lut;// = vtkLookupTable::New();
LookupTableProperty::Pointer lookupTableProp;
this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer);
if (lookupTableProp.IsNotNull() )
{
lut = lookupTableProp->GetLookupTable()->GetVtkLookupTable();
if (dynamic_cast<FloatProperty *>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL)
scalarsMin = dynamic_cast<FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue();
if (dynamic_cast<FloatProperty *>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL)
scalarsMax = dynamic_cast<FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue();
// check if the scalar range has been changed, e.g. manually, for the data tree node, and rebuild the LUT if necessary.
double* oldRange = lut->GetTableRange();
if( oldRange[0] != scalarsMin || oldRange[1] != scalarsMax )
{
lut->SetTableRange(scalarsMin, scalarsMax);
lut->Build();
}
}
else
{
lut = m_LUT;
}
vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(timestep);
if(worldPlaneGeometry.IsNotNull())
{
// set up vtkPlane according to worldGeometry
point=worldPlaneGeometry->GetOrigin();
normal=worldPlaneGeometry->GetNormal(); normal.Normalize();
m_Plane->SetTransform((vtkAbstractTransform*)NULL);
}
else
{
AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldGeometry2D());
if(worldAbstractGeometry.IsNotNull())
{
AbstractTransformGeometry::ConstPointer surfaceAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(input->GetTimeSlicedGeometry()->GetGeometry3D(0));
if(surfaceAbstractGeometry.IsNotNull()) //@todo substitude by operator== after implementation, see bug id 28
{
PaintCells(renderer, vtkpolydata, worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut);
return;
}
else
{
//@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "flat plane" into a "curved plane"?
return;
// set up vtkPlane according to worldGeometry
point=const_cast<BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum();
FillVector3D(normal, 0, 0, 1);
m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse());
}
}
else
return;
}
vtkFloatingPointType vp[3], vnormal[3];
vnl2vtk(point.Get_vnl_vector(), vp);
vnl2vtk(normal.Get_vnl_vector(), vnormal);
//normally, we would need to transform the surface and cut the transformed surface with the cutter.
//This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
//@todo It probably does not work for scaling operations yet:scaling operations have to be
//dealed with after the cut is performed by scaling the contour.
vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();
inversetransform->TransformPoint(vp, vp);
inversetransform->TransformNormalAtPoint(vp, vnormal, vnormal);
m_Plane->SetOrigin(vp);
m_Plane->SetNormal(vnormal);
//set data into cutter
m_Cutter->SetInput(vtkpolydata);
m_Cutter->Update();
// m_Cutter->GenerateCutScalarsOff();
// m_Cutter->SetSortByToSortByCell();
if (m_DrawNormals)
{
m_Stripper->SetInput( m_Cutter->GetOutput() );
// calculate the cut
m_Stripper->Update();
PaintCells(renderer, m_Stripper->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata);
}
else
{
PaintCells(renderer, m_Cutter->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata);
}
}
}
void mitk::SurfaceGLMapper2D::PaintCells(mitk::BaseRenderer* renderer, vtkPolyData* contour,
const Geometry2D* worldGeometry,
const DisplayGeometry* displayGeometry,
vtkLinearTransform * vtktransform,
vtkLookupTable *lut,
vtkPolyData* original3DObject)
{
// deprecated settings
bool usePointData = false;
bool useCellData = false;
this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", useCellData);
bool scalarVisibility = false;
this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility);
if(scalarVisibility)
{
VtkScalarModeProperty* scalarMode;
if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer))
{
if( (scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_POINT_DATA) ||
(scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_DEFAULT) )
{
usePointData = true;
}
if(scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA)
{
useCellData = true;
}
}
else
{
usePointData = true;
}
}
vtkPoints *vpoints = contour->GetPoints();
vtkDataArray *vpointscalars = contour->GetPointData()->GetScalars();
vtkCellArray *vlines = contour->GetLines();
vtkDataArray* vcellscalars = contour->GetCellData()->GetScalars();
Point3D p; Point2D p2d, last;
int i, j;
int numberOfLines = vlines->GetNumberOfCells();
glLineWidth( m_LineWidth );
glBegin (GL_LINES);
glColor4fv(m_LineColor);
double distanceSinceLastNormal(0.0);
vlines->InitTraversal();
for(i=0;i<numberOfLines;++i)
{
vtkIdType *cell(NULL);
vtkIdType cellSize(0);
vtkFloatingPointType vp[3];
vlines->GetNextCell(cellSize, cell);
vpoints->GetPoint(cell[0], vp);
//take transformation via vtktransform into account
vtktransform->TransformPoint(vp, vp);
vtk2itk(vp, p);
//convert 3D point (in mm) to 2D point on slice (also in mm)
worldGeometry->Map(p, p2d);
//convert point (until now mm and in world coordinates) to display coordinates (units )
displayGeometry->WorldToDisplay(p2d, p2d);
last=p2d;
for(j=1; j<cellSize; ++j)
{
vpoints->GetPoint(cell[j], vp);
Point3D originalPoint;
vtk2itk(vp, originalPoint);
//take transformation via vtktransform into account
vtktransform->TransformPoint(vp, vp);
vtk2itk(vp, p);
//convert 3D point (in mm) to 2D point on slice (also in mm)
worldGeometry->Map(p, p2d);
//convert point (until now mm and in world coordinates) to display coordinates (units )
displayGeometry->WorldToDisplay(p2d, p2d);
vtkFloatingPointType color[3];
if (useCellData && vcellscalars != NULL )
{
// color each cell according to cell data
lut->GetColor( vcellscalars->GetComponent(i,0),color);
glColor3f(color[0],color[1],color[2]);
glVertex2f(last[0], last[1]);
glVertex2f(p2d[0], p2d[1]);
}
else if (usePointData && vpointscalars != NULL )
{
lut->GetColor( vpointscalars->GetComponent(cell[j-1],0),color);
glColor3f(color[0],color[1],color[2]);
glVertex2f(last[0], last[1]);
lut->GetColor( vpointscalars->GetComponent(cell[j],0),color);
glColor3f(color[0],color[1],color[2]);
glVertex2f(p2d[0], p2d[1]);
}
else
{
glVertex2f(last[0], last[1]);
glVertex2f(p2d[0], p2d[1]);
// draw normals ?
if (m_DrawNormals && original3DObject)
{
distanceSinceLastNormal += sqrt((p2d[0]-last[0])*(p2d[0]-last[0]) + (p2d[1]-last[1])*(p2d[1]-last[1]));
if (distanceSinceLastNormal >= 5.0)
{
distanceSinceLastNormal = 0.0;
vtkPointData* pointData = original3DObject->GetPointData();
if (!pointData) break;
vtkDataArray* normalsArray = pointData->GetNormals();
if (!normalsArray) break;
// find 3D point closest to the currently drawn point
double distance(0.0);
vtkIdType closestPointId = m_PointLocator->FindClosestPoint(originalPoint[0], originalPoint[1], originalPoint[2], distance);
if (closestPointId >= 0)
{
// find normal of 3D object at this 3D point
double* normal = normalsArray->GetTuple3(closestPointId);
double transformedNormal[3];
vtktransform->TransformNormal(normal, transformedNormal);
Vector3D normalITK;
vtk2itk(transformedNormal, normalITK);
normalITK.Normalize();
// calculate a point (point from the cut 3D object) + (normal vector of closest point)
Point3D tip3D = p + normalITK;
// map this point into our 2D coordinate system
Point2D tip2D;
worldGeometry->Map(tip3D, tip2D);
displayGeometry->WorldToDisplay(tip2D, tip2D);
// calculate 2D vector from point to point+normal, normalize it to standard length
Vector2D tipVectorGLFront = tip2D - p2d;
tipVectorGLFront.Normalize();
tipVectorGLFront *= m_FrontNormalLengthInPixels;
Vector2D tipVectorGLBack = p2d - tip2D;
tipVectorGLBack.Normalize();
tipVectorGLBack *= m_BackNormalLengthInPixels;
Point2D tipPoint2D = p2d + tipVectorGLFront;
Point2D backTipPoint2D = p2d + tipVectorGLBack;
// draw normalized mapped normal vector
glColor4f(m_BackSideColor[0], m_BackSideColor[1], m_BackSideColor[2], m_BackSideColor[3]); // red backside
glVertex2f(p2d[0], p2d[1]);
glVertex2f(tipPoint2D[0], tipPoint2D[1]);
glColor4f(m_FrontSideColor[0], m_FrontSideColor[1], m_FrontSideColor[2], m_FrontSideColor[3]); // green backside
glVertex2f(p2d[0], p2d[1]);
glVertex2f(backTipPoint2D[0], backTipPoint2D[1]);
glColor4fv(m_LineColor); // back to line color
}
}
}
}
last=p2d;
}
}
glEnd();
glLineWidth(1.0);
}
void mitk::SurfaceGLMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty( "line width", IntProperty::New(2), renderer, overwrite );
node->AddProperty( "scalar mode", VtkScalarModeProperty::New(), renderer, overwrite );
node->AddProperty( "draw normals 2D", BoolProperty::New(false), renderer, overwrite );
node->AddProperty( "invert normals", BoolProperty::New(false), renderer, overwrite );
node->AddProperty( "front color", ColorProperty::New(0.0, 1.0, 0.0), renderer, overwrite );
node->AddProperty( "back color", ColorProperty::New(1.0, 0.0, 0.0), renderer, overwrite );
node->AddProperty( "front normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite );
node->AddProperty( "back normal lenth (px)", FloatProperty::New(10.0), renderer, overwrite );
node->AddProperty( "layer", mitk::IntProperty::New(100), renderer, overwrite);
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
void mitk::SurfaceGLMapper2D::ApplyProperties(mitk::BaseRenderer* renderer)
{
Superclass::ApplyProperties(renderer);
GetDataNode()->GetBoolProperty("draw normals 2D", m_DrawNormals, renderer);
// check for color and opacity properties, use it for rendering if they exists
GetColor(m_LineColor, renderer /*, "color" */);
GetOpacity(m_LineColor[3], renderer /*, "color" */);
bool invertNormals(false);
if (DataNode* node = GetDataNode())
{
node->GetBoolProperty("invert normals", invertNormals, renderer);
}
if (!invertNormals)
{
GetColor(m_FrontSideColor, renderer, "front color");
GetOpacity(m_FrontSideColor[3], renderer);
GetColor(m_BackSideColor, renderer, "back color");
GetOpacity(m_BackSideColor[3], renderer);
if (DataNode* node = GetDataNode())
{
node->GetFloatProperty( "front normal lenth (px)", m_FrontNormalLengthInPixels, renderer );
node->GetFloatProperty( "back normal lenth (px)", m_BackNormalLengthInPixels, renderer );
}
}
else
{
GetColor(m_FrontSideColor, renderer, "back color");
GetOpacity(m_FrontSideColor[3], renderer);
GetColor(m_BackSideColor, renderer, "front color");
GetOpacity(m_BackSideColor[3], renderer);
if (DataNode* node = GetDataNode())
{
node->GetFloatProperty( "back normal lenth (px)", m_FrontNormalLengthInPixels, renderer );
node->GetFloatProperty( "front normal lenth (px)", m_BackNormalLengthInPixels, renderer );
}
}
}
diff --git a/Core/Code/Rendering/mitkSurfaceGLMapper2D.h b/Core/Code/Rendering/mitkSurfaceGLMapper2D.h
index e1c3f6881b..e7288d8b2a 100644
--- a/Core/Code/Rendering/mitkSurfaceGLMapper2D.h
+++ b/Core/Code/Rendering/mitkSurfaceGLMapper2D.h
@@ -1,156 +1,155 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8
#define MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8
#include <MitkExports.h>
#include "mitkGLMapper2D.h"
#include "mitkSurface.h"
class vtkCutter;
class vtkPlane;
class vtkLookupTable;
class vtkLinearTransform;
class vtkPKdTree;
class vtkStripper;
namespace mitk {
class BaseRenderer;
class Geometry2D;
class DisplayGeometry;
/**
* @brief OpenGL-based mapper to display a Surface in a 2D window.
*
* Displays a 2D cut through a Surface object (vtkPolyData). This
* is basically done in two steps:
*
* 1. Cut a slice out of a (input) vtkPolyData object. The slice may be a flat plane (PlaneGeometry)
* or a curved plane (ThinPlateSplineCurvedGeometry). The actual cutting is done by a vtkCutter.
* The result of cutting is a (3D) vtkPolyData object, which contains only points and lines
* describing the cut.
*
* 2. Paint the cut out slice by means of OpenGL. To do this, all lines of the cut object are traversed.
* For each line segment, both end points are transformed from 3D into the 2D system of the associated
* renderer and then drawn by OpenGL.
*
* There is a mode to display normals of the input surface object (see properties below). If this mode
* is on, then the drawing of the 2D cut is slightly more complicated. For each line segment of the cut,
* we take the end point (p2d) of this line and search the input vtkPolyData object for the closest point to p2d (p3D-input).
* We then read out the surface normal for p3D-input. We map this normal into our 2D coordinate system and
* then draw a line from p2d to (p2d+mapped normal). This drawing of surface normals will only work if the
* input vtkPolyData actually HAS normals. If you have a vtkPolyData without normals, use the vtkPolyDataNormals
* filter to generate normals.
*
* Properties that influence rendering are:
*
* - \b "color": (ColorProperty) Color of surface object
* - \b "line width": (IntProperty) Width in pixels of the lines drawn.
* - \b "scalar visibility": (BoolProperty) Whether point/cell data values (from vtkPolyData) should be used to influence colors
* - \b "scalar mode": (BoolProperty) If "scalar visibility" is on, whether to use point data or cell data for coloring.
* - \b "LookupTable": (LookupTableProperty) A lookup table to translate point/cell data values (from vtkPolyData) to colors
* - \b "ScalarsRangeMinimum": (FloatProperty) Range of the lookup table
* - \b "ScalarsRangeMaximum": (FloatProperty) Range of the lookup table
* - \b "draw normals 2D": (BoolProperty) If true, normals are drawn (if present in vtkPolyData)
* - \b "invert normals": (BoolProperty) Inverts front/back for display.
* - \b "front color": (ColorProperty) Color for normals display on front side of the plane
* - \b "front normal length (px)": (FloatProperty) Length of the front side normals in pixels.
* - \b "back color": (ColorProperty) Color for normals display on back side of the plane
* - \b "back normal length (px)": (FloatProperty) Length of the back side normals in pixels.
*
*/
class MITK_CORE_EXPORT SurfaceGLMapper2D : public GLMapper2D
{
public:
mitkClassMacro(SurfaceGLMapper2D, GLMapper2D);
itkNewMacro(Self);
const Surface* GetInput(void);
virtual void Paint(BaseRenderer* renderer);
/**
* @brief The Surface to map can be explicitly set by this method.
*
* If it is set, it is used instead of the data stored in the DataNode.
* This enables to use the mapper also internally from other mappers.
*/
itkSetConstObjectMacro(Surface, Surface);
/**
* @brief Get the Surface set explicitly.
*
* @return NULL is returned if no Surface is set to be used instead of DataNode::GetData().
* @sa SetSurface
*/
itkGetConstObjectMacro(Surface, Surface);
/**
*\brief Overwritten to initialize lookup table for point scalar data
*/
void SetDataNode( DataNode* node );
/**
* \brief Generate OpenGL primitives for the VTK contour held in contour.
*/
void PaintCells(BaseRenderer* renderer, vtkPolyData* contour,
const Geometry2D* worldGeometry,
const DisplayGeometry* displayGeometry,
vtkLinearTransform* vtktransform,
vtkLookupTable* lut = NULL,
vtkPolyData* original3DObject = NULL);
static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false);
virtual void ApplyProperties(BaseRenderer* renderer);
protected:
SurfaceGLMapper2D();
virtual ~SurfaceGLMapper2D();
vtkPlane* m_Plane;
vtkCutter* m_Cutter;
Surface::ConstPointer m_Surface;
vtkLookupTable* m_LUT;
int m_LineWidth;
vtkPKdTree* m_PointLocator;
vtkStripper* m_Stripper;
bool m_DrawNormals;
float m_FrontSideColor[4];
float m_BackSideColor[4];
float m_LineColor[4];
float m_FrontNormalLengthInPixels;
float m_BackNormalLengthInPixels;
};
} // namespace mitk
#endif /* MITKSURFACEDATAMAPPER2D_H_HEADER_INCLUDED_C10EB2E8 */
diff --git a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp
index 185e121a5a..7f6ce458d7 100644
--- a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp
+++ b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp
@@ -1,470 +1,469 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurfaceVtkMapper3D.h"
#include "mitkDataNode.h"
#include "mitkProperties.h"
#include "mitkColorProperty.h"
#include "mitkLookupTableProperty.h"
#include "mitkVtkRepresentationProperty.h"
#include "mitkVtkInterpolationProperty.h"
#include "mitkVtkScalarModeProperty.h"
#include "mitkClippingProperty.h"
#include "mitkShaderProperty.h"
#include "mitkShaderRepository.h"
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyDataNormals.h>
#include <vtkPointData.h>
#include <vtkPlaneCollection.h>
const mitk::Surface* mitk::SurfaceVtkMapper3D::GetInput()
{
return static_cast<const mitk::Surface * > ( GetData() );
}
mitk::SurfaceVtkMapper3D::SurfaceVtkMapper3D()
{
// m_Prop3D = vtkActor::New();
m_GenerateNormals = false;
}
mitk::SurfaceVtkMapper3D::~SurfaceVtkMapper3D()
{
// m_Prop3D->Delete();
}
void mitk::SurfaceVtkMapper3D::GenerateDataForRenderer(mitk::BaseRenderer* renderer)
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
bool visible = IsVisible(renderer);
if(visible==false)
{
ls->m_Actor->VisibilityOff();
return;
}
//
// set the input-object at time t for the mapper
//
mitk::Surface::Pointer input = const_cast< mitk::Surface* >( this->GetInput() );
vtkPolyData * polydata = input->GetVtkPolyData( this->GetTimestep() );
if(polydata == NULL)
{
ls->m_Actor->VisibilityOff();
return;
}
if ( m_GenerateNormals )
{
ls->m_VtkPolyDataNormals->SetInput( polydata );
ls->m_VtkPolyDataMapper->SetInput( ls->m_VtkPolyDataNormals->GetOutput() );
}
else
{
ls->m_VtkPolyDataMapper->SetInput( polydata );
}
//
// apply properties read from the PropertyList
//
ApplyProperties(ls->m_Actor, renderer);
if(visible)
ls->m_Actor->VisibilityOn();
}
void mitk::SurfaceVtkMapper3D::ResetMapper( BaseRenderer* renderer )
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
ls->m_Actor->VisibilityOff();
}
void mitk::SurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer)
{
// Backface culling
{
mitk::BoolProperty::Pointer p;
node->GetProperty(p, "Backface Culling", renderer);
bool useCulling = false;
if(p.IsNotNull())
useCulling = p->GetValue();
property->SetBackfaceCulling(useCulling);
}
// Colors
{
double ambient [3] = { 0.5,0.5,0.0 };
double diffuse [3] = { 0.5,0.5,0.0 };
double specular[3] = { 1.0,1.0,1.0 };
float coeff_ambient = 0.5f;
float coeff_diffuse = 0.5f;
float coeff_specular= 0.5f;
float power_specular=10.0f;
// Color
{
mitk::ColorProperty::Pointer p;
node->GetProperty(p, "color", renderer);
if(p.IsNotNull())
{
mitk::Color c = p->GetColor();
ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue();
diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue();
// Setting specular color to the same, make physically no real sense, however vtk rendering slows down, if these colors are different.
specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue();
}
}
// Ambient
{
mitk::ColorProperty::Pointer p;
node->GetProperty(p, "material.ambientColor", renderer);
if(p.IsNotNull())
{
mitk::Color c = p->GetColor();
ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue();
}
}
// Diffuse
{
mitk::ColorProperty::Pointer p;
node->GetProperty(p, "material.diffuseColor", renderer);
if(p.IsNotNull())
{
mitk::Color c = p->GetColor();
diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue();
}
}
// Specular
{
mitk::ColorProperty::Pointer p;
node->GetProperty(p, "material.specularColor", renderer);
if(p.IsNotNull())
{
mitk::Color c = p->GetColor();
specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue();
}
}
// Ambient coeff
{
node->GetFloatProperty("material.ambientCoefficient", coeff_ambient, renderer);
}
// Diffuse coeff
{
node->GetFloatProperty("material.diffuseCoefficient", coeff_diffuse, renderer);
}
// Specular coeff
{
node->GetFloatProperty("material.specularCoefficient", coeff_specular, renderer);
}
// Specular power
{
node->GetFloatProperty("material.specularPower", power_specular, renderer);
}
property->SetAmbient( coeff_ambient );
property->SetDiffuse( coeff_diffuse );
property->SetSpecular( coeff_specular );
property->SetSpecularPower( power_specular );
property->SetAmbientColor( ambient );
property->SetDiffuseColor( diffuse );
property->SetSpecularColor( specular );
}
// Render mode
{
// Opacity
{
float opacity = 1.0f;
if( node->GetOpacity(opacity,renderer) )
property->SetOpacity( opacity );
}
// Wireframe line width
{
float lineWidth = 1;
node->GetFloatProperty("material.wireframeLineWidth", lineWidth, renderer);
property->SetLineWidth( lineWidth );
}
// Representation
{
mitk::VtkRepresentationProperty::Pointer p;
node->GetProperty(p, "material.representation", renderer);
if(p.IsNotNull())
property->SetRepresentation( p->GetVtkRepresentation() );
}
// Interpolation
{
mitk::VtkInterpolationProperty::Pointer p;
node->GetProperty(p, "material.interpolation", renderer);
if(p.IsNotNull())
property->SetInterpolation( p->GetVtkInterpolation() );
}
}
}
void mitk::SurfaceVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer)
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
// Applying shading properties
{
Superclass::ApplyProperties( ls->m_Actor, renderer ) ;
// VTK Properties
ApplyMitkPropertiesToVtkProperty( this->GetDataNode(), ls->m_Actor->GetProperty(), renderer );
// Shaders
mitk::ShaderRepository::GetGlobalShaderRepository()->ApplyProperties(this->GetDataNode(),ls->m_Actor,renderer,ls->m_ShaderTimestampUpdate);
}
mitk::LookupTableProperty::Pointer lookupTableProp;
this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer);
if (lookupTableProp.IsNotNull() )
{
ls->m_VtkPolyDataMapper->SetLookupTable(lookupTableProp->GetLookupTable()->GetVtkLookupTable());
}
mitk::LevelWindow levelWindow;
if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer, "levelWindow"))
{
ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound());
}
else
if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer))
{
ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound());
}
bool scalarVisibility = false;
this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility);
ls->m_VtkPolyDataMapper->SetScalarVisibility( (scalarVisibility ? 1 : 0) );
if(scalarVisibility)
{
mitk::VtkScalarModeProperty* scalarMode;
if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer))
{
ls->m_VtkPolyDataMapper->SetScalarMode(scalarMode->GetVtkScalarMode());
}
else
ls->m_VtkPolyDataMapper->SetScalarModeToDefault();
bool colorMode = false;
this->GetDataNode()->GetBoolProperty("color mode", colorMode);
ls->m_VtkPolyDataMapper->SetColorMode( (colorMode ? 1 : 0) );
float scalarsMin = 0;
if (dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL)
scalarsMin = dynamic_cast<mitk::FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue();
float scalarsMax = 1.0;
if (dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL)
scalarsMax = dynamic_cast<mitk::FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue();
ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax);
}
// deprecated settings
bool deprecatedUseCellData = false;
this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", deprecatedUseCellData);
bool deprecatedUsePointData = false;
this->GetDataNode()->GetBoolProperty("deprecated usePointDataForColouring", deprecatedUsePointData);
if (deprecatedUseCellData)
{
ls->m_VtkPolyDataMapper->SetColorModeToDefault();
ls->m_VtkPolyDataMapper->SetScalarRange(0,255);
ls->m_VtkPolyDataMapper->ScalarVisibilityOn();
ls->m_VtkPolyDataMapper->SetScalarModeToUseCellData();
ls->m_Actor->GetProperty()->SetSpecular (1);
ls->m_Actor->GetProperty()->SetSpecularPower (50);
ls->m_Actor->GetProperty()->SetInterpolationToPhong();
}
else if (deprecatedUsePointData)
{
float scalarsMin = 0;
if (dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL)
scalarsMin = dynamic_cast<mitk::FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue();
float scalarsMax = 0.1;
if (dynamic_cast<mitk::FloatProperty *>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL)
scalarsMax = dynamic_cast<mitk::FloatProperty*>(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue();
ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax);
ls->m_VtkPolyDataMapper->SetColorModeToMapScalars();
ls->m_VtkPolyDataMapper->ScalarVisibilityOn();
ls->m_Actor->GetProperty()->SetSpecular (1);
ls->m_Actor->GetProperty()->SetSpecularPower (50);
ls->m_Actor->GetProperty()->SetInterpolationToPhong();
}
int deprecatedScalarMode = VTK_COLOR_MODE_DEFAULT;
if(this->GetDataNode()->GetIntProperty("deprecated scalar mode", deprecatedScalarMode, renderer))
{
ls->m_VtkPolyDataMapper->SetScalarMode(deprecatedScalarMode);
ls->m_VtkPolyDataMapper->ScalarVisibilityOn();
ls->m_Actor->GetProperty()->SetSpecular (1);
ls->m_Actor->GetProperty()->SetSpecularPower (50);
//m_Actor->GetProperty()->SetInterpolationToPhong();
}
// Check whether one or more ClippingProperty objects have been defined for
// this node. Check both renderer specific and global property lists, since
// properties in both should be considered.
const PropertyList::PropertyMap *rendererProperties = this->GetDataNode()->GetPropertyList( renderer )->GetMap();
const PropertyList::PropertyMap *globalProperties = this->GetDataNode()->GetPropertyList( NULL )->GetMap();
// Add clipping planes (if any)
ls->m_ClippingPlaneCollection->RemoveAllItems();
PropertyList::PropertyMap::const_iterator it;
for ( it = rendererProperties->begin(); it != rendererProperties->end(); ++it )
{
this->CheckForClippingProperty( renderer,(*it).second.GetPointer() );
}
for ( it = globalProperties->begin(); it != globalProperties->end(); ++it )
{
this->CheckForClippingProperty( renderer,(*it).second.GetPointer() );
}
if ( ls->m_ClippingPlaneCollection->GetNumberOfItems() > 0 )
{
ls->m_VtkPolyDataMapper->SetClippingPlanes( ls->m_ClippingPlaneCollection );
}
else
{
ls->m_VtkPolyDataMapper->RemoveAllClippingPlanes();
}
}
vtkProp *mitk::SurfaceVtkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer)
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
return ls->m_Actor;
}
void mitk::SurfaceVtkMapper3D::CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property )
{
LocalStorage *ls = m_LSH.GetLocalStorage(renderer);
// m_Prop3D = ls->m_Actor;
ClippingProperty *clippingProperty = dynamic_cast< ClippingProperty * >( property );
if ( (clippingProperty != NULL)
&& (clippingProperty->GetClippingEnabled()) )
{
const Point3D &origin = clippingProperty->GetOrigin();
const Vector3D &normal = clippingProperty->GetNormal();
vtkPlane *clippingPlane = vtkPlane::New();
clippingPlane->SetOrigin( origin[0], origin[1], origin[2] );
clippingPlane->SetNormal( normal[0], normal[1], normal[2] );
ls->m_ClippingPlaneCollection->AddItem( clippingPlane );
clippingPlane->UnRegister( NULL );
}
}
void mitk::SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
// Shading
{
node->AddProperty( "material.wireframeLineWidth", mitk::FloatProperty::New(1.0f) , renderer, overwrite );
node->AddProperty( "material.ambientCoefficient" , mitk::FloatProperty::New(0.05f) , renderer, overwrite );
node->AddProperty( "material.diffuseCoefficient" , mitk::FloatProperty::New(0.9f) , renderer, overwrite );
node->AddProperty( "material.specularCoefficient", mitk::FloatProperty::New(1.0f) , renderer, overwrite );
node->AddProperty( "material.specularPower" , mitk::FloatProperty::New(16.0f) , renderer, overwrite );
//node->AddProperty( "material.ambientColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite );
//node->AddProperty( "material.diffuseColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite );
//node->AddProperty( "material.specularColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite );
node->AddProperty( "material.representation" , mitk::VtkRepresentationProperty::New() , renderer, overwrite );
node->AddProperty( "material.interpolation" , mitk::VtkInterpolationProperty::New() , renderer, overwrite );
}
// Shaders
{
mitk::ShaderRepository::GetGlobalShaderRepository()->AddDefaultProperties(node,renderer,overwrite);
}
}
void mitk::SurfaceVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty( "color", mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite );
node->AddProperty( "opacity", mitk::FloatProperty::New(1.0), renderer, overwrite );
mitk::SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node,renderer,overwrite); // Shading
node->AddProperty( "scalar visibility", mitk::BoolProperty::New(false), renderer, overwrite );
node->AddProperty( "color mode", mitk::BoolProperty::New(false), renderer, overwrite );
node->AddProperty( "scalar mode", mitk::VtkScalarModeProperty::New(), renderer, overwrite );
mitk::Surface::Pointer surface = dynamic_cast<Surface*>(node->GetData());
if(surface.IsNotNull())
{
if((surface->GetVtkPolyData() != 0) && (surface->GetVtkPolyData()->GetPointData() != NULL) && (surface->GetVtkPolyData()->GetPointData()->GetScalars() != 0))
{
node->AddProperty( "scalar visibility", mitk::BoolProperty::New(true), renderer, overwrite );
node->AddProperty( "color mode", mitk::BoolProperty::New(true), renderer, overwrite );
}
}
// Backface culling
node->AddProperty( "Backface Culling", mitk::BoolProperty::New(false), renderer, overwrite );
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
void mitk::SurfaceVtkMapper3D::SetImmediateModeRenderingOn(int /*on*/)
{
/*
if (m_VtkPolyDataMapper != NULL)
m_VtkPolyDataMapper->SetImmediateModeRendering(on);
*/
}
diff --git a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.h b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.h
index 44de602888..992d9f1046 100644
--- a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.h
+++ b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.h
@@ -1,163 +1,162 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273
#define MITKSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273
#include <MitkExports.h>
#include "mitkVtkMapper3D.h"
#include "mitkSurface.h"
#include "mitkBaseRenderer.h"
#include <vtkActor.h>
#include <vtkOpenGLPolyDataMapper.h>
#include <vtkPainterPolyDataMapper.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyDataNormals.h>
#include <vtkPlaneCollection.h>
namespace mitk {
//##Documentation
//## @brief Vtk-based mapper for Surface
//##
//## @ingroup Mapper
/**
* @brief Vtk-based mapper for Surface
*
* Properties that can be set for surfaces and influence the surfaceVTKMapper3D are:
*
* - \b "Backface Culling": True enables backface culling, which means only front-facing polygons will be visualized. False/disabled by default.
* - \b "color": (ColorProperty) Diffuse color of the surface object (this property will be read when material.diffuseColor is not defined)
* - \b "Opacity": (FloatProperty) Opacity of the surface object
* - \b "material.ambientColor": (ColorProperty) Ambient color of the surface object
* - \b "material.ambientCoefficient": ( FloatProperty) Ambient coefficient of the surface object
* - \b "material.diffuseColor": ( ColorProperty) Diffuse color of the surface object
* - \b "material.diffuseCoefficient": (FloatProperty) Diffuse coefficient of the surface object
* - \b "material.specularColor": (ColorProperty) Specular Color of the surface object
* - \b "material.specularCoefficient": (FloatProperty) Specular coefficient of the surface object
* - \b "material.specularPower": (FloatProperty) Specular power of the surface object
* - \b "material.interpolation": (VtkInterpolationProperty) Interpolation
* - \b "material.representation": (VtkRepresentationProperty*) Representation
* - \b "material.wireframeLineWidth": (FloatProperty) Width in pixels of the lines drawn.
* - \b "scalar visibility": (BoolProperty) If the scarlars of the surface are visible
* Properties to look for are:
*
* - \b "scalar visibility": if set to on, scalars assigned to the data are shown
* Turn this on if using a lookup table.
* - \b "ScalarsRangeMinimum": Optional. Can be used to store the scalar min, e.g.
* for the level window settings.
* - \b "ScalarsRangeMaximum": Optional. See above.
*
* There might be still some other, deprecated properties. These will not be documented anymore.
* Please check the source if you really need them.
*
* @ingroup Mapper
*/
class MITK_CORE_EXPORT SurfaceVtkMapper3D : public VtkMapper3D
{
public:
mitkClassMacro(SurfaceVtkMapper3D, VtkMapper3D);
itkNewMacro(Self);
itkSetMacro(GenerateNormals, bool);
itkGetMacro(GenerateNormals, bool);
//enable ImmediateModeRendering for vtkMapping
//yet to solve bug 1398
void SetImmediateModeRenderingOn(int on = 1);
itkGetMacro(ImmediateModeRenderingOn, int);
virtual const mitk::Surface* GetInput();
virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer);
virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer);
static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false);
protected:
SurfaceVtkMapper3D();
virtual ~SurfaceVtkMapper3D();
virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer);
virtual void ResetMapper( mitk::BaseRenderer* renderer );
/** Checks whether the specified property is a ClippingProperty and if yes,
* adds it to m_ClippingPlaneCollection (internal method). */
virtual void CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property );
bool m_GenerateNormals;
//enable ImmediateModeRendering for the vtkMapper
int m_ImmediateModeRenderingOn;
public:
class LocalStorage : public mitk::Mapper::BaseLocalStorage
{
public:
vtkActor* m_Actor;
vtkPolyDataMapper *m_VtkPolyDataMapper;
vtkPolyDataNormals *m_VtkPolyDataNormals;
vtkPlaneCollection *m_ClippingPlaneCollection;
itk::TimeStamp m_ShaderTimestampUpdate;
LocalStorage()
{
m_VtkPolyDataMapper = vtkOpenGLPolyDataMapper::New();
m_VtkPolyDataNormals = vtkPolyDataNormals::New();
m_Actor = vtkActor::New();
m_ClippingPlaneCollection = vtkPlaneCollection::New();
m_Actor->SetMapper(m_VtkPolyDataMapper);
}
~LocalStorage()
{
m_VtkPolyDataMapper->Delete();
m_VtkPolyDataNormals->Delete();
m_Actor->Delete();
m_ClippingPlaneCollection->Delete();
}
};
mitk::Mapper::LocalStorageHandler<LocalStorage> m_LSH;
static void ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer);
static void SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite);
};
} // namespace mitk
#endif /* MITKSURFACEDATAVTKMAPPER3D_H_HEADER_INCLUDED_C1907273 */
diff --git a/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.cpp b/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.cpp
index 5b222b20ca..a55b41c982 100644
--- a/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.cpp
+++ b/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.cpp
@@ -1,704 +1,703 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVolumeDataVtkMapper3D.h"
#include "mitkDataNode.h"
#include "mitkProperties.h"
#include "mitkLevelWindow.h"
#include "mitkColorProperty.h"
#include "mitkLevelWindowProperty.h"
#include "mitkLookupTableProperty.h"
#include "mitkTransferFunctionProperty.h"
#include "mitkTransferFunctionInitializer.h"
#include "mitkColorProperty.h"
#include "mitkVtkPropRenderer.h"
#include "mitkRenderingManager.h"
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkVolumeRayCastMapper.h>
#include <vtkVolumeTextureMapper2D.h>
#include <vtkVolume.h>
#include <vtkVolumeProperty.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkVolumeRayCastCompositeFunction.h>
#include <vtkVolumeRayCastMIPFunction.h>
#include <vtkFiniteDifferenceGradientEstimator.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageShiftScale.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageWriter.h>
#include <vtkImageData.h>
#include <vtkLODProp3D.h>
#include <vtkImageResample.h>
#include <vtkPlane.h>
#include <vtkImplicitPlaneWidget.h>
#include <vtkAssembly.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include "mitkVtkVolumeRenderingProperty.h"
#include <itkMultiThreader.h>
const mitk::Image* mitk::VolumeDataVtkMapper3D::GetInput()
{
return static_cast<const mitk::Image*> ( GetData() );
}
mitk::VolumeDataVtkMapper3D::VolumeDataVtkMapper3D()
: m_Mask( NULL )
{
m_PlaneSet = false;
m_ClippingPlane = vtkPlane::New();
m_PlaneWidget = vtkImplicitPlaneWidget::New();
/*
m_T2DMapper = vtkVolumeTextureMapper2D::New();
m_T2DMapper->SetMaximumNumberOfPlanes( 100 );
*/
m_HiResMapper = vtkVolumeRayCastMapper::New();
m_HiResMapper->SetSampleDistance(1.0); // 4 rays for every pixel
m_HiResMapper->IntermixIntersectingGeometryOn();
m_HiResMapper->SetNumberOfThreads( itk::MultiThreader::GetGlobalDefaultNumberOfThreads() );
/*
vtkVolumeRayCastCompositeFunction* compositeFunction = vtkVolumeRayCastCompositeFunction::New();
compositeFunction->SetCompositeMethodToClassifyFirst();
m_HiResMapper->SetVolumeRayCastFunction(compositeFunction);
compositeFunction->Delete();
vtkVolumeRayCastMIPFunction* mipFunction = vtkVolumeRayCastMIPFunction::New();
m_HiResMapper->SetVolumeRayCastFunction(mipFunction);
mipFunction->Delete();
*/
vtkFiniteDifferenceGradientEstimator* gradientEstimator =
vtkFiniteDifferenceGradientEstimator::New();
m_HiResMapper->SetGradientEstimator(gradientEstimator);
gradientEstimator->Delete();
m_VolumePropertyLow = vtkVolumeProperty::New();
m_VolumePropertyMed = vtkVolumeProperty::New();
m_VolumePropertyHigh = vtkVolumeProperty::New();
m_VolumeLOD = vtkLODProp3D::New();
m_VolumeLOD->VisibilityOff();
m_HiResID = m_VolumeLOD->AddLOD(m_HiResMapper,m_VolumePropertyHigh,0.0); // RayCast
// m_LowResID = m_VolumeLOD->AddLOD(m_T2DMapper,m_VolumePropertyLow,0.0); // TextureMapper2D
m_MedResID = m_VolumeLOD->AddLOD(m_HiResMapper,m_VolumePropertyMed,0.0); // RayCast
m_Resampler = vtkImageResample::New();
m_Resampler->SetAxisMagnificationFactor(0,0.25);
m_Resampler->SetAxisMagnificationFactor(1,0.25);
m_Resampler->SetAxisMagnificationFactor(2,0.25);
// For abort rendering mechanism
m_VolumeLOD->AutomaticLODSelectionOff();
m_BoundingBox = vtkCubeSource::New();
m_BoundingBox->SetXLength( 0.0 );
m_BoundingBox->SetYLength( 0.0 );
m_BoundingBox->SetZLength( 0.0 );
m_BoundingBoxMapper = vtkPolyDataMapper::New();
m_BoundingBoxMapper->SetInput( m_BoundingBox->GetOutput() );
m_BoundingBoxActor = vtkActor::New();
m_BoundingBoxActor->SetMapper( m_BoundingBoxMapper );
m_BoundingBoxActor->GetProperty()->SetColor( 1.0, 1.0, 1.0 );
m_BoundingBoxActor->GetProperty()->SetRepresentationToWireframe();
// BoundingBox rendering is not working due to problem with assembly
// transformation; see bug #454
// If commenting in the following, do not forget to comment in the
// m_Prop3DAssembly->Delete() line in the destructor.
//m_Prop3DAssembly = vtkAssembly::New();
//m_Prop3DAssembly->AddPart( m_VolumeLOD );
//m_Prop3DAssembly->AddPart( m_BoundingBoxActor );
//m_Prop3D = m_Prop3DAssembly;
m_ImageCast = vtkImageShiftScale::New();
m_ImageCast->SetOutputScalarTypeToUnsignedShort();
m_ImageCast->ClampOverflowOn();
m_UnitSpacingImageFilter = vtkImageChangeInformation::New();
m_UnitSpacingImageFilter->SetInput(m_ImageCast->GetOutput());
m_UnitSpacingImageFilter->SetOutputSpacing( 1.0, 1.0, 1.0 );
m_ImageMaskFilter = vtkImageMask::New();
m_ImageMaskFilter->SetMaskedOutputValue(0xffff);
this->m_Resampler->SetInput( this->m_UnitSpacingImageFilter->GetOutput() );
this->m_HiResMapper->SetInput( this->m_UnitSpacingImageFilter->GetOutput() );
// m_T2DMapper->SetInput(m_Resampler->GetOutput());
this->CreateDefaultTransferFunctions();
}
vtkProp *mitk::VolumeDataVtkMapper3D::GetVtkProp(mitk::BaseRenderer * /*renderer*/)
{
return m_VolumeLOD;
}
mitk::VolumeDataVtkMapper3D::~VolumeDataVtkMapper3D()
{
m_UnitSpacingImageFilter->Delete();
m_ImageCast->Delete();
// m_T2DMapper->Delete();
m_HiResMapper->Delete();
m_Resampler->Delete();
m_VolumePropertyLow->Delete();
m_VolumePropertyMed->Delete();
m_VolumePropertyHigh->Delete();
m_VolumeLOD->Delete();
m_ClippingPlane->Delete();
m_PlaneWidget->Delete();
// m_Prop3DAssembly->Delete();
m_BoundingBox->Delete();
m_BoundingBoxMapper->Delete();
m_BoundingBoxActor->Delete();
m_ImageMaskFilter->Delete();
m_DefaultColorTransferFunction->Delete();
m_DefaultOpacityTransferFunction->Delete();
m_DefaultGradientTransferFunction->Delete();
if (m_Mask)
{
m_Mask->Delete();
}
}
void mitk::VolumeDataVtkMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer )
{
SetVtkMapperImmediateModeRendering(m_BoundingBoxMapper);
mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() );
if ( !input || !input->IsInitialized() )
return;
vtkRenderWindow* renderWindow = renderer->GetRenderWindow();
bool volumeRenderingEnabled = true;
if (this->IsVisible(renderer)==false ||
this->GetDataNode() == NULL ||
dynamic_cast<mitk::BoolProperty*>(GetDataNode()->GetProperty("volumerendering",renderer))==NULL ||
dynamic_cast<mitk::BoolProperty*>(GetDataNode()->GetProperty("volumerendering",renderer))->GetValue() == false
)
{
volumeRenderingEnabled = false;
// Check if a bounding box should be displayed around the dataset
// (even if volume rendering is disabled)
bool hasBoundingBox = false;
this->GetDataNode()->GetBoolProperty( "bounding box", hasBoundingBox );
if ( !hasBoundingBox )
{
m_BoundingBoxActor->VisibilityOff();
}
else
{
m_BoundingBoxActor->VisibilityOn();
const BoundingBox::BoundsArrayType &bounds =
input->GetTimeSlicedGeometry()->GetBounds();
m_BoundingBox->SetBounds(
bounds[0], bounds[1],
bounds[2], bounds[3],
bounds[4], bounds[5] );
ColorProperty *colorProperty;
if ( this->GetDataNode()->GetProperty(
colorProperty, "color" ) )
{
const mitk::Color &color = colorProperty->GetColor();
m_BoundingBoxActor->GetProperty()->SetColor(
color[0], color[1], color[2] );
}
else
{
m_BoundingBoxActor->GetProperty()->SetColor(
1.0, 1.0, 1.0 );
}
}
}
// Don't do anything if VR is disabled
if ( !volumeRenderingEnabled )
{
m_VolumeLOD->VisibilityOff();
return;
}
else
{
mitk::VtkVolumeRenderingProperty* vrp=dynamic_cast<mitk::VtkVolumeRenderingProperty*>(GetDataNode()->GetProperty("volumerendering configuration",renderer));
if(vrp)
{
int renderingValue = vrp->GetValueAsId();
switch(renderingValue)
{
case VTK_VOLUME_RAY_CAST_MIP_FUNCTION:
{
vtkVolumeRayCastMIPFunction* mipFunction = vtkVolumeRayCastMIPFunction::New();
m_HiResMapper->SetVolumeRayCastFunction(mipFunction);
mipFunction->Delete();
MITK_INFO <<"in switch" <<std::endl;
break;
}
case VTK_RAY_CAST_COMPOSITE_FUNCTION:
{
vtkVolumeRayCastCompositeFunction* compositeFunction = vtkVolumeRayCastCompositeFunction::New();
compositeFunction->SetCompositeMethodToClassifyFirst();
m_HiResMapper->SetVolumeRayCastFunction(compositeFunction);
compositeFunction->Delete();
break;
}
default:
MITK_ERROR <<"Warning: invalid volume rendering option. " << std::endl;
}
}
m_VolumeLOD->VisibilityOn();
}
this->SetPreferences();
/*
switch ( mitk::RenderingManager::GetInstance()->GetNextLOD( renderer ) )
{
case 0:
m_VolumeLOD->SetSelectedLODID(m_MedResID); m_LowResID );
break;
default:
case 1:
m_VolumeLOD->SetSelectedLODID( m_HiResID );
break;
}
*/
m_VolumeLOD->SetSelectedLODID( m_HiResID );
assert(input->GetTimeSlicedGeometry());
const Geometry3D* worldgeometry = renderer->GetCurrentWorldGeometry();
if(worldgeometry==NULL)
{
GetDataNode()->SetProperty("volumerendering",mitk::BoolProperty::New(false));
return;
}
vtkImageData *inputData = input->GetVtkImageData( this->GetTimestep() );
if(inputData==NULL)
return;
m_ImageCast->SetInput( inputData );
//If mask exists, process mask before resampling.
if (this->m_Mask)
{
this->m_ImageMaskFilter->SetImageInput(this->m_UnitSpacingImageFilter->GetOutput());
this->m_Resampler->SetInput(this->m_ImageMaskFilter->GetOutput());
this->m_HiResMapper->SetInput(this->m_ImageMaskFilter->GetOutput());
}
else
{
this->m_Resampler->SetInput(this->m_UnitSpacingImageFilter->GetOutput());
this->m_HiResMapper->SetInput(this->m_UnitSpacingImageFilter->GetOutput());
}
this->UpdateTransferFunctions( renderer );
vtkRenderWindowInteractor *interactor = renderWindow->GetInteractor();
float frameRate;
if( this->GetDataNode()->GetFloatProperty( "framerate", frameRate ) && frameRate > 0 && frameRate <= 60)
{
interactor->SetDesiredUpdateRate( frameRate );
interactor->SetStillUpdateRate( frameRate );
}
else if( frameRate > 60 )
{
this->GetDataNode()->SetProperty( "framerate",mitk::FloatProperty::New(60));
interactor->SetDesiredUpdateRate( 60 );
interactor->SetStillUpdateRate( 60 );
}
else
{
this->GetDataNode()->SetProperty( "framerate",mitk::FloatProperty::New(0.00001));
interactor->SetDesiredUpdateRate( 0.00001 );
interactor->SetStillUpdateRate( 0.00001 );
}
if ( m_RenderWindowInitialized.find( renderWindow ) == m_RenderWindowInitialized.end() )
{
m_RenderWindowInitialized.insert( renderWindow );
// mitk::RenderingManager::GetInstance()->SetNextLOD( 0, renderer );
mitk::RenderingManager::GetInstance()->SetShading( true, 0 );
mitk::RenderingManager::GetInstance()->SetShading( true, 1 );
//mitk::RenderingManager::GetInstance()->SetShading( true, 2 );
mitk::RenderingManager::GetInstance()->SetShadingValues(
m_VolumePropertyHigh->GetAmbient(),
m_VolumePropertyHigh->GetDiffuse(),
m_VolumePropertyHigh->GetSpecular(),
m_VolumePropertyHigh->GetSpecularPower());
mitk::RenderingManager::GetInstance()->SetClippingPlaneStatus(false);
}
this->SetClippingPlane( interactor );
}
void mitk::VolumeDataVtkMapper3D::CreateDefaultTransferFunctions()
{
m_DefaultOpacityTransferFunction = vtkPiecewiseFunction::New();
m_DefaultOpacityTransferFunction->AddPoint( 0.0, 0.0 );
m_DefaultOpacityTransferFunction->AddPoint( 255.0, 0.8 );
m_DefaultOpacityTransferFunction->ClampingOn();
m_DefaultGradientTransferFunction = vtkPiecewiseFunction::New();
m_DefaultGradientTransferFunction->AddPoint( 0.0, 0.0 );
m_DefaultGradientTransferFunction->AddPoint( 255.0, 0.8 );
m_DefaultGradientTransferFunction->ClampingOn();
m_DefaultColorTransferFunction = vtkColorTransferFunction::New();
m_DefaultColorTransferFunction->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 );
m_DefaultColorTransferFunction->AddRGBPoint( 127.5, 1, 1, 0.0 );
m_DefaultColorTransferFunction->AddRGBPoint( 255.0, 0.8, 0.2, 0 );
m_DefaultColorTransferFunction->ClampingOn();
}
void mitk::VolumeDataVtkMapper3D::UpdateTransferFunctions( mitk::BaseRenderer *renderer )
{
vtkPiecewiseFunction *opacityTransferFunction = NULL;
vtkPiecewiseFunction *gradientTransferFunction = NULL;
vtkColorTransferFunction *colorTransferFunction = NULL;
mitk::LookupTableProperty::Pointer lookupTableProp;
lookupTableProp = dynamic_cast<mitk::LookupTableProperty*>(this->GetDataNode()->GetProperty("LookupTable"));
mitk::TransferFunctionProperty::Pointer transferFunctionProp = dynamic_cast<mitk::TransferFunctionProperty*>(this->GetDataNode()->GetProperty("TransferFunction"));
if ( transferFunctionProp.IsNotNull() ) {
opacityTransferFunction = transferFunctionProp->GetValue()->GetScalarOpacityFunction();
gradientTransferFunction = transferFunctionProp->GetValue()->GetGradientOpacityFunction();
colorTransferFunction = transferFunctionProp->GetValue()->GetColorTransferFunction();
}
else if (lookupTableProp.IsNotNull() )
{
lookupTableProp->GetLookupTable()->CreateOpacityTransferFunction(opacityTransferFunction);
opacityTransferFunction->ClampingOn();
lookupTableProp->GetLookupTable()->CreateGradientTransferFunction(gradientTransferFunction);
gradientTransferFunction->ClampingOn();
lookupTableProp->GetLookupTable()->CreateColorTransferFunction(colorTransferFunction);
colorTransferFunction->ClampingOn();
}
else
{
opacityTransferFunction = m_DefaultOpacityTransferFunction;
gradientTransferFunction = m_DefaultGradientTransferFunction;
colorTransferFunction = m_DefaultColorTransferFunction;
float rgb[3]={1.0f,1.0f,1.0f};
// check for color prop and use it for rendering if it exists
if(GetColor(rgb, renderer))
{
colorTransferFunction->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 );
colorTransferFunction->AddRGBPoint( 127.5, rgb[0], rgb[1], rgb[2] );
colorTransferFunction->AddRGBPoint( 255.0, rgb[0], rgb[1], rgb[2] );
}
}
if (this->m_Mask)
{
opacityTransferFunction->AddPoint(0xffff, 0.0);
}
m_VolumePropertyLow->SetColor( colorTransferFunction );
m_VolumePropertyLow->SetScalarOpacity( opacityTransferFunction );
m_VolumePropertyLow->SetGradientOpacity( gradientTransferFunction );
m_VolumePropertyLow->SetInterpolationTypeToNearest();
m_VolumePropertyMed->SetColor( colorTransferFunction );
m_VolumePropertyMed->SetScalarOpacity( opacityTransferFunction );
m_VolumePropertyMed->SetGradientOpacity( gradientTransferFunction );
m_VolumePropertyMed->SetInterpolationTypeToNearest();
m_VolumePropertyHigh->SetColor( colorTransferFunction );
m_VolumePropertyHigh->SetScalarOpacity( opacityTransferFunction );
m_VolumePropertyHigh->SetGradientOpacity( gradientTransferFunction );
m_VolumePropertyHigh->SetInterpolationTypeToLinear();
}
/* Shading enabled / disabled */
void mitk::VolumeDataVtkMapper3D::SetPreferences()
{
//LOD 0
/*if(mitk::RenderingManager::GetInstance()->GetShading(0))
{
m_VolumePropertyLow->ShadeOn();
m_VolumePropertyLow->SetAmbient(mitk::RenderingManager::GetInstance()->GetShadingValues()[0]);
m_VolumePropertyLow->SetDiffuse(mitk::RenderingManager::GetInstance()->GetShadingValues()[1]);
m_VolumePropertyLow->SetSpecular(mitk::RenderingManager::GetInstance()->GetShadingValues()[2]);
m_VolumePropertyLow->SetSpecularPower(mitk::RenderingManager::GetInstance()->GetShadingValues()[3]);
}
else*/
{
m_VolumePropertyLow->ShadeOff();
}
//LOD 1
/*if(mitk::RenderingManager::GetInstance()->GetShading(1))
{
m_VolumePropertyMed->ShadeOn();
m_VolumePropertyMed->SetAmbient(mitk::RenderingManager::GetInstance()->GetShadingValues()[0]);
m_VolumePropertyMed->SetDiffuse(mitk::RenderingManager::GetInstance()->GetShadingValues()[1]);
m_VolumePropertyMed->SetSpecular(mitk::RenderingManager::GetInstance()->GetShadingValues()[2]);
m_VolumePropertyMed->SetSpecularPower(mitk::RenderingManager::GetInstance()->GetShadingValues()[3]);
}
else*/
{
m_VolumePropertyMed->ShadeOff();
}
//LOD 2
/*
if(mitk::RenderingManager::GetInstance()->GetShading(2))
{
m_VolumePropertyHigh->ShadeOn();
//Shading Properties
m_VolumePropertyHigh->SetAmbient(mitk::RenderingManager::GetInstance()->GetShadingValues()[0]);
m_VolumePropertyHigh->SetDiffuse(mitk::RenderingManager::GetInstance()->GetShadingValues()[1]);
m_VolumePropertyHigh->SetSpecular(mitk::RenderingManager::GetInstance()->GetShadingValues()[2]);
m_VolumePropertyHigh->SetSpecularPower(mitk::RenderingManager::GetInstance()->GetShadingValues()[3]);
}
else
{
m_VolumePropertyHigh->ShadeOff();
}
*/
}
/* Adds A Clipping Plane to the Mapper */
void mitk::VolumeDataVtkMapper3D::SetClippingPlane(vtkRenderWindowInteractor* interactor)
{
if(mitk::RenderingManager::GetInstance()->GetClippingPlaneStatus()) //if clipping plane is enabled
{
if(!m_PlaneSet)
{
m_PlaneWidget->SetInteractor(interactor);
m_PlaneWidget->SetPlaceFactor(1.0);
m_PlaneWidget->SetInput(m_UnitSpacingImageFilter->GetOutput());
m_PlaneWidget->OutlineTranslationOff(); //disables scaling of the bounding box
m_PlaneWidget->ScaleEnabledOff(); //disables scaling of the bounding box
m_PlaneWidget->DrawPlaneOff(); //clipping plane is transparent
mitk::Image* input = const_cast<mitk::Image *>(this->GetInput());
/*places the widget within the specified bounds*/
m_PlaneWidget->PlaceWidget(
input->GetGeometry()->GetOrigin()[0],(input->GetGeometry()->GetOrigin()[0])+(input->GetDimension(0))*(input->GetVtkImageData()->GetSpacing()[0]), input->GetGeometry()->GetOrigin()[1],(input->GetGeometry()->GetOrigin()[1])+(input->GetDimension(1))*(input->GetVtkImageData()->GetSpacing()[1]), input->GetGeometry()->GetOrigin()[2],(input->GetGeometry()->GetOrigin()[2])+(input->GetDimension(2))*(input->GetVtkImageData()->GetSpacing()[2]));
// m_T2DMapper->AddClippingPlane(m_ClippingPlane);
m_HiResMapper->AddClippingPlane(m_ClippingPlane);
}
m_PlaneWidget->GetPlane(m_ClippingPlane);
m_PlaneSet = true;
}
else //if clippingplane is disabled
{
if(m_PlaneSet) //if plane exists
{
DelClippingPlane();
}
}
}
/* Removes the clipping plane */
void mitk::VolumeDataVtkMapper3D::DelClippingPlane()
{
// m_T2DMapper->RemoveAllClippingPlanes();
m_HiResMapper->RemoveAllClippingPlanes();
m_PlaneSet = false;
}
void mitk::VolumeDataVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* /*renderer*/)
{
}
void mitk::VolumeDataVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
node->AddProperty( "volumerendering", mitk::BoolProperty::New( false ), renderer, overwrite );
node->AddProperty( "volumerendering configuration", mitk::VtkVolumeRenderingProperty::New( 1 ), renderer, overwrite );
node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite );
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(node->GetData());
if(image.IsNotNull() && image->IsInitialized())
{
if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL))
{
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( image );
levWinProp->SetLevelWindow( levelwindow );
node->SetProperty( "levelwindow", levWinProp, renderer );
}
if((overwrite) || (node->GetProperty("LookupTable", renderer)==NULL))
{
// add a default rainbow lookup table for color mapping
mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New();
vtkLookupTable* vtkLut = mitkLut->GetVtkLookupTable();
vtkLut->SetHueRange(0.6667, 0.0);
vtkLut->SetTableRange(0.0, 20.0);
vtkLut->Build();
mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New();
mitkLutProp->SetLookupTable(mitkLut);
node->SetProperty( "LookupTable", mitkLutProp );
}
if((overwrite) || (node->GetProperty("TransferFunction", renderer)==NULL))
{
// add a default transfer function
mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New();
mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(tf);
tfInit->SetTransferFunctionMode(0);
node->SetProperty ( "TransferFunction", mitk::TransferFunctionProperty::New ( tf.GetPointer() ) );
}
}
Superclass::SetDefaultProperties(node, renderer, overwrite);
}
bool mitk::VolumeDataVtkMapper3D::IsLODEnabled( mitk::BaseRenderer * /*renderer*/ ) const
{
return false;
// Volume mapper is LOD enabled if volumerendering is enabled
/*
return
dynamic_cast<mitk::BoolProperty*>(GetDataNode()->GetProperty("volumerendering",renderer)) != NULL &&
dynamic_cast<mitk::BoolProperty*>(GetDataNode()->GetProperty("volumerendering",renderer))->GetValue() == true;
*/
}
void mitk::VolumeDataVtkMapper3D::EnableMask()
{
if (!this->m_Mask)
{
const Image *orig_image = this->GetInput();
unsigned int *dimensions = orig_image->GetDimensions();
this->m_Mask = vtkImageData::New();
this->m_Mask->SetDimensions(dimensions[0], dimensions[1], dimensions[2]);
this->m_Mask->SetScalarTypeToUnsignedChar();
this->m_Mask->SetNumberOfScalarComponents(1);
this->m_Mask->AllocateScalars();
unsigned char *mask_data = static_cast<unsigned char*>(this->m_Mask->GetScalarPointer());
unsigned int size = dimensions[0] * dimensions[1] * dimensions[2];
for (unsigned int i = 0u; i < size; ++i)
{
*mask_data++ = 1u;
}
this->m_ImageMaskFilter->SetMaskInput(this->m_Mask);
this->m_ImageMaskFilter->Modified();
}
}
void mitk::VolumeDataVtkMapper3D::DisableMask()
{
if (this->m_Mask)
{
this->m_Mask->Delete();
this->m_Mask = 0;
}
}
mitk::Image::Pointer mitk::VolumeDataVtkMapper3D::GetMask()
{
if (this->m_Mask)
{
Image::Pointer mask = Image::New();
mask->Initialize(this->m_Mask);
mask->SetImportVolume(this->m_Mask->GetScalarPointer(), 0, 0, Image::ReferenceMemory);
mask->SetGeometry(this->GetInput()->GetGeometry());
return mask;
}
return 0;
}
void mitk::VolumeDataVtkMapper3D::UpdateMask()
{
if (this->m_Mask)
{
this->m_ImageMaskFilter->Modified();
}
}
bool mitk::VolumeDataVtkMapper3D::SetMask(const mitk::Image* mask)
{
if (this->m_Mask)
{
if (mask->GetPixelType().GetPixelTypeId() == typeid(unsigned char))
{
Image *img = const_cast<Image*>(mask);
this->m_Mask->DeepCopy(img->GetVtkImageData());
this->m_ImageMaskFilter->Modified();
return true;
}
}
return false;
}
diff --git a/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.h b/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.h
index 35b53da41b..b97a3fa54d 100644
--- a/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.h
+++ b/Core/Code/Rendering/mitkVolumeDataVtkMapper3D.h
@@ -1,151 +1,150 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED
#define MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkVtkMapper3D.h"
#include "mitkBaseRenderer.h"
#include "mitkImage.h"
#include <vtkVolumeProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPlane.h>
#include <vtkImplicitPlaneWidget.h>
#include <vtkImageMask.h>
#include <vector>
#include <set>
class vtkAssembly;
class vtkVolumeRayCastMapper;
class vtkFixedPointVolumeRayCastMapper;
class vtkVolumeTextureMapper2D;
class vtkVolumeMapper;
class vtkVolume;
class vtkObject;
class vtkImageShiftScale;
class vtkImageChangeInformation;
class vtkLODProp3D;
class vtkImageResample;
class vtkCubeSource;
class vtkPolyDataMapper;
class vtkActor;
namespace mitk {
/************************************************************************/
/* Properties that influence the mapper are:
*
* - \b "level window": for the level window of the volume data
* - \b "LookupTable" : for the lookup table of the volume data
* - \b "TransferFunction" (mitk::TransferFunctionProperty): for the used transfer function of the volume data
************************************************************************/
//##Documentation
//## @brief Vtk-based mapper for VolumeData
//##
//## @ingroup Mapper
class MITK_CORE_EXPORT VolumeDataVtkMapper3D : public VtkMapper3D
{
public:
mitkClassMacro(VolumeDataVtkMapper3D, VtkMapper3D);
itkNewMacro(Self);
virtual const mitk::Image* GetInput();
virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer);
virtual void EnableMask();
virtual void DisableMask();
Image::Pointer GetMask();
bool SetMask(const Image* mask);
virtual void UpdateMask();
static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false);
/** Returns true if this Mapper currently allows for Level-of-Detail rendering.
* This reflects whether this Mapper currently invokes StartEvent, EndEvent, and
* ProgressEvent on BaseRenderer. */
virtual bool IsLODEnabled( BaseRenderer *renderer = NULL ) const;
virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer);
protected:
VolumeDataVtkMapper3D();
virtual ~VolumeDataVtkMapper3D();
virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer);
void CreateDefaultTransferFunctions();
void UpdateTransferFunctions( mitk::BaseRenderer *renderer );
void SetPreferences();
void SetClippingPlane(vtkRenderWindowInteractor* interactor);
void DelClippingPlane();
vtkImageShiftScale* m_ImageCast;
vtkImageChangeInformation* m_UnitSpacingImageFilter;
vtkVolumeProperty* m_VolumePropertyLow;
vtkVolumeProperty* m_VolumePropertyMed;
vtkVolumeProperty* m_VolumePropertyHigh;
vtkVolumeTextureMapper2D* m_T2DMapper;
vtkVolumeRayCastMapper* m_HiResMapper;
vtkImageResample* m_Resampler;
vtkLODProp3D* m_VolumeLOD;
vtkCubeSource *m_BoundingBox;
vtkPolyDataMapper *m_BoundingBoxMapper;
vtkActor *m_BoundingBoxActor;
vtkAssembly *m_Prop3DAssembly;
vtkPlane* m_ClippingPlane;
vtkImplicitPlaneWidget* m_PlaneWidget;
vtkImageData *m_Mask;
vtkImageMask *m_ImageMaskFilter;
vtkPiecewiseFunction *m_DefaultOpacityTransferFunction;
vtkPiecewiseFunction *m_DefaultGradientTransferFunction;
vtkColorTransferFunction *m_DefaultColorTransferFunction;
int m_LowResID;
int m_MedResID;
int m_HiResID;
bool m_PlaneSet;
double m_PlaneNormalA;
double m_PlaneNormalB;
double m_PlaneNormalC;
std::set< vtkRenderWindow * > m_RenderWindowInitialized;
};
} // namespace mitk
#endif /* MITKVOLUMEDATAVTKMAPPER3D_H_HEADER_INCLUDED */
diff --git a/Core/Code/Rendering/mitkVtkEventProvider.cpp b/Core/Code/Rendering/mitkVtkEventProvider.cpp
index 0df42be5c6..2a5b4b62d7 100644
--- a/Core/Code/Rendering/mitkVtkEventProvider.cpp
+++ b/Core/Code/Rendering/mitkVtkEventProvider.cpp
@@ -1,249 +1,248 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-07-22 16:41:18 +0200 (Fr, 17 Aug 2007) $
-Version: $Revision: 11618 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkEventProvider.h"
#include "mitkVtkEventAdapter.h"
#include <mbilog.h>
#include <vtkCallbackCommand.h>
#include <vtkObjectFactory.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyle.h>
#define VTKEVENTPROVIDER_INFO MBI_INFO("mitk.core.vtkeventprovider")
#define VTKEVENTPROVIDER_WARN MBI_WARN("mitk.core.vtkeventprovider")
#define VTKEVENTPROVIDER_ERROR MBI_ERROR("mitk.core.vtkeventprovider")
#define VTKEVENTPROVIDER_DEBUG MBI_DEBUG("mitk.core.vtkeventprovider")
namespace mitk
{
vtkCxxRevisionMacro(vtkEventProvider, "$Revision: 1.18 $");
vtkStandardNewMacro(vtkEventProvider);
}
//----------------------------------------------------------------------------
mitk::vtkEventProvider::vtkEventProvider()
{
// priority of the observer/command; we want MITK events processed in the very beginning
this->Priority = 99999.99;
//take over the processing of delete and keypress events from the superclass
this->EventCallbackCommand->SetCallback(
vtkEventProvider::ProcessEvents);
// Set/Get the passive observer flag. If this is set to true, this
// indicates that this command does not change the state of the
// system in any way. Passive observers are processed first, and
// are not called even when another command has focus.
this->EventCallbackCommand->SetPassiveObserver(1); // get events first
// mouse move
AddInteractionEvent(vtkCommand::MouseMoveEvent);
// mouse press
AddInteractionEvent(vtkCommand::LeftButtonPressEvent);
AddInteractionEvent(vtkCommand::MiddleButtonPressEvent);
AddInteractionEvent(vtkCommand::RightButtonPressEvent);
// mouse release
AddInteractionEvent(vtkCommand::LeftButtonReleaseEvent);
AddInteractionEvent(vtkCommand::MiddleButtonReleaseEvent);
AddInteractionEvent(vtkCommand::RightButtonReleaseEvent);
// wheel event
AddInteractionEvent(vtkCommand::MouseWheelBackwardEvent);
AddInteractionEvent(vtkCommand::MouseWheelForwardEvent);
// key press event
AddInteractionEvent(vtkCommand::KeyPressEvent);
}
mitk::vtkEventProvider::~vtkEventProvider()
{
this->SetInteractor(0);
}
void mitk::vtkEventProvider::SetMitkRenderWindow(mitk::RenderWindow* renWin)
{
m_RenderWindow = renWin;
}
mitk::RenderWindow* mitk::vtkEventProvider::GetRenderWindow()
{
return m_RenderWindow;
}
void mitk::vtkEventProvider::SetEnabled(int enabling)
{
if ( ! this->Interactor )
{
VTKEVENTPROVIDER_ERROR <<"The interactor must be set prior to enabling/disabling widget";
return;
}
if ( enabling ) //----------------------------------------------------------
{
VTKEVENTPROVIDER_DEBUG << "Enabling widget";
if ( this->Enabled ) //already enabled, just return
{
return;
}
this->Enabled = 1;
// listen to all event types specified in m_InteractionEventsVector
vtkRenderWindowInteractor *i = this->Interactor;
InteractionEventsVectorType::iterator it;
for(it = m_InteractionEventsVector.begin(); it != m_InteractionEventsVector.end(); it++)
{
// add observer to interactorStyle
i->GetInteractorStyle()->AddObserver((vtkCommand::EventIds) (*it), this->EventCallbackCommand,
this->Priority);
}
this->InvokeEvent(vtkCommand::EnableEvent,NULL);
}
else //disabling-----------------------------------------------------------
{
VTKEVENTPROVIDER_DEBUG <<"Disabling widget";
if ( ! this->Enabled ) //already disabled, just return
{
return;
}
this->Enabled = 0;
// don't listen for events any more
this->Interactor->RemoveObserver(this->EventCallbackCommand);
//this->Interactor->HandleEventLoop = 0;
this->InvokeEvent(vtkCommand::DisableEvent,NULL);
}
}
//----------------------------------------------------------------------------
// This adds the keypress event observer and the delete event observer
void mitk::vtkEventProvider::SetInteractor(vtkRenderWindowInteractor* i)
{
if (i == this->Interactor)
{
return;
}
// if we already have an Interactor then stop observing it
if (this->Interactor)
this->SetEnabled(0); //disable the old interactor
this->Interactor = i;
this->Modified();
}
//----------------------------------------------------------------------------
void mitk::vtkEventProvider::ProcessEvents(vtkObject* object,
unsigned long event,
void* clientData,
void* vtkNotUsed(callData))
{
vtkEventProvider* self =
reinterpret_cast<vtkEventProvider *>( clientData );
vtkRenderWindowInteractor* rwi =
static_cast<vtkInteractorStyle *>( object )->GetInteractor();
// base renderer
mitk::BaseRenderer* baseRenderer = mitk::BaseRenderer::GetInstance(self->GetRenderWindow()->GetVtkRenderWindow());
switch(event)
{
// key press
case vtkCommand::KeyPressEvent:
{
VTKEVENTPROVIDER_DEBUG << "key press event";
mitk::KeyEvent mke(mitk::VtkEventAdapter::AdaptKeyEvent(baseRenderer,event,rwi));
self->GetRenderWindow()->keyPressMitkEvent(&mke);
break;
}
// mouse events
case vtkCommand::MouseMoveEvent:
{
VTKEVENTPROVIDER_DEBUG << "mouse move event";
mitk::MouseEvent me(mitk::VtkEventAdapter::AdaptMouseEvent(baseRenderer,event,rwi));
self->GetRenderWindow()->mouseMoveMitkEvent(&me);
break;
}
case vtkCommand::LeftButtonPressEvent:
case vtkCommand::MiddleButtonPressEvent:
case vtkCommand::RightButtonPressEvent:
{
VTKEVENTPROVIDER_DEBUG << "mouse press event";
mitk::MouseEvent me(mitk::VtkEventAdapter::AdaptMouseEvent(baseRenderer,event,rwi));
self->GetRenderWindow()->mousePressMitkEvent(&me);
break;
}
case vtkCommand::LeftButtonReleaseEvent:
case vtkCommand::MiddleButtonReleaseEvent:
case vtkCommand::RightButtonReleaseEvent:
{
VTKEVENTPROVIDER_DEBUG << "mouse release event";
mitk::MouseEvent me(mitk::VtkEventAdapter::AdaptMouseEvent(baseRenderer,event,rwi));
self->GetRenderWindow()->mouseReleaseMitkEvent(&me);
break;
}
// mouse WHEEL
case vtkCommand::MouseWheelForwardEvent:
case vtkCommand::MouseWheelBackwardEvent:
{
VTKEVENTPROVIDER_DEBUG << "mouse wheel event";
mitk::WheelEvent we(mitk::VtkEventAdapter::AdaptWheelEvent(baseRenderer,event,rwi));
self->GetRenderWindow()->wheelMitkEvent(&we);
break;
}
default:
VTKEVENTPROVIDER_INFO << "VTK event not mapped properly.";
break;
}
}
void mitk::vtkEventProvider::RemoveInteractionEvent(unsigned long ievent)
{
InteractionEventsVectorType::iterator it;
if(m_InteractionEventsVector.size() > 0)
{
it = std::find(m_InteractionEventsVector.begin(),m_InteractionEventsVector.end(),ievent);
if(it != m_InteractionEventsVector.end())
{
m_InteractionEventsVector.erase(it);
return;
}
}
}
void mitk::vtkEventProvider::AddInteractionEvent(unsigned long ievent)
{
// Remove event if it already exists
RemoveInteractionEvent(ievent);
m_InteractionEventsVector.push_back(ievent);
}
\ No newline at end of file
diff --git a/Core/Code/Rendering/mitkVtkEventProvider.h b/Core/Code/Rendering/mitkVtkEventProvider.h
index 42ab4d88f6..f1b88ed472 100644
--- a/Core/Code/Rendering/mitkVtkEventProvider.h
+++ b/Core/Code/Rendering/mitkVtkEventProvider.h
@@ -1,78 +1,77 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-07-22 16:45:18 +0200 (Do, 04 Mai 2006) $
-Version: $Revision: 6790 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 VTKMITKEVENTPROVIDER_H_HEADER_INCLUDED_C1C53723
#define VTKMITKEVENTPROVIDER_H_HEADER_INCLUDED_C1C53723
#include <MitkExports.h>
#include "mitkRenderWindow.h"
#include "vtkInteractorObserver.h"
namespace mitk
{
/**
* \brief Integrates into the VTK event mechanism to generate MITK specific events.
* This class is NON-QT dependent pandon to the current MITK event handling code in QmitkRenderWindow.
* \ingroup Renderer
*/
class MITK_CORE_EXPORT vtkEventProvider : public vtkInteractorObserver
{
public:
static vtkEventProvider *New();
vtkTypeRevisionMacro(vtkEventProvider,vtkInteractorObserver);
// Satisfy the superclass API. Enable/disable listening for events.
virtual void SetEnabled(int);
virtual void SetInteractor(vtkRenderWindowInteractor* iren);
// Interface to MITK
virtual void SetMitkRenderWindow(mitk::RenderWindow* renWin);
mitk::RenderWindow* GetRenderWindow();
protected:
vtkEventProvider();
~vtkEventProvider();
//methods for processing events - callback for the observer/command pattern of vtkCommand
static void ProcessEvents(vtkObject* object, unsigned long event,
void* clientdata, void* calldata);
mitk::RenderWindow* m_RenderWindow;
// adds the MITK interaction event types to the VTK observer/command pattern
void AddInteractionEvent(unsigned long ievent);
// removes the MITK interaction event types
void RemoveInteractionEvent(unsigned long ievent);
typedef std::vector<unsigned long> InteractionEventsVectorType;
InteractionEventsVectorType m_InteractionEventsVector;
private:
vtkEventProvider(const vtkEventProvider&); // Not implemented.
void operator=(const vtkEventProvider&); // Not implemented.
};
}
#endif /* VTKMITKEVENTPROVIDER_H_HEADER_INCLUDED_C1C53723 */
diff --git a/Core/Code/Rendering/mitkVtkMapper2D.cpp b/Core/Code/Rendering/mitkVtkMapper2D.cpp
index 72f7e5b9a5..5a78c170c9 100644
--- a/Core/Code/Rendering/mitkVtkMapper2D.cpp
+++ b/Core/Code/Rendering/mitkVtkMapper2D.cpp
@@ -1,30 +1,29 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkMapper2D.h"
mitk::VtkMapper2D::VtkMapper2D()
{
}
mitk::VtkMapper2D::~VtkMapper2D()
{
}
diff --git a/Core/Code/Rendering/mitkVtkMapper2D.h b/Core/Code/Rendering/mitkVtkMapper2D.h
index d312d9a95b..eff6a6f02b 100644
--- a/Core/Code/Rendering/mitkVtkMapper2D.h
+++ b/Core/Code/Rendering/mitkVtkMapper2D.h
@@ -1,56 +1,55 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 BASEVTKMAPPER2D_H_HEADER_INCLUDED
#define BASEVTKMAPPER2D_H_HEADER_INCLUDED
#include "mitkMapper2D.h"
class vtkProp;
namespace mitk {
//##Documentation
//## @brief Base class of all vtk-based 2D-Mappers
//##
//## Those must implement the abstract
//## method vtkProp* GetProp().
//## @ingroup Mapper
class MITK_CORE_EXPORT VtkMapper2D : public Mapper2D
{
public:
mitkClassMacro(VtkMapper2D,Mapper2D);
virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer) = 0;
/**
* \brief Returns whether this is an vtk-based mapper
*/
virtual bool IsVtkBased() const { return true; }
protected:
VtkMapper2D();
virtual ~VtkMapper2D();
};
} // namespace mitk
#endif /* BASEVTKMAPPER2D_H_HEADER_INCLUDED */
diff --git a/Core/Code/Rendering/mitkVtkMapper3D.cpp b/Core/Code/Rendering/mitkVtkMapper3D.cpp
index 5c44e669fc..a9f2f94883 100644
--- a/Core/Code/Rendering/mitkVtkMapper3D.cpp
+++ b/Core/Code/Rendering/mitkVtkMapper3D.cpp
@@ -1,239 +1,238 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkMapper3D.h"
#include "mitkDataNode.h"
#include "mitkProperties.h"
#include "mitkAnnotationProperty.h"
#include "mitkVtkPropRenderer.h"
#include <vtkProp3D.h>
#include <vtkLODProp3D.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkLinearTransform.h>
#include <vtkMapper.h>
#include <vtkPropAssembly.h>
#include <vtkFollower.h>
#include <vtkVectorText.h>
#include <vtkPolyDataMapper.h>
#include <vtkProp3DCollection.h>
namespace mitk
{
VtkMapper3D::VtkMapper3D()
{
}
VtkMapper3D::~VtkMapper3D()
{
}
void VtkMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *mapper)
{
if(mapper)
mapper->SetImmediateModeRendering(mitk::VtkPropRenderer::useImmediateModeRendering());
}
void VtkMapper3D::UpdateVtkTransform(mitk::BaseRenderer *renderer)
{
vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(this->GetTimestep());
vtkProp3D *prop = dynamic_cast<vtkProp3D*>( GetVtkProp(renderer) );
if(prop)
prop->SetUserTransform(vtktransform);
}
void VtkMapper3D::MitkRenderOpaqueGeometry(BaseRenderer* renderer)
{
if ( this->IsVisible( renderer )==false )
return;
if ( this->GetVtkProp(renderer)->GetVisibility() )
{
this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() );
}
}
void VtkMapper3D::MitkRenderTranslucentGeometry(BaseRenderer* renderer)
{
if ( this->IsVisible(renderer)==false )
return;
/* if(dynamic_cast<vtkLODProp3D*>(m_Prop3D) != NULL)
{
if( dynamic_cast<BoolProperty*>(GetDataNode()->
GetProperty("volumerendering",renderer).GetPointer())==NULL ||
dynamic_cast<BoolProperty*>(GetDataNode()->
GetProperty("volumerendering",renderer).GetPointer())->GetValue() == false)
return;
}*/
if ( this->GetVtkProp(renderer)->GetVisibility() )
this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer());
}
void VtkMapper3D::MitkRenderVolumetricGeometry(BaseRenderer* renderer)
{
if(IsVisible(renderer)==false)
return;
/* if(dynamic_cast<vtkLODProp3D*>(m_Prop3D) != NULL)
{
if( dynamic_cast<BoolProperty*>(GetDataNode()->
GetProperty("volumerendering",renderer).GetPointer())==NULL ||
dynamic_cast<BoolProperty*>(GetDataNode()->
GetProperty("volumerendering",renderer).GetPointer())->GetValue() == false)
return;
}*/
if ( GetVtkProp(renderer)->GetVisibility() )
GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer());
}
void VtkMapper3D::MitkRenderOverlay(BaseRenderer* renderer)
{
if ( this->IsVisible(renderer)==false )
return;
if ( this->GetVtkProp(renderer)->GetVisibility() )
{
this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer());
}
// Render annotations as overlay
/*
m_LabelActorCollection->InitTraversal();
vtkProp3D *labelActor;
for ( m_LabelActorCollection->InitTraversal();
(labelActor = m_LabelActorCollection->GetNextProp3D()); )
{
if ( labelActor->GetVisibility() )
labelActor->RenderOpaqueGeometry( renderer->GetVtkRenderer() );
}
*/
}
void VtkMapper3D::ApplyProperties(vtkActor* actor, BaseRenderer* renderer)
{
float rgba[4]={1.0f,1.0f,1.0f,1.0f};
// check for color prop and use it for rendering if it exists
this->GetColor(rgba, renderer);
// check for opacity prop and use it for rendering if it exists
this->GetOpacity(rgba[3], renderer);
double drgba[4]={rgba[0],rgba[1],rgba[2],rgba[3]};
actor->GetProperty()->SetColor(drgba);
actor->GetProperty()->SetOpacity(drgba[3]);
// Add annotations to assembly, if any (camera (renderer) must be present)
if ( renderer != NULL )
{
// Check whether one or more AnnotationProperty objects have been defined for
// this node. Check both renderer specific and global property lists, since
// properties in both should be considered.
//const PropertyList::PropertyMap *rendererProperties = this->GetDataNode()->GetPropertyList( renderer )->GetMap();
//const PropertyList::PropertyMap *globalProperties = this->GetDataNode()->GetPropertyList( NULL )->GetMap();
// Add clipping planes (if any)
/*
m_LabelActorCollection->RemoveAllItems();
PropertyList::PropertyMap::const_iterator it;
for ( it = rendererProperties->begin(); it != rendererProperties->end(); ++it )
{
this->CheckForAnnotationProperty( (*it).second.first.GetPointer(), renderer );
}
for ( it = globalProperties->begin(); it != globalProperties->end(); ++it )
{
this->CheckForAnnotationProperty( (*it).second.first.GetPointer(), renderer );
}
*/
}
}
/*
void VtkMapper3D::CheckForAnnotationProperty( mitk::BaseProperty *property, BaseRenderer *renderer )
{
AnnotationProperty *annotationProperty =
dynamic_cast< AnnotationProperty * >( property );
if ( annotationProperty != NULL )
{
vtkVectorText *labelText = vtkVectorText::New();
vtkPolyDataMapper *labelMapper = vtkPolyDataMapper::New();
labelMapper->SetInput( labelText->GetOutput() );
vtkFollower *labelFollower = vtkFollower::New();
labelFollower->SetMapper( labelMapper );
labelFollower->SetCamera( renderer->GetVtkRenderer()->GetActiveCamera() );
labelFollower->SetScale( 2.5, 2.5, 2.5 );
labelFollower->GetProperty()->SetColor( 1.0, 0.2, 0.1 );
labelText->SetText( annotationProperty->GetLabel() );
const Point3D &pos = annotationProperty->GetPosition();
Geometry3D *geometry = m_DataNode->GetData()->GetGeometry();
Point3D transformedPos;
geometry->IndexToWorld( pos, transformedPos );
labelFollower->SetPosition( transformedPos[0], transformedPos[1], transformedPos[2] );
//labelFollower->SetUserTransform(
// m_DataNode->GetData()->GetGeometry()->GetVtkTransform() );
m_LabelActorCollection->AddItem( labelFollower );
}
}
*/
void VtkMapper3D::ReleaseGraphicsResources(vtkWindow * /*renWin*/)
{
/*
if(m_Prop3D)
m_Prop3D->ReleaseGraphicsResources(renWin);
*/
}
bool VtkMapper3D::HasVtkProp( const vtkProp *prop, BaseRenderer *renderer )
{
vtkProp *myProp = this->GetVtkProp( renderer );
// TODO: check if myProp is a vtkAssembly and if so, check if prop is contained in its leafs
return ( prop == myProp );
}
} // namespace
diff --git a/Core/Code/Rendering/mitkVtkMapper3D.h b/Core/Code/Rendering/mitkVtkMapper3D.h
index bf7e42051a..8103cbe67e 100644
--- a/Core/Code/Rendering/mitkVtkMapper3D.h
+++ b/Core/Code/Rendering/mitkVtkMapper3D.h
@@ -1,113 +1,112 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 BASEVTKMAPPER3D_H_HEADER_INCLUDED
#define BASEVTKMAPPER3D_H_HEADER_INCLUDED
#include <MitkExports.h>
#include "mitkMapper.h"
#include "mitkMapper3D.h"
#include "mitkBaseRenderer.h"
#include "vtkMapper.h"
class vtkProp;
class vtkProp3D;
class vtkActor;
class vtkProp3DCollection;
namespace mitk {
//##Documentation
//## @brief Base class of all vtk-based 3D-Mappers
//##
//## GetProp() returns m_Prop3D, which should be
//## initialized by sub-classes (e.g., by setting
//## it to an vtkActor).
//## @ingroup Mapper
class MITK_CORE_EXPORT VtkMapper3D : public Mapper3D
{
public:
mitkClassMacro(VtkMapper3D, Mapper3D);
virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer) = 0;
static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper);
virtual void MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer);
virtual void MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer);
virtual void MitkRenderOverlay(mitk::BaseRenderer* renderer);
virtual void MitkRenderVolumetricGeometry(mitk::BaseRenderer* renderer);
//##Documentation
//## @brief Set the vtkTransform of the m_Prop3D for
//## the current time step of \a renderer
//##
//## Called by mitk::VtkPropRenderer::Update before rendering
//##
virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer);
//##Documentation
//## @brief Apply color and opacity read from the PropertyList
virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer);
/**
* \brief Release vtk-based graphics resources. Must be overwritten in
* subclasses if vtkProps additional to m_Prop3D are used.
*/
virtual void ReleaseGraphicsResources(vtkWindow *renWin);
/** \brief Returns true if this mapper owns the specified vtkProp for
* the given BaseRenderer.
*
* Note: returns false by default; should be implemented for VTK-based
* Mapper subclasses. */
virtual bool HasVtkProp( const vtkProp *prop, BaseRenderer *renderer );
/**
* \brief Returns whether this is an vtk-based mapper
*/
virtual bool IsVtkBased() const { return true; }
protected:
VtkMapper3D();
virtual ~VtkMapper3D();
/** Checks whether the specified property is a AnnotationProperty and if yes,
* adds it to m_LabelActorCollection (internal method). */
// virtual void CheckForAnnotationProperty( mitk::BaseProperty *property, BaseRenderer *renderer );
public:
itkGetObjectMacro(Geometry,Geometry3D);
itkSetObjectMacro(Geometry,Geometry3D);
protected:
Geometry3D::Pointer m_Geometry;
LevelWindow m_LevelWindow;
//vtkProp3D *m_Prop3D;
//vtkProp3DCollection *m_LabelActorCollection;
};
} // namespace mitk
#endif /* BASEVTKMAPPER3D_H_HEADER_INCLUDED */
diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.cpp b/Core/Code/Rendering/mitkVtkPropRenderer.cpp
index 5ea42204d3..9b88069173 100644
--- a/Core/Code/Rendering/mitkVtkPropRenderer.cpp
+++ b/Core/Code/Rendering/mitkVtkPropRenderer.cpp
@@ -1,931 +1,936 @@
-/*=========================================================================
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+/*===================================================================
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkPropRenderer.h"
// MAPPERS
#include "mitkMapper.h"
#include "mitkImageVtkMapper2D.h"
#include "mitkVtkMapper2D.h"
#include "mitkVtkMapper3D.h"
#include "mitkGeometry2DDataVtkMapper3D.h"
#include "mitkPointSetGLMapper2D.h"
#include "mitkImageSliceSelector.h"
#include "mitkRenderingManager.h"
#include "mitkGL.h"
#include "mitkGeometry3D.h"
#include "mitkDisplayGeometry.h"
#include "mitkLevelWindow.h"
#include "mitkCameraController.h"
#include "mitkVtkInteractorCameraController.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"
#include "mitkSurface.h"
#include "mitkNodePredicateDataType.h"
#include "mitkVtkInteractorStyle.h"
// VTK
#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkLight.h>
#include <vtkLightKit.h>
#include <vtkRenderWindow.h>
#include <vtkLinearTransform.h>
#include <vtkCamera.h>
#include <vtkWorldPointPicker.h>
#include <vtkPointPicker.h>
#include <vtkCellPicker.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkProp.h>
#include <vtkAssemblyPath.h>
#include <vtkAssemblyNode.h>
#include <vtkMapper.h>
#include <vtkSmartPointer.h>
#include <vtkTransform.h>
#include <vtkInteractorStyleTrackballCamera.h>
mitk::VtkPropRenderer::VtkPropRenderer( const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm )
: BaseRenderer(name,renWin, rm),
m_VtkMapperPresent(false),
m_NewRenderer(true),
m_CameraInitializedForMapperID(0)
{
didCount=false;
m_WorldPointPicker = vtkWorldPointPicker::New();
m_PointPicker = vtkPointPicker::New();
m_PointPicker->SetTolerance( 0.0025 );
m_CellPicker = vtkCellPicker::New();
m_CellPicker->SetTolerance( 0.0025 );
mitk::Geometry2DDataVtkMapper3D::Pointer geometryMapper = mitk::Geometry2DDataVtkMapper3D::New();
m_CurrentWorldGeometry2DMapper = geometryMapper;
m_CurrentWorldGeometry2DNode->SetMapper(2, geometryMapper);
m_LightKit = vtkLightKit::New();
m_LightKit->AddLightsToRenderer(m_VtkRenderer);
m_PickingMode = WorldPointPicking;
m_TextRenderer = vtkRenderer::New();
m_TextRenderer->SetRenderWindow(renWin);
m_TextRenderer->SetInteractive(0);
m_TextRenderer->SetErase(0);
}
/*!
\brief Destructs the VtkPropRenderer.
*/
mitk::VtkPropRenderer::~VtkPropRenderer()
{
// Workaround for GLDisplayList Bug
{
m_MapperID=0;
checkState();
}
if (m_LightKit != NULL)
m_LightKit->Delete();
if (m_VtkRenderer!=NULL)
{
m_CameraController = NULL;
m_VtkRenderer->Delete();
m_VtkRenderer = NULL;
}
else
m_CameraController = NULL;
if (m_WorldPointPicker != NULL)
m_WorldPointPicker->Delete();
if (m_PointPicker != NULL)
m_PointPicker->Delete();
if (m_CellPicker != NULL)
m_CellPicker->Delete();
if (m_TextRenderer != NULL)
m_TextRenderer->Delete();
}
void mitk::VtkPropRenderer::SetDataStorage( mitk::DataStorage* storage )
{
if ( storage == NULL )
return;
BaseRenderer::SetDataStorage(storage);
static_cast<mitk::Geometry2DDataVtkMapper3D*>(m_CurrentWorldGeometry2DMapper.GetPointer())->SetDataStorageForTexture( m_DataStorage.GetPointer() );
// Compute the geometry from the current data tree bounds and set it as world geometry
this->SetWorldGeometryToDataStorageBounds();
}
bool mitk::VtkPropRenderer::SetWorldGeometryToDataStorageBounds()
{
if ( m_DataStorage.IsNull() )
return false;
//initialize world geometry
mitk::TimeSlicedGeometry::Pointer geometry = m_DataStorage->ComputeVisibleBoundingGeometry3D( NULL, "includeInBoundingBox" );
if ( geometry.IsNull() )
return false;
this->SetWorldGeometry(geometry);
//this->GetDisplayGeometry()->SetSizeInDisplayUnits( this->m_TextRenderer->GetRenderWindow()->GetSize()[0], this->m_TextRenderer->GetRenderWindow()->GetSize()[1] );
this->GetDisplayGeometry()->Fit();
this->GetVtkRenderer()->ResetCamera();
this->Modified();
return true;
}
/*!
\brief
Called by the vtkMitkRenderProp in order to start MITK rendering process.
*/
int mitk::VtkPropRenderer::Render(mitk::VtkPropRenderer::RenderType type)
{
// Do we have objects to render?
if ( this->GetEmptyWorldGeometry())
return 0;
if ( m_DataStorage.IsNull())
return 0;
// Update mappers and prepare mapper queue
if (type == VtkPropRenderer::Opaque)
this->PrepareMapperQueue();
//go through the generated list and let the sorted mappers paint
bool lastVtkBased = true;
//bool sthVtkBased = false;
for(MappersMapType::iterator it = m_MappersMap.begin(); it != m_MappersMap.end(); it++)
{
Mapper * mapper = (*it).second;
if((mapper->IsVtkBased() == true) )
{
//sthVtkBased = true;
mitk::VtkMapper3D::Pointer vtkMapper = dynamic_cast<mitk::VtkMapper3D*>(mapper);
if(vtkMapper)
{
vtkMapper->GetVtkProp(this)->SetAllocatedRenderTime(5000,GetVtkRenderer()); //B/ ToDo: rendering time calculation
//vtkMapper->GetVtkProp(this)->PokeMatrix(NULL); //B/ ToDo ??: VtkUserTransform
}
if(lastVtkBased == false)
{
Disable2DOpenGL();
lastVtkBased = true;
}
}
else
if((mapper->IsVtkBased() == false) && (lastVtkBased == true))
{
Enable2DOpenGL();
lastVtkBased = false;
}
//Workarround for bug GL_TEXTURE_2D (bug #8188)
GLboolean mode;
GLenum bit = GL_TEXTURE_2D;
GLfloat lineWidth;
glGetFloatv(GL_LINE_WIDTH, &lineWidth);
glGetBooleanv(bit, &mode);
switch(type)
{
case mitk::VtkPropRenderer::Opaque: mapper->MitkRenderOpaqueGeometry(this); break;
case mitk::VtkPropRenderer::Translucent: mapper->MitkRenderTranslucentGeometry(this); break;
case mitk::VtkPropRenderer::Overlay: mapper->MitkRenderOverlay(this); break;
case mitk::VtkPropRenderer::Volumetric: mapper->MitkRenderVolumetricGeometry(this); break;
}
if(mode)
glEnable(bit);
else
glDisable(bit);
glLineWidth(lineWidth);
//end Workarround for bug GL_TEXTURE_2D (bug #8188)
}
if (lastVtkBased == false)
Disable2DOpenGL();
// Render text
if (type == VtkPropRenderer::Overlay)
{
if (m_TextCollection.size() > 0)
{
for (TextMapType::iterator it = m_TextCollection.begin(); it != m_TextCollection.end() ; it++)
m_TextRenderer->AddViewProp((*it).second);
m_TextRenderer->Render();
}
}
return 1;
}
/*!
\brief PrepareMapperQueue iterates the datatree
PrepareMapperQueue iterates the datatree in order to find mappers which shall be rendered. Also, it sortes the mappers wrt to their layer.
*/
void mitk::VtkPropRenderer::PrepareMapperQueue()
{
// variable for counting LOD-enabled mappers
m_NumberOfVisibleLODEnabledMappers = 0;
// Do we have to update the mappers ?
if ( m_LastUpdateTime < GetMTime() || m_LastUpdateTime < GetDisplayGeometry()->GetMTime() ) {
Update();
}
else if (m_MapperID>=1 && m_MapperID < 6)
Update();
// remove all text properties before mappers will add new ones
m_TextRenderer->RemoveAllViewProps();
for ( unsigned int i=0; i<m_TextCollection.size(); i++ )
{
m_TextCollection[i]->Delete();
}
m_TextCollection.clear();
// clear priority_queue
m_MappersMap.clear();
int mapperNo = 0;
//DataStorage
if( m_DataStorage.IsNull() )
return;
DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll();
for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it)
{
DataNode::Pointer node = it->Value();
if ( node.IsNull() )
continue;
mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID);
if ( mapper.IsNull() )
continue;
// The information about LOD-enabled mappers is required by RenderingManager
if ( mapper->IsLODEnabled( this ) && mapper->IsVisible( this ) )
{
++m_NumberOfVisibleLODEnabledMappers;
}
// mapper without a layer property get layer number 1
int layer = 1;
node->GetIntProperty("layer", layer, this);
int nr = (layer<<16) + mapperNo;
m_MappersMap.insert( std::pair< int, Mapper * >( nr, mapper ) );
mapperNo++;
}
}
/*!
\brief
Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection)
*/
void mitk::VtkPropRenderer::Enable2DOpenGL()
{
GLint iViewport[4];
// Get a copy of the viewport
glGetIntegerv( GL_VIEWPORT, iViewport );
// Save a copy of the projection matrix so that we can restore it
// when it's time to do 3D rendering again.
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
// Set up the orthographic projection
glOrtho(
iViewport[0], iViewport[0]+iViewport[2],
iViewport[1], iViewport[1]+iViewport[3],
-1.0, 1.0
);
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
// Make sure depth testing and lighting are disabled for 2D rendering until
// we are finished rendering in 2D
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT );
glDisable( GL_DEPTH_TEST );
glDisable( GL_LIGHTING );
}
/*!
\brief Initialize the VtkPropRenderer
Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection)
*/
void mitk::VtkPropRenderer::Disable2DOpenGL()
{
glPopAttrib();
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
void mitk::VtkPropRenderer::Update(mitk::DataNode* datatreenode)
{
if(datatreenode!=NULL)
{
mitk::Mapper::Pointer mapper = datatreenode->GetMapper(m_MapperID);
if(mapper.IsNotNull())
{
Mapper2D* mapper2d=dynamic_cast<Mapper2D*>(mapper.GetPointer());
if(mapper2d != NULL)
{
if(GetDisplayGeometry()->IsValid())
{
VtkMapper2D* vtkmapper2d=dynamic_cast<VtkMapper2D*>(mapper.GetPointer());
if(vtkmapper2d != NULL)
{
vtkmapper2d->Update(this);
m_VtkMapperPresent=true;
}
else
mapper2d->Update(this);
}
}
else
{
VtkMapper3D* vtkmapper3d=dynamic_cast<VtkMapper3D*>(mapper.GetPointer());
if(vtkmapper3d != NULL)
{
vtkmapper3d->Update(this);
vtkmapper3d->UpdateVtkTransform(this);
m_VtkMapperPresent=true;
}
}
}
}
}
void mitk::VtkPropRenderer::Update()
{
if( m_DataStorage.IsNull() )
return;
m_VtkMapperPresent = false;
mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetAll();
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it)
Update(it->Value());
Modified();
m_LastUpdateTime = GetMTime();
}
/*!
\brief
This method is called from the two Constructors
*/
void mitk::VtkPropRenderer::InitRenderer(vtkRenderWindow* renderWindow)
{
BaseRenderer::InitRenderer(renderWindow);
if(renderWindow == NULL)
{
m_InitNeeded = false;
m_ResizeNeeded = false;
return;
}
m_InitNeeded = true;
m_ResizeNeeded = true;
m_LastUpdateTime = 0;
}
/*!
\brief Resize the OpenGL Window
*/
void mitk::VtkPropRenderer::Resize(int w, int h)
{
BaseRenderer::Resize(w, h);
m_RenderingManager->RequestUpdate(this->GetRenderWindow());
}
void mitk::VtkPropRenderer::InitSize(int w, int h)
{
m_RenderWindow->SetSize(w,h);
Superclass::InitSize(w, h);
Modified();
Update();
if(m_VtkRenderer!=NULL)
{
int w=vtkObject::GetGlobalWarningDisplay();
vtkObject::GlobalWarningDisplayOff();
m_VtkRenderer->ResetCamera();
vtkObject::SetGlobalWarningDisplay(w);
}
}
void mitk::VtkPropRenderer::SetMapperID(const MapperSlotId mapperId)
{
if(m_MapperID != mapperId)
Superclass::SetMapperID(mapperId);
// Workaround for GL Displaylist Bug
checkState();
}
/*!
\brief Activates the current renderwindow.
*/
void mitk::VtkPropRenderer::MakeCurrent()
{
if(m_RenderWindow!=NULL)
m_RenderWindow->MakeCurrent();
}
void mitk::VtkPropRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const
{
if(m_VtkMapperPresent)
{
//m_WorldPointPicker->SetTolerance (0.0001);
switch ( m_PickingMode )
{
case (WorldPointPicking) :
{
m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer);
vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint);
break;
}
case (PointPicking) :
{
// create a new vtkRenderer
// give it all necessary information (camera position, etc.)
// get all surfaces from datastorage, get actors from them
// add all those actors to the new renderer
// give this new renderer to pointpicker
/*
vtkRenderer* pickingRenderer = vtkRenderer::New();
pickingRenderer->SetActiveCamera( );
DataStorage* dataStorage = m_DataStorage;
TNodePredicateDataType<Surface> isSurface;
DataStorage::SetOfObjects::ConstPointer allSurfaces = dataStorage->GetSubset( isSurface );
MITK_INFO << "in picking: got " << allSurfaces->size() << " surfaces." << std::endl;
for (DataStorage::SetOfObjects::const_iterator iter = allSurfaces->begin();
iter != allSurfaces->end();
++iter)
{
const DataNode* currentNode = *iter;
VtkMapper3D* baseVtkMapper3D = dynamic_cast<VtkMapper3D*>( currentNode->GetMapper( BaseRenderer::Standard3D ) );
if ( baseVtkMapper3D )
{
vtkActor* actor = dynamic_cast<vtkActor*>( baseVtkMapper3D->GetViewProp() );
if (actor)
{
MITK_INFO << "a" << std::flush;
pickingRenderer->AddActor( actor );
}
}
}
MITK_INFO << ";" << std::endl;
*/
m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer);
vtk2itk(m_PointPicker->GetPickPosition(), worldPoint);
break;
}
}
}
else
{
Superclass::PickWorldPoint(displayPoint, worldPoint);
}
}
mitk::DataNode *
mitk::VtkPropRenderer::PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const
{
if ( m_VtkMapperPresent )
{
m_CellPicker->InitializePickList();
// Iterate over all DataStorage objects to determine all vtkProps intended
// for picking
DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll();
for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin();
it != allObjects->End();
++it )
{
DataNode *node = it->Value();
if ( node == NULL )
continue;
bool pickable = false;
node->GetBoolProperty( "pickable", pickable );
if ( !pickable )
continue;
VtkMapper3D *mapper = dynamic_cast< VtkMapper3D * >
( node->GetMapper( m_MapperID ) );
if ( mapper == NULL )
continue;
vtkProp *prop = mapper->GetVtkProp( (mitk::BaseRenderer *)this );
if ( prop == NULL )
continue;
m_CellPicker->AddPickList( prop );
}
// Do the picking and retrieve the picked vtkProp (if any)
m_CellPicker->PickFromListOn();
m_CellPicker->Pick( displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer );
m_CellPicker->PickFromListOff();
vtk2itk( m_CellPicker->GetPickPosition(), worldPosition );
vtkProp *prop = m_CellPicker->GetViewProp();
if ( prop == NULL )
{
return NULL;
}
// Iterate over all DataStorage objects to determine if the retrieved
// vtkProp is owned by any associated mapper.
for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin();
it != allObjects->End();
++it)
{
DataNode::Pointer node = it->Value();
if ( node.IsNull() )
continue;
mitk::Mapper::Pointer mapper = node->GetMapper( m_MapperID );
if ( mapper.IsNull() )
continue;
if ( mapper->HasVtkProp( prop, const_cast< mitk::VtkPropRenderer * >( this ) ) )
{
return node;
}
}
return NULL;
}
else
{
return Superclass::PickObject( displayPosition, worldPosition );
}
};
/*!
\brief Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function
in order to get a vtkTextProperty. This property enables the setup of font, font size, etc.
*/
int mitk::VtkPropRenderer::WriteSimpleText(std::string text, double posX, double posY, double color1, double color2, double color3)
{
if(text.size() > 0)
{
vtkTextActor* textActor = vtkTextActor::New();
textActor->SetPosition(posX,posY);
textActor->SetInput(text.c_str());
textActor->GetTextProperty()->SetColor(color1, color2, color3); //TODO: Read color from node property
int text_id = m_TextCollection.size();
m_TextCollection.insert(TextMapType::value_type(text_id,textActor));
return text_id;
}
return -1;
}
/*!
\brief Can be used in order to get a vtkTextProperty for a specific text_id. This property enables the setup of font, font size, etc.
*/
vtkTextProperty* mitk::VtkPropRenderer::GetTextLabelProperty(int text_id)
{
return this->m_TextCollection[text_id]->GetTextProperty();
}
void mitk::VtkPropRenderer::InitPathTraversal()
{
if (m_DataStorage.IsNotNull())
{
m_PickingObjects = m_DataStorage->GetAll();
m_PickingObjectsIterator = m_PickingObjects->begin();
}
}
vtkAssemblyPath* mitk::VtkPropRenderer::GetNextPath()
{
if (m_DataStorage.IsNull() )
{
return NULL;
}
if ( m_PickingObjectsIterator == m_PickingObjects->end() )
{
return NULL;
}
vtkAssemblyPath* returnPath = vtkAssemblyPath::New();
//returnPath->Register(NULL);
bool success = false;
while (!success)
{
// loop until AddNode can be called successfully
const DataNode* node = *m_PickingObjectsIterator;
if (node)
{
Mapper* mapper = node->GetMapper( BaseRenderer::Standard3D );
if (mapper)
{
VtkMapper3D* vtkmapper = dynamic_cast<VtkMapper3D*>( mapper );
if (vtkmapper)
{
vtkProp* prop = vtkmapper->GetVtkProp(this);
if ( prop && prop->GetVisibility() )
{
// add to assembly path
returnPath->AddNode( prop, prop->GetMatrix() );
success = true;
}
}
}
}
++m_PickingObjectsIterator;
if ( m_PickingObjectsIterator == m_PickingObjects->end() ) break;
}
if ( success )
{
return returnPath;
}
else
{
return NULL;
}
}
void mitk::VtkPropRenderer::ReleaseGraphicsResources(vtkWindow *renWin)
{
if( m_DataStorage.IsNull() )
return;
DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll();
for (DataStorage::SetOfObjects::const_iterator iter = allObjects->begin(); iter != allObjects->end(); ++iter)
{
DataNode::Pointer node = *iter;
if ( node.IsNull() )
continue;
Mapper::Pointer mapper = node->GetMapper(m_MapperID);
if(mapper.IsNotNull())
mapper->ReleaseGraphicsResources(renWin);
}
}
const vtkWorldPointPicker *mitk::VtkPropRenderer::GetWorldPointPicker() const
{
return m_WorldPointPicker;
}
const vtkPointPicker *mitk::VtkPropRenderer::GetPointPicker() const
{
return m_PointPicker;
}
const vtkCellPicker *mitk::VtkPropRenderer::GetCellPicker() const
{
return m_CellPicker;
}
mitk::VtkPropRenderer::MappersMapType mitk::VtkPropRenderer::GetMappersMap() const
{
return m_MappersMap;
}
// Workaround for GL Displaylist bug
static int glWorkAroundGlobalCount = 0;
bool mitk::VtkPropRenderer::useImmediateModeRendering()
{
return glWorkAroundGlobalCount>1;
}
void mitk::VtkPropRenderer::checkState()
{
if (m_MapperID == Standard3D)
{
if (!didCount)
{
didCount = true;
glWorkAroundGlobalCount++;
if (glWorkAroundGlobalCount == 2)
{
MITK_INFO << "Multiple 3D Renderwindows active...: turning Immediate Rendering ON for legacy mappers";
// vtkMapper::GlobalImmediateModeRenderingOn();
}
//MITK_INFO << "GLOBAL 3D INCREASE " << glWorkAroundGlobalCount << "\n";
}
}
else
{
if(didCount)
{
didCount=false;
glWorkAroundGlobalCount--;
if(glWorkAroundGlobalCount==1)
{
MITK_INFO << "Single 3D Renderwindow active...: turning Immediate Rendering OFF for legacy mappers";
// vtkMapper::GlobalImmediateModeRenderingOff();
}
//MITK_INFO << "GLOBAL 3D DECREASE " << glWorkAroundGlobalCount << "\n";
}
}
}
//### Contains all methods which are neceassry before each VTK Render() call
void mitk::VtkPropRenderer::PrepareRender()
{
if ( this->GetMapperID() != m_CameraInitializedForMapperID )
{
Initialize2DvtkCamera(); //Set parallel projection etc.
}
AdjustCameraToScene(); //Prepare camera for 2D render windows
}
bool mitk::VtkPropRenderer::Initialize2DvtkCamera()
{
if ( this->GetMapperID() == Standard3D )
{
//activate parallel projection for 2D
this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(false);
this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( vtkInteractorStyleTrackballCamera::New() );
m_CameraInitializedForMapperID = Standard3D;
}
else if( this->GetMapperID() == Standard2D)
{
//activate parallel projection for 2D
this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true);
//turn the light out in the scene in order to render correct grey values.
//TODO Implement a property for light in the 2D render windows (in another method)
this->GetVtkRenderer()->RemoveAllLights();
this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( mitkVtkInteractorStyle::New() );
m_CameraInitializedForMapperID = Standard2D;
}
return true;
}
void mitk::VtkPropRenderer::AdjustCameraToScene(){
if(this->GetMapperID() == Standard2D)
{
const mitk::DisplayGeometry* displayGeometry = this->GetDisplayGeometry();
double objectHeightInMM = this->GetCurrentWorldGeometry2D()->GetExtentInMM(1);//the height of the current object slice in mm
double displayHeightInMM = displayGeometry->GetSizeInMM()[1]; //the display height in mm (gets smaller when you zoom in)
double zoomFactor = objectHeightInMM/displayHeightInMM; //displayGeometry->GetScaleFactorMMPerDisplayUnit()
//determine how much of the object can be displayed
Vector2D displayGeometryOriginInMM = displayGeometry->GetOriginInMM(); //top left of the render window (Origin)
Vector2D displayGeometryCenterInMM = displayGeometryOriginInMM + displayGeometry->GetSizeInMM()*0.5; //center of the render window: (Origin + Size/2)
//Scale the rendered object:
//The image is scaled by a single factor, because in an orthographic projection sizes
//are preserved (so you cannot scale X and Y axis with different parameters). The
//parameter sets the size of the total display-volume. If you set this to the image
//height, the image plus a border with the size of the image will be rendered.
//Therefore, the size is imageHeightInMM / 2.
this->GetVtkRenderer()->GetActiveCamera()->SetParallelScale(objectHeightInMM*0.5 );
//zooming with the factor calculated by dividing displayHeight through imegeHeight. The factor is inverse, because the VTK zoom method is working inversely.
this->GetVtkRenderer()->GetActiveCamera()->Zoom(zoomFactor);
//the center of the view-plane
double viewPlaneCenter[3];
viewPlaneCenter[0] = displayGeometryCenterInMM[0];
viewPlaneCenter[1] = displayGeometryCenterInMM[1];
viewPlaneCenter[2] = 0.0; //the view-plane is located in the XY-plane with Z=0.0
//define which direction is "up" for the ciamera (like default for vtk (0.0, 1.0, 0.0)
double cameraUp[3];
cameraUp[0] = 0.0;
cameraUp[1] = 1.0;
cameraUp[2] = 0.0;
//the position of the camera (center[0], center[1], 900000)
double cameraPosition[3];
cameraPosition[0] = viewPlaneCenter[0];
cameraPosition[1] = viewPlaneCenter[1];
cameraPosition[2] = 900000.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker.
//set the camera corresponding to the textured plane
vtkSmartPointer<vtkCamera> camera = this->GetVtkRenderer()->GetActiveCamera();
if (camera)
{
camera->SetPosition( cameraPosition ); //set the camera position on the textured plane normal (in our case this is the view plane normal)
camera->SetFocalPoint( viewPlaneCenter ); //set the focal point to the center of the textured plane
camera->SetViewUp( cameraUp ); //set the view-up for the camera
// double distance = sqrt((cameraPosition[2]-viewPlaneCenter[2])*(cameraPosition[2]-viewPlaneCenter[2]));
// camera->SetClippingRange(distance-50, distance+50); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker.
camera->SetClippingRange(0.1, 1000000); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker.
}
const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( this->GetCurrentWorldGeometry2D() );
if ( planeGeometry != NULL )
{
//Transform the camera to the current position (transveral, coronal and saggital plane).
//This is necessary, because the SetUserTransform() method does not manipulate the vtkCamera.
//(Without not all three planes would be visible).
vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
Point3D origin;
Vector3D right, bottom, normal;
origin = planeGeometry->GetOrigin();
right = planeGeometry->GetAxisVector( 0 ); // right = Extent of Image in mm (worldspace)
bottom = planeGeometry->GetAxisVector( 1 );
normal = planeGeometry->GetNormal();
right.Normalize();
bottom.Normalize();
normal.Normalize();
matrix->SetElement(0, 0, right[0]);
matrix->SetElement(1, 0, right[1]);
matrix->SetElement(2, 0, right[2]);
matrix->SetElement(0, 1, bottom[0]);
matrix->SetElement(1, 1, bottom[1]);
matrix->SetElement(2, 1, bottom[2]);
matrix->SetElement(0, 2, normal[0]);
matrix->SetElement(1, 2, normal[1]);
matrix->SetElement(2, 2, normal[2]);
matrix->SetElement(0, 3, origin[0]);
matrix->SetElement(1, 3, origin[1]);
matrix->SetElement(2, 3, origin[2]);
matrix->SetElement(3, 0, 0.0);
matrix->SetElement(3, 1, 0.0);
matrix->SetElement(3, 2, 0.0);
matrix->SetElement(3, 3, 1.0);
trans->SetMatrix(matrix);
//Transform the camera to the current position (transveral, coronal and saggital plane).
this->GetVtkRenderer()->GetActiveCamera()->ApplyTransform(trans);
}
}
}
diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.h b/Core/Code/Rendering/mitkVtkPropRenderer.h
index 79fae29200..f4832f62f5 100644
--- a/Core/Code/Rendering/mitkVtkPropRenderer.h
+++ b/Core/Code/Rendering/mitkVtkPropRenderer.h
@@ -1,241 +1,240 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-09-22 12:01:41 +0200 (Sa, 22 Sep 2007) $
-Version: $Revision: 12241 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D
#define MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D
#include <MitkExports.h>
#include "mitkBaseRenderer.h"
#include "mitkDataStorage.h"
#include "mitkRenderingManager.h"
#include <itkCommand.h>
#include <map>
#include <utility>
class vtkRenderWindow;
class vtkLight;
class vtkLightKit;
class vtkWorldPointPicker;
class vtkPointPicker;
class vtkCellPicker;
class vtkTextActor;
class vtkTextProperty;
class vtkAssemblyPath;
namespace mitk
{
class Mapper;
/*!
\brief VtkPropRenderer
VtkPropRenderer organizes the MITK rendering process. The MITK rendering process is completely integrated into the VTK rendering pipeline.
The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes.
VtkPropRenderer replaces the old OpenGLRenderer.
\sa rendering
\ingroup rendering
*/
class MITK_CORE_EXPORT VtkPropRenderer : public BaseRenderer
{
// Workaround for Displaylistbug
private:
bool didCount;
void checkState();
// Workaround END
public:
mitkClassMacro(VtkPropRenderer,BaseRenderer);
mitkNewMacro3Param(VtkPropRenderer, const char*, vtkRenderWindow *, mitk::RenderingManager* );
typedef std::map<int,Mapper*> MappersMapType;
// Render - called by vtkMitkRenderProp, returns the number of props rendered
enum RenderType{Opaque,Translucent,Overlay,Volumetric};
int Render(RenderType type);
/** \brief This methods contains all method neceassary before a VTK Render() call */
virtual void PrepareRender();
// Active current renderwindow
virtual void MakeCurrent();
virtual void SetDataStorage( mitk::DataStorage* storage ); ///< set the datastorage that will be used for rendering
virtual void InitRenderer(vtkRenderWindow* renderwindow);
virtual void Update(mitk::DataNode* datatreenode);
virtual void SetMapperID(const MapperSlotId mapperId);
// Size
virtual void InitSize(int w, int h);
virtual void Resize(int w, int h);
// Picking
enum PickingMode{ WorldPointPicking, PointPicking };
itkSetEnumMacro( PickingMode, PickingMode );
itkGetEnumMacro( PickingMode, PickingMode );
virtual void PickWorldPoint(const Point2D& displayPoint, Point3D& worldPoint) const;
virtual mitk::DataNode *PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const;
// Simple text rendering method
int WriteSimpleText(std::string text, double posX, double posY, double color1 = 0.0, double color2 = 1.0, double color3 = 0.0);
vtkTextProperty * GetTextLabelProperty(int text_id);
// Initialization / geometry handling
/** This method calculates the bounds of the DataStorage (if it contains any
* valid data), creates a geometry from these bounds and sets it as world
* geometry of the renderer.
*
* Call this method to re-initialize the renderer to the current DataStorage
* (e.g. after loading an additional dataset), to ensure that the view is
* aligned correctly.
*/
virtual bool SetWorldGeometryToDataStorageBounds();
/**
* \brief Used by vtkPointPicker/vtkPicker.
* This will query a list of all objects in MITK and provide every vtk based mapper to the picker.
*/
void InitPathTraversal();
/**
* \brief Used by vtkPointPicker/vtkPicker.
* This will query a list of all objects in MITK and provide every vtk based mapper to the picker.
*/
vtkAssemblyPath* GetNextPath();
const vtkWorldPointPicker *GetWorldPointPicker() const;
const vtkPointPicker *GetPointPicker() const;
const vtkCellPicker *GetCellPicker() const;
/**
* \brief Release vtk-based graphics resources. Called by
* vtkMitkRenderProp::ReleaseGraphicsResources.
*/
virtual void ReleaseGraphicsResources(vtkWindow *renWin);
MappersMapType GetMappersMap() const;
static bool useImmediateModeRendering();
protected:
VtkPropRenderer( const char* name = "VtkPropRenderer", vtkRenderWindow * renWin = NULL, mitk::RenderingManager* rm = NULL );
virtual ~VtkPropRenderer();
virtual void Update();
private:
/** \brief This method sets up the camera on the actor (e.g. an image) of all
* 2D vtkRenderWindows. The view is centered; zooming and panning of VTK are called inside.
*
* \image html ImageMapperdisplayGeometry.png
*
* Similar to the textured plane of an image
* (cf. void mitkImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer* renderer,
* vtkFloatingPointType planeBounds[6])), the mitkDisplayGeometry defines a view plane (or
* projection plane). This plane is used to set the camera parameters. The view plane
* center (VC) is important for camera positioning (cf. the image above).
*
* The following figure shows the combination of the textured plane and the view plane.
*
* \image html cameraPositioning.png
*
* The view plane center (VC) is the center of the textured plane (C) and the focal point
* (FP) at the same time. The FP defines the direction the camera faces. Since
* the textured plane is always in the XY-plane and orthographic projection is applied, the
* distance between camera and plane is theoretically irrelevant (because in the orthographic
* projection the center of projection is at infinity and the size of objects depends only on
* a scaling parameter). As a consequence, the direction of projection (DOP) is (0; 0; -1).
* The camera up vector is always defined as (0; 1; 0).
*
* \warning Due to a VTK clipping bug the distance between textured plane and camera is really huge.
* Otherwise, VTK would clip off some slices. Same applies for the clipping range size.
*
* \note The camera position is defined through the mitkDisplayGeometry.
* This facilitates zooming and panning, because the display
* geometry changes and the textured plane does not.
*
* \image html scaling.png
*
* The textured plane is scaled to fill the render window via
* camera->SetParallelScale( imageHeightInMM / 2). In the orthographic projection all extends,
* angles and sizes are preserved. Therefore, the image is scaled by one parameter which defines
* the size of the rendered image. A higher value will result in smaller images. In order to render
* just the whole image, the scale is set to half of the image height in worldcoordinates
* (cf. the picture above).
*
* For zooming purposes, a factor is computed as follows:
* factor = image height / display height (in worldcoordinates).
* When the display geometry gets smaller (zoom in), the factor becomes bigger. When the display
* geometry gets bigger (zoom out), the factor becomes smaller. The used VTK method
* camera->Zoom( factor ) also works with an inverse scale.
*/
void AdjustCameraToScene();
// switch between orthogonal opengl projection (2D rendering via mitk::GLMapper2D) and perspective projection (3D rendering)
void Enable2DOpenGL();
void Disable2DOpenGL();
// prepare all mitk::mappers for rendering
void PrepareMapperQueue();
/** \brief Set parallel projection, remove the interactor and the lights of VTK. */
bool Initialize2DvtkCamera();
bool m_InitNeeded;
bool m_ResizeNeeded;
bool m_VtkMapperPresent;
bool m_NewRenderer;
MapperSlotId m_CameraInitializedForMapperID;
// Picking
vtkWorldPointPicker * m_WorldPointPicker;
vtkPointPicker * m_PointPicker;
vtkCellPicker * m_CellPicker;
PickingMode m_PickingMode;
// Explicit use of SmartPointer to avoid circular #includes
itk::SmartPointer< mitk::Mapper > m_CurrentWorldGeometry2DMapper;
vtkLightKit* m_LightKit;
// sorted list of mappers
MappersMapType m_MappersMap;
// rendering of text
vtkRenderer * m_TextRenderer;
typedef std::map<unsigned int,vtkTextActor*> TextMapType;
TextMapType m_TextCollection;
DataStorage::SetOfObjects::ConstPointer m_PickingObjects;
DataStorage::SetOfObjects::const_iterator m_PickingObjectsIterator;
};
} // namespace mitk
#endif /* MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D */
diff --git a/Core/Code/Rendering/mitkVtkWidgetRendering.cpp b/Core/Code/Rendering/mitkVtkWidgetRendering.cpp
index 346cef22a4..ac431a5071 100644
--- a/Core/Code/Rendering/mitkVtkWidgetRendering.cpp
+++ b/Core/Code/Rendering/mitkVtkWidgetRendering.cpp
@@ -1,174 +1,173 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-12-18 16:04:12 +0100 (Di, 18 Dez 2007) $
-Version: $Revision: 13252 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkVtkWidgetRendering.h"
#include "mitkVtkLayerController.h"
#include <mitkConfig.h>
#include <itkObject.h>
#include <itkMacro.h>
#include <itksys/SystemTools.hxx>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkObjectFactory.h>
#include <vtkRendererCollection.h>
#include <vtkInteractorObserver.h>
#include <algorithm>
mitk::VtkWidgetRendering::VtkWidgetRendering()
: m_RenderWindow( NULL ),
m_VtkWidget( NULL ),
m_IsEnabled( false )
{
m_Renderer = vtkRenderer::New();
}
mitk::VtkWidgetRendering::~VtkWidgetRendering()
{
if ( m_RenderWindow != NULL )
if ( this->IsEnabled() )
this->Disable();
if ( m_Renderer != NULL )
m_Renderer->Delete();
}
/**
* Sets the renderwindow, in which the widget
* will be shown. Make sure, you have called this function
* before calling Enable()
*/
void mitk::VtkWidgetRendering::SetRenderWindow( vtkRenderWindow* renderWindow )
{
m_RenderWindow = renderWindow;
}
/**
* Returns the vtkRenderWindow, which is used
* for displaying the widget
*/
vtkRenderWindow* mitk::VtkWidgetRendering::GetRenderWindow()
{
return m_RenderWindow;
}
/**
* Returns the renderer responsible for
* rendering the widget into the
* vtkRenderWindow
*/
vtkRenderer* mitk::VtkWidgetRendering::GetVtkRenderer()
{
return m_Renderer;
}
/**
* Enables drawing of the widget.
* If you want to disable it, call the Disable() function.
*/
void mitk::VtkWidgetRendering::Enable()
{
if(m_IsEnabled)
return;
if(m_RenderWindow != NULL)
{
vtkRenderWindowInteractor *interactor = m_RenderWindow->GetInteractor();
if ( m_VtkWidget != NULL )
{
m_VtkWidget->SetInteractor( interactor );
mitk::VtkLayerController *layerController =
mitk::VtkLayerController::GetInstance(m_RenderWindow);
if ( layerController )
{
layerController->InsertForegroundRenderer(m_Renderer,false);
}
m_IsEnabled = true;
}
}
}
/**
* Disables drawing of the widget.
* If you want to enable it, call the Enable() function.
*/
void mitk::VtkWidgetRendering::Disable()
{
if ( this->IsEnabled() )
{
mitk::VtkLayerController *layerController =
mitk::VtkLayerController::GetInstance(m_RenderWindow);
if ( layerController )
{
layerController->RemoveRenderer(m_Renderer);
}
m_IsEnabled = false;
}
}
/**
* Checks, if the widget is currently
* enabled (visible)
*/
bool mitk::VtkWidgetRendering::IsEnabled()
{
return m_IsEnabled;
}
void mitk::VtkWidgetRendering::SetRequestedRegionToLargestPossibleRegion()
{
//nothing to do
}
bool mitk::VtkWidgetRendering::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::VtkWidgetRendering::VerifyRequestedRegion()
{
return true;
}
void mitk::VtkWidgetRendering::SetRequestedRegion(itk::DataObject*)
{
//nothing to do
}
void mitk::VtkWidgetRendering::SetVtkWidget( vtkInteractorObserver *widget )
{
m_VtkWidget = widget;
}
vtkInteractorObserver *mitk::VtkWidgetRendering::GetVtkWidget() const
{
return m_VtkWidget;
}
diff --git a/Core/Code/Rendering/mitkVtkWidgetRendering.h b/Core/Code/Rendering/mitkVtkWidgetRendering.h
index d4d4f144d2..f60bfc6b28 100644
--- a/Core/Code/Rendering/mitkVtkWidgetRendering.h
+++ b/Core/Code/Rendering/mitkVtkWidgetRendering.h
@@ -1,143 +1,142 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-08 13:23:19 +0100 (Fr, 08 Feb 2008) $
-Version: $Revision: 13561 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/ for details.
+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 the above copyright notices for more information.
+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 _vtk_Widget_Rendering_h_
#define _vtk_Widget_Rendering_h_
#include <mitkBaseData.h>
class vtkRenderer;
class vtkRenderWindow;
class vtkInteractorObserver;
namespace mitk {
class RenderWindow;
/**
* \brief Mechanism for rendering a vtkWidget in the foreground of a RenderWindow.
*
* To use this class, specify the vtkRenderWindow of the window into which the
* vtkWidget shall be placed, and set the vtkWidget using SetVtkWidget().
* After enabling the vtkWidget and calling Enable() of this class, the widget
* should be rendered.
*
* Note: this class only provides a basic mechanism for adding widget; all widget
* configuration such as placement, size, and en-/disabling of interaction
* mechanisms need to be done in the vtkWidget object.
*/
class MITK_CORE_EXPORT VtkWidgetRendering : public BaseData
{
public:
mitkClassMacro( VtkWidgetRendering, BaseData );
itkNewMacro( Self );
/**
* Sets the renderwindow, in which the widget
* will be shown. Make sure, you have called this function
* before calling Enable()
*/
virtual void SetRenderWindow( vtkRenderWindow* renderWindow );
/**
* Enables drawing of the widget.
* If you want to disable it, call the Disable() function.
*/
virtual void Enable();
/**
* Disables drawing of the widget.
* If you want to enable it, call the Enable() function.
*/
virtual void Disable();
/**
* Checks, if the widget is currently
* enabled (visible)
*/
virtual bool IsEnabled();
/**
* Empty implementation, since the VtkWidgetRendering doesn't
* support the requested region concept
*/
virtual void SetRequestedRegionToLargestPossibleRegion();
/**
* Empty implementation, since the VtkWidgetRendering doesn't
* support the requested region concept
*/
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
/**
* Empty implementation, since the VtkWidgetRendering doesn't
* support the requested region concept
*/
virtual bool VerifyRequestedRegion();
/**
* Empty implementation, since the VtkWidgetRendering doesn't
* support the requested region concept
*/
virtual void SetRequestedRegion(itk::DataObject*);
/**
* Returns the vtkRenderWindow, which is used
* for displaying the widget
*/
virtual vtkRenderWindow* GetRenderWindow();
/**
* Returns the renderer responsible for
* rendering the widget into the
* vtkRenderWindow
*/
virtual vtkRenderer* GetVtkRenderer();
/** Set the vtkWidget to be rendered */
void SetVtkWidget( vtkInteractorObserver *widget );
/** Get the vtkWidget to be rendered */
vtkInteractorObserver *GetVtkWidget() const;
protected:
/**
* Constructor
*/
VtkWidgetRendering();
/**
* Destructor
*/
~VtkWidgetRendering();
vtkRenderWindow* m_RenderWindow;
vtkRenderer* m_Renderer;
vtkInteractorObserver *m_VtkWidget;
bool m_IsEnabled;
};
} //end of namespace mitk
#endif
diff --git a/Core/Code/Rendering/vtkMitkApplyLevelWindowToRGBFilter.cpp b/Core/Code/Rendering/vtkMitkApplyLevelWindowToRGBFilter.cpp
index bb6dfd66c9..e3b973fe36 100644
--- a/Core/Code/Rendering/vtkMitkApplyLevelWindowToRGBFilter.cpp
+++ b/Core/Code/Rendering/vtkMitkApplyLevelWindowToRGBFilter.cpp
@@ -1,266 +1,265 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "vtkMitkApplyLevelWindowToRGBFilter.h"
#include <vtkImageData.h>
#include <vtkImageIterator.h>
#include <vtkLookupTable.h>
//used for acos etc.
#include <cmath>
//used for PI
#include <itkMath.h>
static const double PI = itk::Math::pi;
vtkMitkApplyLevelWindowToRGBFilter::vtkMitkApplyLevelWindowToRGBFilter():m_MinOqacity(0.0),m_MaxOpacity(255.0)
{
}
vtkMitkApplyLevelWindowToRGBFilter::~vtkMitkApplyLevelWindowToRGBFilter()
{
}
void vtkMitkApplyLevelWindowToRGBFilter::SetLookupTable(vtkScalarsToColors *lookupTable)
{
m_LookupTable = lookupTable;
}
vtkScalarsToColors* vtkMitkApplyLevelWindowToRGBFilter::GetLookupTable()
{
return m_LookupTable;
}
//This code was copied from the iil. The template works only for float and double.
//Internal method which should never be used anywhere else and should not be in th header.
// Convert color pixels from (R,G,B) to (H,S,I).
// Reference: "Digital Image Processing, 2nd. edition", R. Gonzalez and R. Woods. Prentice Hall, 2002.
template<class T>
void RGBtoHSI(T* RGB, T* HSI)
{
T R = RGB[0],
G = RGB[1],
B = RGB[2],
nR = (R<0?0:(R>255?255:R))/255,
nG = (G<0?0:(G>255?255:G))/255,
nB = (B<0?0:(B>255?255:B))/255,
m = nR<nG?(nR<nB?nR:nB):(nG<nB?nG:nB),
theta = (T)(std::acos(0.5f*((nR-nG)+(nR-nB))/std::sqrt(std::pow(nR-nG,2)+(nR-nB)*(nG-nB)))*180/PI),
sum = nR + nG + nB;
T H = 0, S = 0, I = 0;
if (theta>0) H = (nB<=nG)?theta:360-theta;
if (sum>0) S = 1 - 3/sum*m;
I = sum/3;
HSI[0] = (T)H;
HSI[1] = (T)S;
HSI[2] = (T)I;
}
//This code was copied from the iil. The template works only for float and double.
//Internal method which should never be used anywhere else and should not be in th header.
// Convert color pixels from (H,S,I) to (R,G,B).
template<class T>
void HSItoRGB(T* HSI, T* RGB)
{
T H = (T)HSI[0],
S = (T)HSI[1],
I = (T)HSI[2],
a = I*(1-S),
R = 0, G = 0, B = 0;
if (H<120) {
B = a;
R = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180)));
G = 3*I-(R+B);
} else if (H<240) {
H-=120;
R = a;
G = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180)));
B = 3*I-(R+G);
} else {
H-=240;
G = a;
B = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180)));
R = 3*I-(G+B);
}
R*=255; G*=255; B*=255;
RGB[0] = (T)(R<0?0:(R>255?255:R));
RGB[1] = (T)(G<0?0:(G>255?255:G));
RGB[2] = (T)(B<0?0:(B>255?255:B));
}
//Internal method which should never be used anywhere else and should not be in th header.
//----------------------------------------------------------------------------
// This templated function executes the filter for any type of data.
template <class T>
void vtkCalculateIntensityFromLookupTable(vtkMitkApplyLevelWindowToRGBFilter *self,
vtkImageData *inData,
vtkImageData *outData,
int outExt[6], T *)
{
vtkImageIterator<T> inputIt(inData, outExt);
vtkImageIterator<T> outputIt(outData, outExt);
vtkLookupTable* lookupTable;
int maxC;
int indexComponents = 3; //RGB case
double imgRange[2];
double tableRange[2];
lookupTable = dynamic_cast<vtkLookupTable*>(self->GetLookupTable());
lookupTable->GetTableRange(tableRange);
inData->GetScalarRange(imgRange);
//parameters for RGB level window
double scale = (tableRange[1] -tableRange[0] > 0 ? 255.0 / (tableRange[1] - tableRange[0]) : 0.0);
double bias = tableRange[0] * scale;
// find the region to loop over
maxC = inData->GetNumberOfScalarComponents();
//parameters for opaque level window
double scaleOpac = (self->GetMaxOpacity() -self->GetMinOpacity() > 0 ? 255.0 / (self->GetMaxOpacity() - self->GetMinOpacity()) : 0.0);
double biasOpac = self->GetMinOpacity() * scaleOpac;
// Loop through ouput pixels
while (!outputIt.IsAtEnd())
{
T* inputSI = inputIt.BeginSpan();
T* outputSI = outputIt.BeginSpan();
T* outputSIEnd = outputIt.EndSpan();
while (outputSI != outputSIEnd)
{
double rgb[3], alpha, hsi[3];
// level/window mechanism for intensity in HSI space
rgb[0] = static_cast<double>(*inputSI); inputSI++;
rgb[1] = static_cast<double>(*inputSI); inputSI++;
rgb[2] = static_cast<double>(*inputSI); inputSI++;
RGBtoHSI<double>(rgb,hsi);
hsi[2] = hsi[2] * 255.0 * scale - bias;
hsi[2] = (hsi[2] > 255.0 ? 255 : (hsi[2] < 0.0 ? 0 : hsi[2]));
hsi[2] /= 255.0;
HSItoRGB<double>(hsi,rgb);
*outputSI = static_cast<T>(rgb[0]); outputSI++;
*outputSI = static_cast<T>(rgb[1]); outputSI++;
*outputSI = static_cast<T>(rgb[2]); outputSI++;
//RGBA case
if(maxC >= 4)
{
indexComponents = 4; //now its the RGBA case
// level/window mechanism for opacity
alpha = static_cast<double>(*inputSI); inputSI++;
alpha = alpha * scaleOpac - biasOpac;
if(alpha > 255.0)
{
alpha = 255.0;
}
else if(alpha < 0.0)
{
alpha = 0.0;
}
*outputSI = static_cast<T>(alpha); outputSI++;
}
for (int i = indexComponents; i < maxC; i++)
{
*outputSI++ = *inputSI++;
}
}
inputIt.NextSpan();
outputIt.NextSpan();
}
}
void vtkMitkApplyLevelWindowToRGBFilter::ExecuteInformation()
{
vtkImageData *input = this->GetInput();
vtkImageData *output = this->GetOutput();
if (!input)
{
vtkErrorMacro(<< "Input not set.");
return;
}
output->CopyTypeSpecificInformation( input );
int extent[6];
input->GetWholeExtent(extent);
output->SetExtent(extent);
output->SetWholeExtent(extent);
output->SetUpdateExtent(extent);
output->AllocateScalars();
switch (input->GetScalarType())
{
vtkTemplateMacro(
vtkCalculateIntensityFromLookupTable( this,
input,
output, extent,
static_cast<VTK_TT *>(0)));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
//Method to run the filter in different threads.
void vtkMitkApplyLevelWindowToRGBFilter::ThreadedExecute(vtkImageData *inData,
vtkImageData *outData,
int extent[6], int /*id*/)
{
switch (inData->GetScalarType())
{
vtkTemplateMacro(
vtkCalculateIntensityFromLookupTable( this,
inData,
outData,
extent,
static_cast<VTK_TT *>(0)));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
void vtkMitkApplyLevelWindowToRGBFilter::ExecuteInformation(
vtkImageData *vtkNotUsed(inData), vtkImageData *vtkNotUsed(outData))
{
}
void vtkMitkApplyLevelWindowToRGBFilter::SetMinOpacity(double minOpacity)
{
m_MinOqacity = minOpacity;
}
inline double vtkMitkApplyLevelWindowToRGBFilter::GetMinOpacity() const
{
return m_MinOqacity;
}
void vtkMitkApplyLevelWindowToRGBFilter::SetMaxOpacity(double maxOpacity)
{
m_MaxOpacity = maxOpacity;
}
inline double vtkMitkApplyLevelWindowToRGBFilter::GetMaxOpacity() const
{
return m_MaxOpacity;
}
diff --git a/Core/Code/Rendering/vtkMitkApplyLevelWindowToRGBFilter.h b/Core/Code/Rendering/vtkMitkApplyLevelWindowToRGBFilter.h
index 73db7a85c3..61bc6d89af 100644
--- a/Core/Code/Rendering/vtkMitkApplyLevelWindowToRGBFilter.h
+++ b/Core/Code/Rendering/vtkMitkApplyLevelWindowToRGBFilter.h
@@ -1,81 +1,80 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
-Version: $Revision: 18127 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 __vtkMitkApplyLevelWindowToRGBFilter_h
#define __vtkMitkApplyLevelWindowToRGBFilter_h
class vtkScalarsToColors;
#include <vtkImageData.h>
#include <vtkImageToImageFilter.h>
#include <MitkExports.h>
/** Documentation
* \brief Applies the color and opacity level window to RGB(A) images.
*
* This filter is used to apply the color level window to RBG images (e.g.
* diffusion tensor images). Therefore, the RGB channels are converted to
* the HSI color space, where the level window can be applied. Afterwards,
* the HSI values transformed back to the RGB space.
*
* The filter is also able to apply an opacity level window to RGBA images.
*
* \ingroup Renderer
*/
class MITK_CORE_EXPORT vtkMitkApplyLevelWindowToRGBFilter : public vtkImageToImageFilter
{
public:
/** \brief Get the lookup table for the RGB level window */
vtkScalarsToColors* GetLookupTable();
/** \brief Set the lookup table for the RGB level window */
void SetLookupTable(vtkScalarsToColors *lookupTable);
/** \brief Get/Set the lower window opacity for the alpha level window */
void SetMinOpacity(double minOpacity);
inline double GetMinOpacity() const;
/** \brief Get/Set the upper window opacity for the alpha level window */
void SetMaxOpacity(double maxOpacity);
inline double GetMaxOpacity() const;
/** Default constructor. */
vtkMitkApplyLevelWindowToRGBFilter();
/** Default deconstructor. */
~vtkMitkApplyLevelWindowToRGBFilter();
protected:
/** \brief Method for threaded execution of the filter.
* \param *inData: The input.
* \param *outData: The output of the filter.
* \param extent[6]: Specefies the region of the image to be updated inside this thread.
* It is a six-component array of the form (xmin, xmax, ymin, ymax, zmin, zmax).
* \param id: The thread id.
*/
void ThreadedExecute(vtkImageData *inData, vtkImageData *outData,int extent[6], int id);
/** Standard VTK filter method to apply the filter. See VTK documentation.*/
void ExecuteInformation();
/** Standard VTK filter method to apply the filter. See VTK documentation. Not used at the moment.*/
void ExecuteInformation(vtkImageData *vtkNotUsed(inData), vtkImageData *vtkNotUsed(outData));
private:
/** m_LookupTable contains the lookup table for the RGB level window.*/
vtkScalarsToColors* m_LookupTable;
/** m_MinOqacity contains the lower bound for the alpha level window.*/
double m_MinOqacity;
/** m_MinOqacity contains the upper bound for the alpha level window.*/
double m_MaxOpacity;
};
#endif
diff --git a/Core/Code/Rendering/vtkMitkRectangleProp.cpp b/Core/Code/Rendering/vtkMitkRectangleProp.cpp
index 08d5b7a282..d9958b611e 100644
--- a/Core/Code/Rendering/vtkMitkRectangleProp.cpp
+++ b/Core/Code/Rendering/vtkMitkRectangleProp.cpp
@@ -1,129 +1,128 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-08-17 16:41:18 +0200 (Fr, 17 Aug 2007) $
-Version: $Revision: 11618 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "vtkMitkRectangleProp.h"
#include "vtkObjectFactory.h"
#include "mitkGL.h"
vtkStandardNewMacro(vtkMitkRectangleProp);
vtkMitkRectangleProp::vtkMitkRectangleProp()
{
}
vtkMitkRectangleProp::~vtkMitkRectangleProp()
{
}
double *vtkMitkRectangleProp::GetBounds()
{
return NULL;
}
int vtkMitkRectangleProp::RenderOverlay(vtkViewport* /*viewport*/)
{
m_RenderWindow->MakeCurrent();
Enable2DOpenGL();
//make it nicer
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
//size and position
int * i = m_RenderWindow->GetSize();
GLfloat bbox[8] = {0.f , 0.f, (float)i[0], 0.f, (float)i[0], (float)i[1], 0.f, (float)i[1]};
//render rectangle
glLineWidth(5.0f);
glBegin(GL_LINE_LOOP);
for (int j = 0; j < 4; j++)
{
glColor3f(m_Color[0],m_Color[1],m_Color[2]);
glVertex2fv(&bbox[2*j]);
}
glEnd();
glLineWidth(1.0f);
glDisable(GL_LINE_SMOOTH);
Disable2DOpenGL();
return 1;
}
void vtkMitkRectangleProp::SetRenderWindow(vtkRenderWindow* renWin)
{
m_RenderWindow = renWin;
}
void vtkMitkRectangleProp::SetColor(float col1, float col2, float col3)
{
m_Color[0] = col1;
m_Color[1] = col2;
m_Color[2] = col3;
}
int vtkMitkRectangleProp::RenderTranslucentGeometry(vtkViewport* /*viewport*/)
{
return 0;
}
int vtkMitkRectangleProp::RenderOpaqueGeometry(vtkViewport* /*viewport*/)
{
return 0;
}
void vtkMitkRectangleProp::Enable2DOpenGL()
{
GLint iViewport[4];
// Get a copy of the viewport
glGetIntegerv( GL_VIEWPORT, iViewport );
// Save a copy of the projection matrix so that we can restore it
// when it's time to do 3D rendering again.
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
// Set up the orthographic projection
glOrtho( iViewport[0], iViewport[0]+iViewport[2],
iViewport[1]+iViewport[3], iViewport[1], -1, 1 );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
// Make sure depth testing and lighting are disabled for 2D rendering until
// we are finished rendering in 2D
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT | GL_TEXTURE_2D);
glDisable( GL_DEPTH_TEST );
glDisable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
}
void vtkMitkRectangleProp::Disable2DOpenGL()
{
glPopAttrib();
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
diff --git a/Core/Code/Rendering/vtkMitkRectangleProp.h b/Core/Code/Rendering/vtkMitkRectangleProp.h
index a5e25e9b35..e9be714f75 100644
--- a/Core/Code/Rendering/vtkMitkRectangleProp.h
+++ b/Core/Code/Rendering/vtkMitkRectangleProp.h
@@ -1,57 +1,56 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2006-05-04 16:45:18 +0200 (Do, 04 Mai 2006) $
-Version: $Revision: 6790 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 vtkMitkRectangleProp_H_HEADER_INCLUDED_C1C53723
#define vtkMitkRectangleProp_H_HEADER_INCLUDED_C1C53723
#include "vtkActor2D.h"
#include "vtkRenderWindow.h"
#include <MitkExports.h>
class MITK_CORE_EXPORT vtkMitkRectangleProp : public vtkProp
{
public:
static vtkMitkRectangleProp* New();
vtkTypeMacro(vtkMitkRectangleProp,vtkProp);
int RenderOpaqueGeometry(vtkViewport* viewport);
int RenderTranslucentGeometry(vtkViewport* viewport);
int RenderOverlay(vtkViewport* viewport);
void SetRenderWindow(vtkRenderWindow* renWin);
void SetColor(float col1, float col2, float col3);
double* GetBounds();
protected:
vtkMitkRectangleProp();
virtual ~vtkMitkRectangleProp();
void Enable2DOpenGL();
void Disable2DOpenGL();
vtkRenderWindow* m_RenderWindow;
float m_Color[3];
};
#endif /* vtkMitkRectangleProp_H_HEADER_INCLUDED_C1C53723 */
diff --git a/Core/Code/Rendering/vtkMitkRenderProp.cpp b/Core/Code/Rendering/vtkMitkRenderProp.cpp
index 33f4226f97..f458de210c 100644
--- a/Core/Code/Rendering/vtkMitkRenderProp.cpp
+++ b/Core/Code/Rendering/vtkMitkRenderProp.cpp
@@ -1,125 +1,125 @@
-/*=========================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-08-17 16:41:18 +0200 (Fr, 17 Aug 2007) $
-Version: $Revision: 11618 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "vtkMitkRenderProp.h"
#include <vtkObjectFactory.h>
#include <vtkLODProp3D.h>
#include <vtkPropAssembly.h>
#include "mitkVtkMapper3D.h"
#include "mitkVtkMapper2D.h"
vtkStandardNewMacro(vtkMitkRenderProp);
vtkMitkRenderProp::vtkMitkRenderProp()
{
}
vtkMitkRenderProp::~vtkMitkRenderProp()
{
}
double *vtkMitkRenderProp::GetBounds()
{
return const_cast<double*>(m_VtkPropRenderer->GetBounds());
}
void vtkMitkRenderProp::SetPropRenderer(mitk::VtkPropRenderer::Pointer propRenderer)
{
this->m_VtkPropRenderer = propRenderer;
}
int vtkMitkRenderProp::RenderOpaqueGeometry(vtkViewport* /*viewport*/)
{
return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Opaque);
}
int vtkMitkRenderProp::RenderOverlay(vtkViewport* /*viewport*/)
{
return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Overlay);
}
void vtkMitkRenderProp::ReleaseGraphicsResources(vtkWindow* window)
{
m_VtkPropRenderer->ReleaseGraphicsResources(window);
}
void vtkMitkRenderProp::InitPathTraversal()
{
m_VtkPropRenderer->InitPathTraversal();
}
vtkAssemblyPath* vtkMitkRenderProp::GetNextPath()
{
return m_VtkPropRenderer->GetNextPath();
}
//BUG (#1551) added method depth peeling
int vtkMitkRenderProp::HasTranslucentPolygonalGeometry()
{
typedef std::map<int,mitk::Mapper*> MappersMapType;
MappersMapType mappersMap = m_VtkPropRenderer->GetMappersMap();
for(MappersMapType::iterator it = mappersMap.begin(); it != mappersMap.end(); it++)
{
mitk::Mapper * mapper = (*it).second;
mitk::VtkMapper3D::Pointer vtkMapper3D = dynamic_cast<mitk::VtkMapper3D*>(mapper);
if(vtkMapper3D)
{
// Due to VTK 5.2 bug, we need to initialize the Paths object in vtkPropAssembly
// manually (see issue #8186 committed to VTK's Mantis issue tracker)
// --> VTK bug resolved on 2008-12-01
vtkPropAssembly *propAssembly = dynamic_cast< vtkPropAssembly * >(
vtkMapper3D->GetVtkProp(m_VtkPropRenderer) );
if ( propAssembly )
{
propAssembly->InitPathTraversal();
}
if (vtkMapper3D->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry()==1)
return 1;
}
//TODO bad solution.
mitk::VtkMapper2D::Pointer vtkMapper2D = dynamic_cast<mitk::VtkMapper2D*>(mapper);
if(vtkMapper2D)
{
// Due to VTK 5.2 bug, we need to initialize the Paths object in vtkPropAssembly
// manually (see issue #8186 committed to VTK's Mantis issue tracker)
// --> VTK bug resolved on 2008-12-01
vtkPropAssembly *propAssembly = dynamic_cast< vtkPropAssembly * >(
vtkMapper2D->GetVtkProp(m_VtkPropRenderer) );
if ( propAssembly )
{
propAssembly->InitPathTraversal(); //TODO why is this called here???
}
if (vtkMapper2D->GetVtkProp(m_VtkPropRenderer)->HasTranslucentPolygonalGeometry()==1) {
return 1;
}
}
}
return 0;
}
int vtkMitkRenderProp::RenderTranslucentPolygonalGeometry( vtkViewport * )
{
return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Translucent);
}
int vtkMitkRenderProp::RenderVolumetricGeometry( vtkViewport * )
{
return m_VtkPropRenderer->Render(mitk::VtkPropRenderer::Volumetric);
}
diff --git a/Core/Code/Rendering/vtkMitkRenderProp.h b/Core/Code/Rendering/vtkMitkRenderProp.h
index 87047a2d7b..e6dbde1121 100644
--- a/Core/Code/Rendering/vtkMitkRenderProp.h
+++ b/Core/Code/Rendering/vtkMitkRenderProp.h
@@ -1,80 +1,79 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2006-05-04 16:45:18 +0200 (Do, 04 Mai 2006) $
-Version: $Revision: 6790 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723
#define VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723
#include "vtkProp.h"
#include "mitkVtkPropRenderer.h"
/*!
\brief vtkMitkRenderProp
The MITK rendering process is completely integrated into the VTK rendering pipeline.
The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes.
\sa rendering
\ingroup rendering
*/
class MITK_CORE_EXPORT vtkMitkRenderProp : public vtkProp
{
public:
static vtkMitkRenderProp *New();
vtkTypeMacro(vtkMitkRenderProp,vtkProp);
void SetPropRenderer(mitk::VtkPropRenderer::Pointer propRenderer);
int RenderOpaqueGeometry(vtkViewport* viewport);
int RenderOverlay(vtkViewport* viewport);
double *GetBounds();
void ReleaseGraphicsResources(vtkWindow* window);
/**
* \brief Used by vtkPointPicker/vtkPicker.
* This will query a list of all objects in MITK and provide every vtk based mapper to the picker.
*/
virtual void InitPathTraversal();
/**
* \brief Used by vtkPointPicker/vtkPicker.
* This will query a list of all objects in MITK and provide every vtk based mapper to the picker.
*/
virtual vtkAssemblyPath* GetNextPath();
//BUG (#1551) added method for depth peeling support
virtual int HasTranslucentPolygonalGeometry();
virtual int RenderTranslucentPolygonalGeometry( vtkViewport *);
virtual int RenderVolumetricGeometry( vtkViewport *);
protected:
vtkMitkRenderProp();
~vtkMitkRenderProp();
mitk::VtkPropRenderer::Pointer m_VtkPropRenderer;
};
#endif /* VTKMITKRENDERPROP_H_HEADER_INCLUDED_C1C53723 */
diff --git a/Core/Code/Rendering/vtkMitkThickSlicesFilter.cpp b/Core/Code/Rendering/vtkMitkThickSlicesFilter.cpp
index cb33dccd71..ef8f746ead 100644
--- a/Core/Code/Rendering/vtkMitkThickSlicesFilter.cpp
+++ b/Core/Code/Rendering/vtkMitkThickSlicesFilter.cpp
@@ -1,374 +1,373 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
-Version: $Revision: 18127 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "vtkMitkThickSlicesFilter.h"
#include "vtkDataArray.h"
#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include <math.h>
#include <vtksys/ios/sstream>
vtkCxxRevisionMacro(vtkMitkThickSlicesFilter, "$Revision: 1.00 $");
vtkStandardNewMacro(vtkMitkThickSlicesFilter);
//----------------------------------------------------------------------------
// Construct an instance of vtkMitkThickSlicesFilter fitler.
vtkMitkThickSlicesFilter::vtkMitkThickSlicesFilter()
{
this->HandleBoundaries = 1;
this->Dimensionality = 2;
this->m_CurrentMode = MIP;
// by default process active point scalars
this->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
vtkDataSetAttributes::SCALARS);
}
//----------------------------------------------------------------------------
void vtkMitkThickSlicesFilter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "HandleBoundaries: " << this->HandleBoundaries << "\n";
os << indent << "Dimensionality: " << this->Dimensionality << "\n";
}
//----------------------------------------------------------------------------
int vtkMitkThickSlicesFilter::RequestInformation(vtkInformation*,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
// Get input and output pipeline information.
vtkInformation* outInfo = outputVector->GetInformationObject(0);
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
// Get the input whole extent.
int extent[6];
inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent);
// Reduce 3D to 2D output
extent[4] = extent[5] = 0;
// Store the new whole extent for the output.
outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent, 6);
/*
// Set the number of point data componets to the number of
// components in the gradient vector.
vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_DOUBLE,
this->Dimensionality);
*/
return 1;
}
//----------------------------------------------------------------------------
// This method computes the input extent necessary to generate the output.
int vtkMitkThickSlicesFilter::RequestUpdateExtent(vtkInformation*,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
// Get input and output pipeline information.
vtkInformation* outInfo = outputVector->GetInformationObject(0);
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
// Get the input whole extent.
int wholeExtent[6];
inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExtent);
// Get the requested update extent from the output.
int inUExt[6];
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inUExt);
/*inUExt[4] -= 5;
inUExt[5] += 5;
if (inUExt[4] < wholeExtent[4]) */inUExt[4] = wholeExtent[4];
/*if (inUExt[5] > wholeExtent[5]) */inUExt[5] = wholeExtent[5];
// Store the update extent needed from the intput.
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inUExt, 6);
return 1;
}
//----------------------------------------------------------------------------
// This execute method handles boundaries.
// it handles boundaries. Pixels are just replicated to get values
// out of extent.
template <class T>
void vtkMitkThickSlicesFilterExecute(vtkMitkThickSlicesFilter *self,
vtkImageData *inData, T *inPtr,
vtkImageData *outData, T *outPtr,
int outExt[6], int /*id*/)
{
int idxX, idxY;
int maxX, maxY;
vtkIdType inIncX, inIncY, inIncZ;
vtkIdType outIncX, outIncY, outIncZ;
//int axesNum;
int *inExt = inData->GetExtent();
int *wholeExtent;
vtkIdType *inIncs;
//int useYMin, useYMax, useXMin, useXMax;
// find the region to loop over
maxX = outExt[1] - outExt[0];
maxY = outExt[3] - outExt[2];
// maxZ = outExt[5] - outExt[4];
// Get the dimensionality of the gradient.
//axesNum = self->GetDimensionality();
// Get increments to march through data
inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
/*
// The data spacing is important for computing the gradient.
// central differences (2 * ratio).
// Negative because below we have (min - max) for dx ...
inData->GetSpacing(r);
r[0] = -0.5 / r[0];
r[1] = -0.5 / r[1];
r[2] = -0.5 / r[2];
*/
// get some other info we need
inIncs = inData->GetIncrements();
wholeExtent = inData->GetExtent();
// Move the pointer to the correct starting position.
inPtr += (outExt[0]-inExt[0])*inIncs[0] +
(outExt[2]-inExt[2])*inIncs[1] +
(outExt[4]-inExt[4])*inIncs[2];
// Loop through ouput pixels
int _minZ = /*-5 + outExt[4]; if( _minZ < wholeExtent[4]) _minZ=*/wholeExtent[4];
int _maxZ = /* 5 + outExt[4]; if( _maxZ > wholeExtent[5]) _maxZ=*/wholeExtent[5];
if(_maxZ<_minZ)
return;
double invNum = 1.0 / (_maxZ-_minZ+1) ;
switch(self->GetThickSliceMode())
{
default:
case vtkMitkThickSlicesFilter::MIP:
{
//MIP
for (idxY = 0; idxY <= maxY; idxY++)
{
//useYMin = ((idxY + outExt[2]) <= wholeExtent[2]) ? 0 : -inIncs[1];
//useYMax = ((idxY + outExt[2]) >= wholeExtent[3]) ? 0 : inIncs[1];
for (idxX = 0; idxX <= maxX; idxX++)
{
//useXMin = ((idxX + outExt[0]) <= wholeExtent[0]) ? 0 : -inIncs[0];
//useXMax = ((idxX + outExt[0]) >= wholeExtent[1]) ? 0 : inIncs[0];
T mip = inPtr[_minZ*inIncs[2]];
for(int z = _minZ+1; z<= _maxZ;z++)
{
T value = inPtr[z*inIncs[2]];
if(value > mip)
mip=value;
}
// do X axis
*outPtr = mip;
outPtr++;
inPtr++;
}
outPtr += outIncY;
inPtr += inIncY;
}
}
break;
case vtkMitkThickSlicesFilter::SUM:
{
//MIP
for (idxY = 0; idxY <= maxY; idxY++)
{
//useYMin = ((idxY + outExt[2]) <= wholeExtent[2]) ? 0 : -inIncs[1];
//useYMax = ((idxY + outExt[2]) >= wholeExtent[3]) ? 0 : inIncs[1];
for (idxX = 0; idxX <= maxX; idxX++)
{
//useXMin = ((idxX + outExt[0]) <= wholeExtent[0]) ? 0 : -inIncs[0];
//useXMax = ((idxX + outExt[0]) >= wholeExtent[1]) ? 0 : inIncs[0];
double sum = 0;
for(int z = _minZ; z<= _maxZ;z++)
{
T value = inPtr[z*inIncs[2]];
sum += value;
}
// do X axis
*outPtr = invNum*sum;
outPtr++;
inPtr++;
}
outPtr += outIncY;
inPtr += inIncY;
}
}
break;
case vtkMitkThickSlicesFilter::WEIGHTED:
{
const int size = _maxZ-_minZ;
std::vector<double> weights(size);
double mean = 0.5 * double(_minZ + _maxZ);
double sigma_sq = double(size) / 6.0;
sigma_sq *= sigma_sq;
double sum = 0;
int i=0;
for(int z = _minZ+1; z<= _maxZ;z++)
{
double val = exp(-(((double)z-mean)/sigma_sq));
weights[i++] = val;
sum += val;
}
for(i=0; i<size; i++)
{
weights[i] /= sum;
}
for (idxY = 0; idxY <= maxY; idxY++)
{
//useYMin = ((idxY + outExt[2]) <= wholeExtent[2]) ? 0 : -inIncs[1];
//useYMax = ((idxY + outExt[2]) >= wholeExtent[3]) ? 0 : inIncs[1];
for (idxX = 0; idxX <= maxX; idxX++)
{
//useXMin = ((idxX + outExt[0]) <= wholeExtent[0]) ? 0 : -inIncs[0];
//useXMax = ((idxX + outExt[0]) >= wholeExtent[1]) ? 0 : inIncs[0];
T mip = inPtr[_minZ*inIncs[2]];
i=0;
double mymip = 0;
for(int z = _minZ+1; z<= _maxZ;z++)
{
double value = inPtr[z*inIncs[2]];
mymip+=value*weights[i++];
}
mip = mymip;
// do X axis
*outPtr = mip;
outPtr++;
inPtr++;
}
outPtr += outIncY;
inPtr += inIncY;
}
}
break;
}
}
int vtkMitkThickSlicesFilter::RequestData(
vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
if (!this->Superclass::RequestData(request, inputVector, outputVector))
{
return 0;
}
vtkImageData* output = vtkImageData::GetData(outputVector);
vtkDataArray* outArray = output->GetPointData()->GetScalars();
vtksys_ios::ostringstream newname;
newname << (outArray->GetName()?outArray->GetName():"")
<< "Gradient";
outArray->SetName(newname.str().c_str());
// Why not pass the original array?
if (this->GetInputArrayToProcess(0, inputVector))
{
output->GetPointData()->AddArray(
this->GetInputArrayToProcess(0, inputVector));
}
return 1;
}
//----------------------------------------------------------------------------
// This method contains a switch statement that calls the correct
// templated function for the input data type. This method does handle
// boundary conditions.
void vtkMitkThickSlicesFilter::ThreadedRequestData(vtkInformation*,
vtkInformationVector** inputVector,
vtkInformationVector*,
vtkImageData*** inData,
vtkImageData** outData,
int outExt[6],
int threadId)
{
// Get the input and output data objects.
vtkImageData* input = inData[0][0];
vtkImageData* output = outData[0];
// The ouptut scalar type must be double to store proper gradients.
/*
if(output->GetScalarType() != VTK_DOUBLE)
{
vtkErrorMacro("Execute: output ScalarType is "
<< output->GetScalarType() << "but must be double.");
return;
}
*/
vtkDataArray* inputArray = this->GetInputArrayToProcess(0, inputVector);
if (!inputArray)
{
vtkErrorMacro("No input array was found. Cannot execute");
return;
}
// Gradient makes sense only with one input component. This is not
// a Jacobian filter.
if(inputArray->GetNumberOfComponents() != 1)
{
vtkErrorMacro(
"Execute: input has more than one component. "
"The input to gradient should be a single component image. "
"Think about it. If you insist on using a color image then "
"run it though RGBToHSV then ExtractComponents to get the V "
"components. That's probably what you want anyhow.");
return;
}
void* inPtr = inputArray->GetVoidPointer(0);
void* outPtr = output->GetScalarPointerForExtent(outExt);
switch(inputArray->GetDataType())
{
vtkTemplateMacro(
vtkMitkThickSlicesFilterExecute(this, input, static_cast<VTK_TT*>(inPtr), output, static_cast<VTK_TT*>(outPtr), outExt, threadId)
);
default:
vtkErrorMacro("Execute: Unknown ScalarType " << input->GetScalarType());
return;
}
}
diff --git a/Core/Code/Rendering/vtkMitkThickSlicesFilter.h b/Core/Code/Rendering/vtkMitkThickSlicesFilter.h
index cf82b21a13..b73bff7b01 100644
--- a/Core/Code/Rendering/vtkMitkThickSlicesFilter.h
+++ b/Core/Code/Rendering/vtkMitkThickSlicesFilter.h
@@ -1,109 +1,108 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
-Version: $Revision: 18127 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
// .NAME vtkMitkThickSlicesFilter - Computes the gradient vector.
// .SECTION Description
// vtkMitkThickSlicesFilter computes the gradient vector of an image. The
// vector results are stored as scalar components. The Dimensionality
// determines whether to perform a 2d or 3d gradient. The default is
// two dimensional XY gradient. OutputScalarType is always
// double. Gradient is computed using central differences.
#ifndef __vtkMitkThickSlicesFilter_h
#define __vtkMitkThickSlicesFilter_h
#include <MitkExports.h>
#include "vtkThreadedImageAlgorithm.h"
class MITK_CORE_EXPORT vtkMitkThickSlicesFilter : public vtkThreadedImageAlgorithm
{
public:
static vtkMitkThickSlicesFilter *New();
vtkTypeRevisionMacro(vtkMitkThickSlicesFilter,vtkThreadedImageAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Determines how the input is interpreted (set of 2d slices ...)
vtkSetClampMacro(Dimensionality,int,2,3);
vtkGetMacro(Dimensionality,int);
// Description:
// Get/Set whether to handle boundaries. If enabled, boundary
// pixels are treated as duplicated so that central differencing
// works for the boundary pixels. If disabled, the output whole
// extent of the image is reduced by one pixel.
vtkSetMacro(HandleBoundaries, int);
vtkGetMacro(HandleBoundaries, int);
vtkBooleanMacro(HandleBoundaries, int);
enum {
MIP=0,
SUM,
WEIGHTED
};
protected:
vtkMitkThickSlicesFilter();
~vtkMitkThickSlicesFilter() {};
int HandleBoundaries;
int Dimensionality;
virtual int RequestInformation (vtkInformation*,
vtkInformationVector**,
vtkInformationVector*);
virtual int RequestUpdateExtent(vtkInformation*,
vtkInformationVector**,
vtkInformationVector*);
virtual int RequestData(vtkInformation*,
vtkInformationVector**,
vtkInformationVector*);
void ThreadedRequestData(vtkInformation*,
vtkInformationVector**,
vtkInformationVector*,
vtkImageData*** inData,
vtkImageData** outData,
int outExt[6],
int threadId);
int m_CurrentMode;
private:
vtkMitkThickSlicesFilter(const vtkMitkThickSlicesFilter&); // Not implemented.
void operator=(const vtkMitkThickSlicesFilter&); // Not implemented.
public:
void SetThickSliceMode( int mode)
{
m_CurrentMode = mode;
}
int GetThickSliceMode()
{
return m_CurrentMode;
}
};
#endif
diff --git a/Core/Code/Testing/itkTotalVariationDenoisingImageFilterTest.cpp b/Core/Code/Testing/itkTotalVariationDenoisingImageFilterTest.cpp
index 6f503086f6..200cc982a4 100644
--- a/Core/Code/Testing/itkTotalVariationDenoisingImageFilterTest.cpp
+++ b/Core/Code/Testing/itkTotalVariationDenoisingImageFilterTest.cpp
@@ -1,292 +1,291 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-09-26 18:50:26 +0200 (Mi, 26 Sep 2007) $
-Version: $Revision: 9585 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "itkTotalVariationDenoisingImageFilter.h"
#include "itkTotalVariationSingleIterationImageFilter.h"
#include "itkLocalVariationImageFilter.h"
#include "itkImageRegionIterator.h"
// image typedefs
typedef itk::Image<float, 3>
ImageType;
typedef itk::ImageRegionIterator<ImageType>
IteratorType;
// vector image typedefs
typedef itk::Vector<float,2>
VectorPixelType;
typedef itk::Image<VectorPixelType, 3>
VectorImageType;
typedef itk::ImageRegionIterator<VectorImageType>
VectorIteratorType;
/**
* 3x3x3 test image
*/
ImageType::Pointer GenerateTestImage()
{
// init
ImageType::Pointer image = ImageType::New();;
// spacing
ImageType::SpacingType spacing;
spacing[0] = 1;
spacing[1] = 1;
spacing[2] = 1;
image->SetSpacing(spacing);
// extent
ImageType::RegionType largestPossibleRegion;
ImageType::SizeType size = {{3,3,1}};
largestPossibleRegion.SetSize( size );
ImageType::IndexType index = {{0,0,0}};
largestPossibleRegion.SetIndex( index );
image->SetLargestPossibleRegion( largestPossibleRegion );
image->SetBufferedRegion( largestPossibleRegion );
// allocate memory
image->Allocate();
int i=0;
IteratorType it(image, largestPossibleRegion);
it.GoToBegin();
while(!it.IsAtEnd())
{
it.Set((float)i++);
++it;
}
return image;
}
VectorImageType::Pointer GenerateVectorTestImage()
{
// init
VectorImageType::Pointer image = VectorImageType::New();;
// spacing
VectorImageType::SpacingType spacing;
spacing[0] = 1;
spacing[1] = 1;
spacing[2] = 1;
image->SetSpacing(spacing);
// extent
VectorImageType::RegionType largestPossibleRegion;
VectorImageType::SizeType size = {{3,3,1}};
largestPossibleRegion.SetSize( size );
VectorImageType::IndexType index = {{0,0,0}};
largestPossibleRegion.SetIndex( index );
image->SetLargestPossibleRegion( largestPossibleRegion );
image->SetBufferedRegion( largestPossibleRegion );
// allocate memory
image->Allocate();
int i=0;
VectorIteratorType it(image, largestPossibleRegion);
it.GoToBegin();
while(!it.IsAtEnd())
{
VectorPixelType vec;
vec[0] = (float)i;
vec[1] = (float)i++;
it.Set(vec);
++it;
}
return image;
}
void PrintImage(ImageType::Pointer image)
{
IteratorType it(image, image->GetLargestPossibleRegion());
for(it.GoToBegin(); !it.IsAtEnd(); ++it)
{
std::cout << it.Get() << " ";
}
std::cout << std::endl;
}
void PrintVectorImage(VectorImageType::Pointer image)
{
VectorIteratorType it(image, image->GetLargestPossibleRegion());
for(it.GoToBegin(); !it.IsAtEnd(); ++it)
{
std::cout << it.Get() << " ";
}
std::cout << std::endl;
}
/**
* todo
*/
int itkTotalVariationDenoisingImageFilterTest(int /*argc*/, char* /*argv*/[])
{
ImageType::Pointer image = GenerateTestImage();
PrintImage(image);
double precision = 0.01;
ImageType::IndexType index = {{1,1,0}};
VectorImageType::IndexType vecIndex = {{1,1,0}};
try
{
typedef itk::LocalVariationImageFilter<ImageType,ImageType>
LocalFilterType;
LocalFilterType::Pointer filter = LocalFilterType::New();
filter->SetInput(image);
filter->SetNumberOfThreads(1);
filter->Update();
ImageType::Pointer outImage = filter->GetOutput();
PrintImage(outImage);
if(fabs(outImage->GetPixel(index) - 4.472) > precision)
{
return EXIT_FAILURE;
}
}
catch (...)
{
return EXIT_FAILURE;
}
try
{
typedef itk::TotalVariationSingleIterationImageFilter<ImageType,ImageType>
SingleFilterType;
SingleFilterType::Pointer sFilter = SingleFilterType::New();
sFilter->SetInput( image );
sFilter->SetOriginalImage(GenerateTestImage());
sFilter->SetLambda(0.5);
sFilter->SetNumberOfThreads(1);
sFilter->Update();
ImageType::Pointer outImageS = sFilter->GetOutput();
PrintImage(outImageS);
if(fabs(outImageS->GetPixel(index) - 4.0) > precision)
{
return EXIT_FAILURE;
}
}
catch (...)
{
return EXIT_FAILURE;
}
try
{
typedef itk::TotalVariationDenoisingImageFilter<ImageType,ImageType>
TVFilterType;
TVFilterType::Pointer tvFilter = TVFilterType::New();
tvFilter->SetInput(image);
tvFilter->SetNumberIterations(30);
tvFilter->SetNumberOfThreads(1);
tvFilter->SetLambda(0.1);
tvFilter->Update();
ImageType::Pointer outImageTV = tvFilter->GetOutput();
PrintImage(outImageTV);
if(fabs(outImageTV->GetPixel(index) - 4.0) > precision)
{
return EXIT_FAILURE;
}
}
catch (...)
{
return EXIT_FAILURE;
}
VectorImageType::Pointer vecImage = GenerateVectorTestImage();
PrintVectorImage(vecImage);
try
{
typedef itk::LocalVariationImageFilter<VectorImageType,ImageType>
LocalVecFilterType;
LocalVecFilterType::Pointer vecFilter = LocalVecFilterType::New();
vecFilter->SetInput(vecImage);
vecFilter->SetNumberOfThreads(1);
vecFilter->Update();
ImageType::Pointer outVecImage = vecFilter->GetOutput();
PrintImage(outVecImage);
if(fabs(outVecImage->GetPixel(index) - 6.324) > precision)
{
return EXIT_FAILURE;
}
}
catch (...)
{
return EXIT_FAILURE;
}
try
{
typedef itk::TotalVariationSingleIterationImageFilter
<VectorImageType,VectorImageType>
SingleVecFilterType;
SingleVecFilterType::Pointer sVecFilter = SingleVecFilterType::New();
sVecFilter->SetInput( vecImage );
sVecFilter->SetOriginalImage(vecImage);
sVecFilter->SetLambda(0.5);
sVecFilter->SetNumberOfThreads(1);
sVecFilter->UpdateLargestPossibleRegion();
VectorImageType::Pointer outVecImageS = sVecFilter->GetOutput();
PrintVectorImage(outVecImageS);
if(fabs(outVecImageS->GetPixel(vecIndex)[1] - 4.0) > precision)
{
return EXIT_FAILURE;
}
}
catch (...)
{
return EXIT_FAILURE;
}
try
{
typedef itk::TotalVariationDenoisingImageFilter
<VectorImageType,VectorImageType> TVVectorFilterType;
TVVectorFilterType::Pointer tvVecFilter = TVVectorFilterType::New();
tvVecFilter->SetInput(vecImage);
tvVecFilter->SetNumberIterations(30);
tvVecFilter->SetNumberOfThreads(1);
tvVecFilter->SetLambda(0.1);
tvVecFilter->Update();
VectorImageType::Pointer outVecImageTV = tvVecFilter->GetOutput();
PrintVectorImage(outVecImageTV);
if(fabs(outVecImageTV->GetPixel(vecIndex)[1] - 4.0) > precision)
{
return EXIT_FAILURE;
}
}
catch (...)
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkAbstractTransformGeometryTest.cpp b/Core/Code/Testing/mitkAbstractTransformGeometryTest.cpp
index 5b5164132a..326dc16a66 100644
--- a/Core/Code/Testing/mitkAbstractTransformGeometryTest.cpp
+++ b/Core/Code/Testing/mitkAbstractTransformGeometryTest.cpp
@@ -1,206 +1,205 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkExternAbstractTransformGeometry.h"
#include "mitkPlaneGeometry.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include <vtkSphericalTransform.h>
#include <fstream>
int mitkAbstractTransformGeometryTest(int /*argc*/, char* /*argv*/ [])
{
mitk::Point3D origin;
mitk::Vector3D right, bottom;
mitk::ScalarType width, height;
mitk::ScalarType widthInMM, heightInMM;
std::cout << "Initializing an x-/y-plane (xyPlane) as parameter plane by InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
mitk::PlaneGeometry::Pointer xyPlane = mitk::PlaneGeometry::New();
width = 100; widthInMM = width;
height = 200; heightInMM = height;
mitk::ScalarType bounds[6] = {0, width, 0, height, 0, 1};
mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
mitk::FillVector3D(right, widthInMM, 0, 0);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
xyPlane->InitializeStandardPlane(right, bottom);
xyPlane->SetOrigin(origin);
xyPlane->SetSizeInUnits(width, height);
std::cout << "Creating AbstractTransformGeometry: " <<std::endl;
mitk::ExternAbstractTransformGeometry::Pointer abstractgeometry=mitk::ExternAbstractTransformGeometry::New();
std::cout << "Setting xyPlane as parameter plane of AbstractTransformGeometry: "<<std::endl;
abstractgeometry->SetPlane(xyPlane);
std::cout << "Testing whether the bounds of xyPlane and the parametric bounds of AbstractTransformGeometry are equal: ";
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(xyPlane->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(xyPlane->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing whether the parametic bounds of AbstractTransformGeometry and the bounds of the plane accessed from there are equal: ";
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Change parametic bounds of AbstractTransformGeometry and test whether they are equal to the bounds of the plane accessed from there: "<<std::endl;
height = 300;
bounds[3] = height;
abstractgeometry->SetParametricBounds(bounds);
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Initializing an phi-/theta-plane (sphereParameterPlane) as parameter plane by InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
mitk::PlaneGeometry::Pointer sphereParameterPlane = mitk::PlaneGeometry::New();
width = 100; widthInMM = 2*vnl_math::pi;
height = 200; heightInMM = vnl_math::pi;
mitk::ScalarType radiusInMM = 2.5;
mitk::FillVector3D(origin, radiusInMM, 0, widthInMM);
mitk::FillVector3D(right, 0, 0, -widthInMM);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
sphereParameterPlane->InitializeStandardPlane(right, bottom);
sphereParameterPlane->SetOrigin(origin);
sphereParameterPlane->SetSizeInUnits(width, height);
std::cout << "Creating an vtkSphericalTransform (sphericalTransform) to use with sphereParameterPlane: "<<std::endl;
vtkSphericalTransform* sphericalTransform = vtkSphericalTransform::New();
std::cout << "Setting sphereParameterPlane as parameter plane and sphericalTransform as transform of AbstractTransformGeometry: "<<std::endl;
abstractgeometry->SetPlane(sphereParameterPlane);
abstractgeometry->SetVtkAbstractTransform(sphericalTransform);
std::cout << "Testing whether the bounds of sphereParameterPlane and the parametric bounds of AbstractTransformGeometry are equal: ";
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(sphereParameterPlane->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(sphereParameterPlane->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing whether the parametic bounds of AbstractTransformGeometry and the bounds of the plane accessed from there are equal: ";
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mapping Map(pt2d_mm(phi=Pi,theta=Pi/2.0), pt3d_mm) and compare with expected (-radius, 0, 0): ";
mitk::Point2D pt2d_mm;
mitk::Point3D pt3d_mm, expected_pt3d_mm;
pt2d_mm[0] = vnl_math::pi; pt2d_mm[1] = vnl_math::pi_over_2;
mitk::FillVector3D(expected_pt3d_mm, -radiusInMM, 0, 0);
abstractgeometry->Map(pt2d_mm, pt3d_mm);
if(mitk::Equal(pt3d_mm, expected_pt3d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected: ";
mitk::Point2D testpt2d_mm;
abstractgeometry->Map(pt3d_mm, testpt2d_mm);
if(mitk::Equal(pt2d_mm, testpt2d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ";
mitk::Point2D pt2d_units;
pt2d_units[0] = width/2.0; pt2d_units[1] = height/2.0;
pt2d_mm[0] = widthInMM/2.0; pt2d_mm[1] = heightInMM/2.0;
abstractgeometry->IndexToWorld(pt2d_units, testpt2d_mm);
if(mitk::Equal(pt2d_mm, testpt2d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Change parametic bounds of AbstractTransformGeometry and test whether they are equal to the bounds of the plane accessed from there: "<<std::endl;
height = 300;
bounds[3] = height;
abstractgeometry->SetParametricBounds(bounds);
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ";
pt2d_units[0] = width/2.0; pt2d_units[1] = height/2.0;
pt2d_mm[0] = widthInMM/2.0; pt2d_mm[1] = heightInMM/2.0;
abstractgeometry->IndexToWorld(pt2d_units, testpt2d_mm);
if(mitk::Equal(pt2d_mm, testpt2d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
//std::cout << "Testing availability and type (PlaneGeometry) of first geometry in the SlicedGeometry3D: ";
//mitk::PlaneGeometry* accessedplanegeometry3 = dynamic_cast<mitk::PlaneGeometry*>(slicedWorldGeometry->GetGeometry2D(0));
//if(accessedplanegeometry3==NULL)
//{
// std::cout<<"[FAILED]"<<std::endl;
// return EXIT_FAILURE;
//}
//std::cout<<"[PASSED]"<<std::endl;
//std::cout << "Testing whether the first geometry in the SlicedGeometry3D is identical to planegeometry3 by axis comparison: "<<std::endl;
//if((mitk::Equal(accessedplanegeometry3->GetAxisVector(0), planegeometry3->GetAxisVector(0))==false) ||
// (mitk::Equal(accessedplanegeometry3->GetAxisVector(1), planegeometry3->GetAxisVector(1))==false) ||
// (mitk::Equal(accessedplanegeometry3->GetAxisVector(2), planegeometry3->GetAxisVector(2))==false))
//{
// std::cout<<"[FAILED]"<<std::endl;
// return EXIT_FAILURE;
//}
//std::cout<<"[PASSED]"<<std::endl;
sphericalTransform->Delete();
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkAbstractTransformPlaneGeometryTest.cpp b/Core/Code/Testing/mitkAbstractTransformPlaneGeometryTest.cpp
index 839521ce8e..2fe16cd4d4 100644
--- a/Core/Code/Testing/mitkAbstractTransformPlaneGeometryTest.cpp
+++ b/Core/Code/Testing/mitkAbstractTransformPlaneGeometryTest.cpp
@@ -1,208 +1,207 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkVtkAbstractTransformPlaneGeometry.h"
#include "mitkPlaneGeometry.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include <vtkSphericalTransform.h>
#include <vnl/vnl_quaternion.h>
#include <vnl/vnl_quaternion.txx>
#include <fstream>
int mitkVtkAbstractTransformPlaneGeometryTest(int argc, char* argv[])
{
mitk::Point3D origin;
mitk::Vector3D right, bottom;
mitk::ScalarType width, height;
mitk::ScalarType widthInMM, heightInMM;
std::cout << "Initializing an x-/y-plane (xyPlane) as parameter plane by InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
mitk::PlaneGeometry::Pointer xyPlane = mitk::PlaneGeometry::New();
width = 100; widthInMM = width;
height = 200; heightInMM = height;
mitk::ScalarType bounds[6] = {0, width, 0, height, 0, 1};
mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
mitk::FillVector3D(right, widthInMM, 0, 0);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
xyPlane->InitializeStandardPlane(right, bottom);
xyPlane->SetOrigin(origin);
xyPlane->SetSizeInUnits(width, height);
std::cout << "Creating VtkAbstractTransformPlaneGeometry: " <<std::endl;
mitk::VtkAbstractTransformPlaneGeometry::Pointer abstractgeometry=mitk::VtkAbstractTransformPlaneGeometry::New();
std::cout << "Setting xyPlane as parameter plane of VtkAbstractTransformPlaneGeometry: "<<std::endl;
abstractgeometry->SetPlane(xyPlane);
std::cout << "Testing whether the bounds of xyPlane and the parametric bounds of VtkAbstractTransformPlaneGeometry are equal: ";
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(xyPlane->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(xyPlane->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing whether the parametic bounds of VtkAbstractTransformPlaneGeometry and the bounds of the plane accessed from there are equal: ";
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Change parametic bounds of VtkAbstractTransformPlaneGeometry and test whether they are equal to the bounds of the plane accessed from there: "<<std::endl;
height = 300;
bounds[3] = height;
abstractgeometry->SetParametricBounds(bounds);
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Initializing an phi-/theta-plane (sphereParameterPlane) as parameter plane by InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
mitk::PlaneGeometry::Pointer sphereParameterPlane = mitk::PlaneGeometry::New();
width = 100; widthInMM = 2*vnl_math::pi;
height = 200; heightInMM = vnl_math::pi;
mitk::ScalarType radiusInMM = 2.5;
mitk::FillVector3D(origin, radiusInMM, 0, widthInMM);
mitk::FillVector3D(right, 0, 0, -widthInMM);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
sphereParameterPlane->InitializeStandardPlane(right, bottom);
sphereParameterPlane->SetOrigin(origin);
sphereParameterPlane->SetSizeInUnits(width, height);
std::cout << "Creating an vtkSphericalTransform (sphericalTransform) to use with sphereParameterPlane: "<<std::endl;
vtkSphericalTransform* sphericalTransform = vtkSphericalTransform::New();
std::cout << "Setting sphereParameterPlane as parameter plane and sphericalTransform as transform of VtkAbstractTransformPlaneGeometry: "<<std::endl;
abstractgeometry->SetPlane(sphereParameterPlane);
abstractgeometry->SetVtkAbstractTransform(sphericalTransform);
std::cout << "Testing whether the bounds of sphereParameterPlane and the parametric bounds of VtkAbstractTransformPlaneGeometry are equal: ";
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(sphereParameterPlane->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(sphereParameterPlane->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing whether the parametic bounds of VtkAbstractTransformPlaneGeometry and the bounds of the plane accessed from there are equal: ";
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mapping Map(pt2d_mm(phi=Pi,theta=Pi/2.0), pt3d_mm) and compare with expected (-radius, 0, 0): ";
mitk::Point2D pt2d_mm;
mitk::Point3D pt3d_mm, expected_pt3d_mm;
pt2d_mm[0] = vnl_math::pi; pt2d_mm[1] = vnl_math::pi_over_2;
mitk::FillVector3D(expected_pt3d_mm, -radiusInMM, 0, 0);
abstractgeometry->Map(pt2d_mm, pt3d_mm);
if(mitk::Equal(pt3d_mm, expected_pt3d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected: ";
mitk::Point2D testpt2d_mm;
abstractgeometry->Map(pt3d_mm, testpt2d_mm);
if(mitk::Equal(pt2d_mm, testpt2d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ";
mitk::Point2D pt2d_units;
pt2d_units[0] = width/2.0; pt2d_units[1] = height/2.0;
pt2d_mm[0] = widthInMM/2.0; pt2d_mm[1] = heightInMM/2.0;
abstractgeometry->IndexToWorld(pt2d_units, testpt2d_mm);
if(mitk::Equal(pt2d_mm, testpt2d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Change parametic bounds of VtkAbstractTransformPlaneGeometry and test whether they are equal to the bounds of the plane accessed from there: "<<std::endl;
height = 300;
bounds[3] = height;
abstractgeometry->SetParametricBounds(bounds);
if((mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMinimum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMinimum())==false) ||
(mitk::Equal(const_cast<mitk::BoundingBox*>(abstractgeometry->GetParametricBoundingBox())->GetMaximum(), const_cast<mitk::BoundingBox*>(abstractgeometry->GetPlane()->GetBoundingBox())->GetMaximum())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ";
pt2d_units[0] = width/2.0; pt2d_units[1] = height/2.0;
pt2d_mm[0] = widthInMM/2.0; pt2d_mm[1] = heightInMM/2.0;
abstractgeometry->IndexToWorld(pt2d_units, testpt2d_mm);
if(mitk::Equal(pt2d_mm, testpt2d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
//std::cout << "Testing availability and type (PlaneGeometry) of first geometry in the SlicedGeometry3D: ";
//mitk::PlaneGeometry* accessedplanegeometry3 = dynamic_cast<mitk::PlaneGeometry*>(slicedWorldGeometry->GetGeometry2D(0));
//if(accessedplanegeometry3==NULL)
//{
// std::cout<<"[FAILED]"<<std::endl;
// return EXIT_FAILURE;
//}
//std::cout<<"[PASSED]"<<std::endl;
//std::cout << "Testing whether the first geometry in the SlicedGeometry3D is identical to planegeometry3 by axis comparison: "<<std::endl;
//if((mitk::Equal(accessedplanegeometry3->GetAxisVector(0), planegeometry3->GetAxisVector(0))==false) ||
// (mitk::Equal(accessedplanegeometry3->GetAxisVector(1), planegeometry3->GetAxisVector(1))==false) ||
// (mitk::Equal(accessedplanegeometry3->GetAxisVector(2), planegeometry3->GetAxisVector(2))==false))
//{
// std::cout<<"[FAILED]"<<std::endl;
// return EXIT_FAILURE;
//}
//std::cout<<"[PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkAccessByItkTest.cpp b/Core/Code/Testing/mitkAccessByItkTest.cpp
index 53354356f9..2141666f7a 100644
--- a/Core/Code/Testing/mitkAccessByItkTest.cpp
+++ b/Core/Code/Testing/mitkAccessByItkTest.cpp
@@ -1,240 +1,239 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 17495 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <stdexcept>
#include "mitkTestingMacros.h"
#include <mitkITKImageImport.h>
#include <mitkImageAccessByItk.h>
#define TestImageType(type, dim) \
MITK_TEST_CONDITION(typeid(type) == typeid(TPixel) && dim == VDimension, "Checking for correct type itk::Image<" #type "," #dim ">")
class AccessByItkTest
{
public:
typedef AccessByItkTest Self;
typedef itk::Image<int, 2> IntImage2D;
typedef itk::Image<int, 3> IntImage3D;
typedef itk::Image<float, 2> FloatImage2D;
typedef itk::Image<float, 3> FloatImage3D;
enum EImageType {
Unknown = 0,
Int2D,
Int3D,
Float2D,
Float3D
};
void testAccessByItk()
{
mitk::Image::Pointer mitkIntImage2D = createMitkImage<IntImage2D>();
mitk::Image::ConstPointer mitkIntImage3D(createMitkImage<IntImage3D>());
mitk::Image::ConstPointer mitkFloatImage2D(createMitkImage<FloatImage2D>());
mitk::Image::Pointer mitkFloatImage3D = createMitkImage<FloatImage3D>();
AccessByItk(mitkIntImage2D, AccessItkImage);
AccessByItk(mitkIntImage3D, AccessItkImage);
AccessByItk(mitkFloatImage2D, AccessItkImage);
AccessByItk(mitkFloatImage3D, AccessItkImage);
AccessByItk_n(mitkIntImage2D, AccessItkImage, (Int2D, 2));
AccessByItk_n(mitkIntImage3D, AccessItkImage, (Int3D, 2));
AccessByItk_n(mitkFloatImage2D, AccessItkImage, (Float2D, 2));
AccessByItk_n(mitkFloatImage3D, AccessItkImage, (Float3D, 2));
}
void testAccessFixedDimensionByItk()
{
mitk::Image::Pointer mitkIntImage2D = createMitkImage<IntImage2D>();
mitk::Image::ConstPointer mitkIntImage3D(createMitkImage<IntImage3D>());
mitk::Image::ConstPointer mitkFloatImage2D(createMitkImage<FloatImage2D>());
mitk::Image::Pointer mitkFloatImage3D = createMitkImage<FloatImage3D>();
AccessFixedDimensionByItk(mitkIntImage2D, AccessItkImage, 2);
AccessFixedDimensionByItk(mitkIntImage3D, AccessItkImage, 3);
AccessFixedDimensionByItk(mitkFloatImage2D, AccessItkImage, 2);
AccessFixedDimensionByItk(mitkFloatImage3D, AccessItkImage, 3);
AccessFixedDimensionByItk_n(mitkIntImage2D, AccessItkImage, 2, (Int2D, 2));
AccessFixedDimensionByItk_n(mitkIntImage3D, AccessItkImage, 3, (Int3D, 2));
AccessFixedDimensionByItk_n(mitkFloatImage2D, AccessItkImage, 2, (Float2D, 2));
AccessFixedDimensionByItk_n(mitkFloatImage3D, AccessItkImage, 3, (Float3D, 2));
// Test for wrong dimension
MITK_TEST_FOR_EXCEPTION_BEGIN(const mitk::AccessByItkException&)
AccessFixedDimensionByItk(mitkFloatImage3D, AccessItkImage, 2);
MITK_TEST_FOR_EXCEPTION_END(const mitk::AccessByItkException&)
MITK_TEST_FOR_EXCEPTION_BEGIN(const mitk::AccessByItkException&)
AccessFixedDimensionByItk_n(mitkFloatImage3D, AccessItkImage, 2, (Float3D, 2));
MITK_TEST_FOR_EXCEPTION_END(const mitk::AccessByItkException&)
}
void testAccessFixedPixelTypeByItk()
{
mitk::Image::Pointer mitkIntImage2D = createMitkImage<IntImage2D>();
mitk::Image::ConstPointer mitkIntImage3D(createMitkImage<IntImage3D>());
mitk::Image::ConstPointer mitkFloatImage2D(createMitkImage<FloatImage2D>());
mitk::Image::Pointer mitkFloatImage3D = createMitkImage<FloatImage3D>();
AccessFixedPixelTypeByItk(mitkIntImage2D, AccessItkImage, (int)(float));
AccessFixedPixelTypeByItk(mitkIntImage3D, AccessItkImage, (int)(float));
AccessFixedPixelTypeByItk(mitkFloatImage2D, AccessItkImage, (int)(float));
AccessFixedPixelTypeByItk(mitkFloatImage3D, AccessItkImage, (int)(float));
AccessFixedPixelTypeByItk_n(mitkIntImage2D, AccessItkImage, (int)(float), (Int2D, 2));
AccessFixedPixelTypeByItk_n(mitkIntImage3D, AccessItkImage, (int)(float), (Int3D, 2));
AccessFixedPixelTypeByItk_n(mitkFloatImage2D, AccessItkImage, (int)(float), (Float2D, 2));
AccessFixedPixelTypeByItk_n(mitkFloatImage3D, AccessItkImage, (int)(float), (Float3D, 2));
// Test for wrong pixel type
MITK_TEST_FOR_EXCEPTION_BEGIN(const mitk::AccessByItkException&)
AccessFixedPixelTypeByItk(mitkFloatImage3D, AccessItkImage, (int));
MITK_TEST_FOR_EXCEPTION_END(const mitk::AccessByItkException&)
MITK_TEST_FOR_EXCEPTION_BEGIN(const mitk::AccessByItkException&)
AccessFixedPixelTypeByItk_n(mitkFloatImage3D, AccessItkImage, (int), (Float3D, 2));
MITK_TEST_FOR_EXCEPTION_END(const mitk::AccessByItkException&)
}
void testAccessFixedTypeByItk()
{
mitk::Image::Pointer mitkIntImage2D = createMitkImage<IntImage2D>();
mitk::Image::ConstPointer mitkIntImage3D(createMitkImage<IntImage3D>());
mitk::Image::ConstPointer mitkFloatImage2D(createMitkImage<FloatImage2D>());
mitk::Image::Pointer mitkFloatImage3D = createMitkImage<FloatImage3D>();
AccessFixedTypeByItk(mitkIntImage2D, AccessItkImage, (int)(float), (2)(3));
AccessFixedTypeByItk(mitkIntImage3D, AccessItkImage, (int)(float), (2)(3));
AccessFixedTypeByItk(mitkFloatImage2D, AccessItkImage, (int)(float), (2)(3));
AccessFixedTypeByItk(mitkFloatImage3D, AccessItkImage, (int)(float), (2)(3));
AccessFixedTypeByItk_n(mitkIntImage2D, AccessItkImage, (int)(float), (2)(3), (Int2D, 2));
AccessFixedTypeByItk_n(mitkIntImage3D, AccessItkImage, (int)(float), (2)(3), (Int3D, 2));
AccessFixedTypeByItk_n(mitkFloatImage2D, AccessItkImage, (int)(float), (2)(3), (Float2D, 2));
AccessFixedTypeByItk_n(mitkFloatImage3D, AccessItkImage, (int)(float), (2)(3), (Float3D, 2));
// Test for wrong dimension
MITK_TEST_FOR_EXCEPTION_BEGIN(const mitk::AccessByItkException&)
AccessFixedTypeByItk(mitkFloatImage3D, AccessItkImage, (float), (2));
MITK_TEST_FOR_EXCEPTION_END(const mitk::AccessByItkException&)
MITK_TEST_FOR_EXCEPTION_BEGIN(const mitk::AccessByItkException&)
AccessFixedTypeByItk_n(mitkFloatImage3D, AccessItkImage, (float), (2), (Float3D, 2));
MITK_TEST_FOR_EXCEPTION_END(const mitk::AccessByItkException&)
// Test for wrong pixel type
MITK_TEST_FOR_EXCEPTION_BEGIN(const mitk::AccessByItkException&)
AccessFixedTypeByItk(mitkFloatImage3D, AccessItkImage, (int), (3));
MITK_TEST_FOR_EXCEPTION_END(const mitk::AccessByItkException&)
MITK_TEST_FOR_EXCEPTION_BEGIN(const mitk::AccessByItkException&)
AccessFixedTypeByItk_n(mitkFloatImage3D, AccessItkImage, (int), (3), (Float3D, 2));
MITK_TEST_FOR_EXCEPTION_END(const mitk::AccessByItkException&)
}
void testAccessTwoImagesFixedDimensionByItk()
{
mitk::Image::Pointer mitkIntImage2D = createMitkImage<IntImage2D>();
mitk::Image::ConstPointer mitkFloatImage2D(createMitkImage<FloatImage2D>());
AccessTwoImagesFixedDimensionByItk(mitkIntImage2D, mitkFloatImage2D, AccessTwoItkImages, 2);
}
template<typename TPixel, unsigned int VDimension>
void AccessItkImage(itk::Image<TPixel, VDimension>*,
EImageType param1 = Unknown, int param2 = 0, int param3 = 0)
{
switch (param1)
{
case Int2D: TestImageType(int , 2) break;
case Int3D: TestImageType(int, 3) break;
case Float2D: TestImageType(float, 2) break;
case Float3D: TestImageType(float, 3) break;
default: break;
}
if (param2)
{
MITK_TEST_CONDITION(param2 == 2, "Checking for correct second parameter")
}
if (param3)
{
MITK_TEST_CONDITION(param3 == 3, "Checking for correct third parameter")
}
}
private:
template<typename TPixel1, unsigned int VDimension1, typename TPixel2, unsigned int VDimension2>
void AccessTwoItkImages(itk::Image<TPixel1,VDimension1>* /*itkImage1*/, itk::Image<TPixel2,VDimension2>* /*itkImage2*/)
{
if (!(typeid(int) == typeid(TPixel1) && typeid(float) == typeid(TPixel2) &&
VDimension1 == 2 && VDimension2 == 2))
{
throw std::runtime_error("Image type mismatch");
}
}
template<typename ImageType>
mitk::Image::Pointer createMitkImage()
{
typename ImageType::Pointer itkImage = ImageType::New();
typename ImageType::IndexType start;
start.Fill(0);
typename ImageType::SizeType size;
size.Fill(3);
typename ImageType::RegionType region;
region.SetSize(size);
region.SetIndex(start);
itkImage->SetRegions(region);
itkImage->Allocate();
return mitk::GrabItkImageMemory(itkImage);
}
};
int mitkAccessByItkTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("AccessByItk")
AccessByItkTest accessTest;
MITK_TEST_OUTPUT(<< "Testing AccessByItk macro")
accessTest.testAccessByItk();
MITK_TEST_OUTPUT(<< "Testing AccessFixedDimensionByItk macro")
accessTest.testAccessFixedDimensionByItk();
MITK_TEST_OUTPUT(<< "Testing AccessFixedTypeByItk macro")
accessTest.testAccessFixedTypeByItk();
MITK_TEST_OUTPUT(<< "Testing AccessFixedPixelTypeByItk macro")
accessTest.testAccessFixedPixelTypeByItk();
MITK_TEST_OUTPUT(<< "Testing AccessTwoImagesFixedDimensionByItk macro")
accessTest.testAccessTwoImagesFixedDimensionByItk();
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkActionTest.cpp b/Core/Code/Testing/mitkActionTest.cpp
index dfd024afaf..f7e9472402 100644
--- a/Core/Code/Testing/mitkActionTest.cpp
+++ b/Core/Code/Testing/mitkActionTest.cpp
@@ -1,81 +1,80 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkAction.h>
#include <mitkProperties.h>
#include <fstream>
int mitkActionTest(int /*argc*/, char* /*argv*/[])
{
int actionId = 10;
//Create Action
mitk::Action::Pointer action = mitk::Action::New(actionId);
//check ActionID
std::cout << "check ActionId";
if (action->GetActionId()!=actionId)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
//check properties
action->AddProperty("boolproperty", mitk::BoolProperty::New(true));
action->AddProperty("intproperty", mitk::IntProperty::New(10));
action->AddProperty("floatproperty", mitk::FloatProperty::New(10.05));
std::cout << "try adding property BOOL and read them: ";
bool boolproperty = false;
boolproperty = dynamic_cast<mitk::BoolProperty *>(action->GetProperty("boolproperty"))->GetValue();
if (boolproperty != true)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "try adding property INT and read them: ";
int intproperty = 0;
intproperty = dynamic_cast<mitk::IntProperty *>(action->GetProperty("intproperty"))->GetValue();
if (intproperty != 10)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "try adding property FLOAT and read them: ";
float floatproperty = 0.0;
floatproperty = dynamic_cast<mitk::FloatProperty *>(action->GetProperty("floatproperty"))->GetValue();
if (floatproperty != 10.05f)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
//delete the action
//action->Delete();
//well done!!! Passed!
std::cout<<"[EVERYTHING PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkBaseDataTest.cpp b/Core/Code/Testing/mitkBaseDataTest.cpp
index 4b02e21e4f..7fc7af098c 100644
--- a/Core/Code/Testing/mitkBaseDataTest.cpp
+++ b/Core/Code/Testing/mitkBaseDataTest.cpp
@@ -1,121 +1,120 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 17495 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkBaseDataTestImplementation.h"
#include "mitkStringProperty.h"
#include "mitkTestingMacros.h"
#include "itkImage.h"
int mitkBaseDataTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("BaseData")
//Create a BaseData implementation
MITK_INFO << "Creating a base data instance...";
mitk::BaseDataTestImplementation::Pointer baseDataImpl = mitk::BaseDataTestImplementation::New();
MITK_TEST_CONDITION_REQUIRED(baseDataImpl.IsNotNull(),"Testing instantiation");
MITK_TEST_CONDITION(baseDataImpl->IsInitialized(), "BaseDataTestImplementation is initialized");
MITK_TEST_CONDITION(baseDataImpl->IsEmpty(), "BaseDataTestImplementation is initialized and empty");
MITK_TEST_CONDITION(baseDataImpl->GetExternalReferenceCount()== baseDataImpl->GetReferenceCount(), "Checks external reference count!");
mitk::BaseDataTestImplementation::Pointer cloneBaseData = baseDataImpl->Clone();
MITK_TEST_CONDITION_REQUIRED(cloneBaseData.IsNotNull(),"Testing instantiation of base data clone");
MITK_TEST_CONDITION(cloneBaseData->IsInitialized(), "Clone of BaseDataTestImplementation is initialized");
MITK_TEST_CONDITION(cloneBaseData->IsEmpty(), "Clone of BaseDataTestImplementation is initialized and empty");
MITK_TEST_CONDITION(cloneBaseData->GetExternalReferenceCount()== cloneBaseData->GetReferenceCount(), "Checks external reference count of base data clone!");
MITK_INFO << "Testing setter and getter for geometries...";
//test method GetTimeSlicedGeometry()
MITK_TEST_CONDITION(baseDataImpl->GetTimeSlicedGeometry(), "Testing creation of TimeSlicedGeometry");
mitk::TimeSlicedGeometry* geo = NULL;
baseDataImpl->SetGeometry(geo);
MITK_TEST_CONDITION(baseDataImpl->GetTimeSlicedGeometry() == NULL, "Reset Geometry");
mitk::TimeSlicedGeometry::Pointer geo2 = mitk::TimeSlicedGeometry::New();
baseDataImpl->SetGeometry(geo2);
baseDataImpl->InitializeTimeSlicedGeometry(2);
MITK_TEST_CONDITION(baseDataImpl->GetTimeSlicedGeometry() == geo2, "Correct Reinit of TimeslicedGeometry");
//test method GetGeometry(int timeStep)
MITK_TEST_CONDITION(baseDataImpl->GetGeometry(1) != NULL, "... and single Geometries");
//test method Expand(unsigned int timeSteps)
baseDataImpl->Expand(5);
MITK_TEST_CONDITION(baseDataImpl->GetTimeSteps() == 5, "Expand the geometry to further time slices!");
//test method GetUpdatedGeometry(int timeStep);
mitk::Geometry3D::Pointer geo3 = mitk::Geometry3D::New();
mitk::TimeSlicedGeometry::Pointer timeSlicedGeometry = baseDataImpl->GetTimeSlicedGeometry();
if (timeSlicedGeometry.IsNotNull() )
{
timeSlicedGeometry->SetGeometry3D(geo3, 1);
}
MITK_TEST_CONDITION(baseDataImpl->GetUpdatedGeometry(1) == geo3, "Set Geometry for time step 1");
MITK_TEST_CONDITION(baseDataImpl->GetMTime()!= 0, "Check if modified time is set");
baseDataImpl->SetClonedGeometry(geo3, 1);
float x[3];
x[0] = 2;
x[1] = 4;
x[2] = 6;
mitk::Point3D p3d(x);
baseDataImpl->SetOrigin(p3d);
geo3->SetOrigin(p3d);
MITK_TEST_CONDITION(baseDataImpl->GetGeometry(1)->GetOrigin() == geo3->GetOrigin(), "Testing Origin set");
cloneBaseData = baseDataImpl->Clone();
MITK_TEST_CONDITION(cloneBaseData->GetGeometry(1)->GetOrigin() == geo3->GetOrigin(), "Testing origin set in clone!");
MITK_TEST_CONDITION(!baseDataImpl->IsEmptyTimeStep(1), "Is not empty before clear()!");
baseDataImpl->Clear();
MITK_TEST_CONDITION(baseDataImpl->IsEmptyTimeStep(1), "...but afterwards!");
//test method Set-/GetProperty()
baseDataImpl->SetProperty("property38", mitk::StringProperty::New("testproperty"));
//baseDataImpl->SetProperty("visibility", mitk::BoolProperty::New());
MITK_TEST_CONDITION(baseDataImpl->GetProperty("property38")->GetValueAsString() == "testproperty","Check if base property is set correctly!");
cloneBaseData = baseDataImpl->Clone();
MITK_TEST_CONDITION(cloneBaseData->GetProperty("property38")->GetValueAsString() == "testproperty", "Testing origin set in clone!");
//test method Set-/GetPropertyList
mitk::PropertyList::Pointer propertyList = mitk::PropertyList::New();
propertyList->SetFloatProperty("floatProperty1", 123.45);
propertyList->SetBoolProperty("visibility",true);
propertyList->SetStringProperty("nameXY","propertyName");
baseDataImpl->SetPropertyList(propertyList);
bool value = false;
MITK_TEST_CONDITION(baseDataImpl->GetPropertyList() == propertyList, "Check if base property list is set correctly!");
MITK_TEST_CONDITION(baseDataImpl->GetPropertyList()->GetBoolProperty("visibility", value) == true, "Check if base property is set correctly in the property list!");
//test method UpdateOutputInformation()
baseDataImpl->UpdateOutputInformation();
MITK_TEST_CONDITION(baseDataImpl->GetUpdatedTimeSlicedGeometry() == geo2, "TimeSlicedGeometry update!");
//Test method CopyInformation()
mitk::BaseDataTestImplementation::Pointer newBaseData = mitk::BaseDataTestImplementation::New();
newBaseData->CopyInformation(baseDataImpl);
MITK_TEST_CONDITION_REQUIRED( newBaseData->GetTimeSlicedGeometry()->GetTimeSteps() == 5, "Check copying of of Basedata Data Object!");
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp b/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp
index b9a0d7b22b..2ebd73b38a 100644
--- a/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp
+++ b/Core/Code/Testing/mitkClippedSurfaceBoundsCalculatorTest.cpp
@@ -1,428 +1,427 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include <iostream>
#include "mitkClippedSurfaceBoundsCalculator.h"
#include "mitkGeometry3D.h"
#include "mitkGeometry2D.h"
#include "mitkVector.h"
static void CheckPlanesInsideBoundingBoxOnlyOnOneSlice(mitk::Geometry3D::Pointer geometry3D)
{
//Check planes which are inside the bounding box
mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator();
mitk::Image::Pointer image = mitk::Image::New();
image->SetGeometry(geometry3D);
//Check planes which are only on one slice:
//Slice 0
mitk::Point3D origin;
origin[0] = 511;
origin[1] = 0;
origin[2] = 0;
mitk::Vector3D normal;
mitk::FillVector3D(normal, 0, 0, 1);
mitk::PlaneGeometry::Pointer planeOnSliceZero = mitk::PlaneGeometry::New();
planeOnSliceZero->InitializePlane(origin, normal);
calculator->SetInput( planeOnSliceZero , image);
calculator->Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice");
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 0, "Check if plane is on slice 0");
//Slice 3
origin[2] = 3;
mitk::PlaneGeometry::Pointer planeOnSliceThree = mitk::PlaneGeometry::New();
planeOnSliceThree->InitializePlane(origin, normal);
planeOnSliceThree->SetImageGeometry(false);
calculator->SetInput( planeOnSliceThree , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice");
MITK_TEST_CONDITION(minMax.first == 3 && minMax.second == 3, "Check if plane is on slice 3");
//Slice 17
origin[2] = 17;
mitk::PlaneGeometry::Pointer planeOnSliceSeventeen = mitk::PlaneGeometry::New();
planeOnSliceSeventeen->InitializePlane(origin, normal);
calculator->SetInput( planeOnSliceSeventeen , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice");
MITK_TEST_CONDITION(minMax.first == 17 && minMax.second == 17, "Check if plane is on slice 17");
//Slice 20
origin[2] = 19;
mitk::PlaneGeometry::Pointer planeOnSliceTwenty = mitk::PlaneGeometry::New();
planeOnSliceTwenty->InitializePlane(origin, normal);
calculator->SetInput( planeOnSliceTwenty , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == minMax.second, "Check if plane is only on one slice");
MITK_TEST_CONDITION(minMax.first == 19 && minMax.second == 19, "Check if plane is on slice 19");
delete calculator;
}
static void CheckPlanesInsideBoundingBox(mitk::Geometry3D::Pointer geometry3D)
{
//Check planes which are inside the bounding box
mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator();
mitk::Image::Pointer image = mitk::Image::New();
image->SetGeometry(geometry3D);
//Check planes which are only on one slice:
//Slice 0
mitk::Point3D origin;
origin[0] = 511; // Set to 511.9 so that the intersection point is inside the bounding box
origin[1] = 0;
origin[2] = 0;
mitk::Vector3D normal;
mitk::FillVector3D(normal, 1, 0, 0);
mitk::PlaneGeometry::Pointer planeSagittalOne = mitk::PlaneGeometry::New();
planeSagittalOne->InitializePlane(origin, normal);
calculator->SetInput( planeSagittalOne , image);
calculator->Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19");
//Slice 3
origin[0] = 256;
MITK_INFO << "Case1 origin: " << origin;
mitk::PlaneGeometry::Pointer planeSagittalTwo = mitk::PlaneGeometry::New();
planeSagittalTwo->InitializePlane(origin, normal);
MITK_INFO << "PlaneNormal: " << planeSagittalTwo->GetNormal();
MITK_INFO << "PlaneOrigin: " << planeSagittalTwo->GetOrigin();
calculator->SetInput( planeSagittalTwo , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19");
//Slice 17
origin[0] = 0; // Set to 0.1 so that the intersection point is inside the bounding box
mitk::PlaneGeometry::Pointer planeOnSliceSeventeen = mitk::PlaneGeometry::New();
planeOnSliceSeventeen->InitializePlane(origin, normal);
calculator->SetInput( planeOnSliceSeventeen , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19");
//Crooked planes:
origin[0] = 0;
origin[1] = 507;
origin[2] = 0;
normal[0] = 1;
normal[1] = -1;
normal[2] = 1;
mitk::PlaneGeometry::Pointer planeCrookedOne = mitk::PlaneGeometry::New();
planeCrookedOne->InitializePlane(origin, normal);
calculator->SetInput( planeCrookedOne , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 4, "Check if plane is from slice 0 to slice 4 with inclined plane");
origin[0] = 512;
origin[1] = 0;
origin[2] = 16;
mitk::PlaneGeometry::Pointer planeCrookedTwo = mitk::PlaneGeometry::New();
planeCrookedTwo->InitializePlane(origin, normal);
calculator->SetInput( planeCrookedTwo , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 17 && minMax.second == 19, "Check if plane is from slice 17 to slice 19 with inclined plane");
origin[0] = 511;
origin[1] = 0;
origin[2] = 0;
normal[1] = 0;
normal[2] = 0.04;
mitk::PlaneGeometry::Pointer planeCrookedThree = mitk::PlaneGeometry::New();
planeCrookedThree->InitializePlane(origin, normal);
calculator->SetInput( planeCrookedThree , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19 with inclined plane");
delete calculator;
}
static void CheckPlanesOutsideOfBoundingBox(mitk::Geometry3D::Pointer geometry3D)
{
//Check planes which are outside of the bounding box
mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator();
mitk::Image::Pointer image = mitk::Image::New();
image->SetGeometry(geometry3D);
//In front of the bounding box
mitk::Point3D origin;
origin[0] = 511;
origin[1] = 0;
origin[2] = -5;
mitk::Vector3D normal;
mitk::FillVector3D(normal, 0, 0, 1);
mitk::PlaneGeometry::Pointer planeInFront = mitk::PlaneGeometry::New();
planeInFront->InitializePlane(origin, normal);
calculator->SetInput( planeInFront , image);
calculator->Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Behind the bounding box
origin[2] = 515;
mitk::PlaneGeometry::Pointer planeBehind = mitk::PlaneGeometry::New();
planeBehind->InitializePlane(origin, normal);
calculator->SetInput( planeBehind , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Above
origin[1] = 515;
mitk::FillVector3D(normal, 0, 1, 0);
mitk::PlaneGeometry::Pointer planeAbove = mitk::PlaneGeometry::New();
planeAbove->InitializePlane(origin, normal);
calculator->SetInput( planeAbove , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Below
origin[1] = -5;
mitk::PlaneGeometry::Pointer planeBelow = mitk::PlaneGeometry::New();
planeBelow->InitializePlane(origin, normal);
calculator->SetInput( planeBelow , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Left side
origin[0] = -5;
mitk::FillVector3D(normal, 1, 0, 0);
mitk::PlaneGeometry::Pointer planeLeftSide = mitk::PlaneGeometry::New();
planeLeftSide->InitializePlane(origin, normal);
calculator->SetInput( planeLeftSide , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
//Right side
origin[1] = 515;
mitk::PlaneGeometry::Pointer planeRightSide = mitk::PlaneGeometry::New();
planeRightSide->InitializePlane(origin, normal);
calculator->SetInput( planeRightSide , image);
calculator->Update();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_TEST_CONDITION(minMax.first == std::numeric_limits<int>::max(), "Check if min value hasn't been set");
MITK_TEST_CONDITION(minMax.second == std::numeric_limits<int>::min(), "Check if max value hasn't been set");
delete calculator;
}
static void CheckIntersectionPointsOfTwoGeometry3D(mitk::Geometry3D::Pointer firstGeometry3D, mitk::Geometry3D::Pointer secondGeometry3D)
{
mitk::ClippedSurfaceBoundsCalculator* calculator = new mitk::ClippedSurfaceBoundsCalculator();
mitk::Image::Pointer firstImage = mitk::Image::New();
firstImage->SetGeometry(firstGeometry3D);
calculator->SetInput( secondGeometry3D, firstImage);
calculator->Update();
mitk::ClippedSurfaceBoundsCalculator::OutputType minMax = calculator->GetMinMaxSpatialDirectionZ();
minMax = calculator->GetMinMaxSpatialDirectionZ();
MITK_INFO << "min: " << minMax.first << " max: " << minMax.second;
MITK_TEST_CONDITION(minMax.first == 0 && minMax.second == 19, "Check if plane is from slice 0 to slice 19");
}
int mitkClippedSurfaceBoundsCalculatorTest(int, char* [])
{
// always start with this!
MITK_TEST_BEGIN("ClippedSurfaceBoundsCalculator");
/** The class mitkClippedSurfaceBoundsCalculator calculates the intersection points of a PlaneGeometry and a Geometry3D.
* This unittest checks if the correct min and max values for the three spatial directions (x, y, z)
* are calculated. To test this we define artifical PlaneGeometries and Geometry3Ds and test different
* scenarios:
*
* 1. planes which are inside the bounding box of a 3D geometry but only on one slice
* 2. planes which are outside of the bounding box
* 3. planes which are inside the bounding box but over more than one slice
*
* Note: Currently rotated geometries are not tested!
*/
/********************* Define Geometry3D ***********************/
//Define origin:
mitk::Point3D origin;
origin[0] = 511;
origin[1] = 0;
origin[2] = 0;
//Define normal:
mitk::Vector3D normal;
mitk::FillVector3D(normal, 0, 0, 1);
//Initialize PlaneGeometry:
mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
planeGeometry->InitializePlane(origin, normal);
//Set Bounds:
mitk::BoundingBox::BoundsArrayType bounds = planeGeometry->GetBounds();
bounds[0] = 0;
bounds[1] = 512;
bounds[2] = 0;
bounds[3] = 512;
bounds[4] = 0;
bounds[5] = 1;
planeGeometry->SetBounds(bounds);
//Initialize SlicedGeometry3D:
mitk::SlicedGeometry3D::Pointer slicedGeometry3D = mitk::SlicedGeometry3D::New();
slicedGeometry3D->InitializeEvenlySpaced(dynamic_cast<mitk::Geometry2D*>(planeGeometry.GetPointer()), 20);
mitk::Geometry3D::Pointer geometry3D = dynamic_cast< mitk::Geometry3D* > ( slicedGeometry3D.GetPointer() );
geometry3D->SetImageGeometry(true);
//Define origin for second Geometry3D;
mitk::Point3D origin2;
origin2[0] = 511;
origin2[1] = 60;
origin2[2] = 0;
//Define normal:
mitk::Vector3D normal2;
mitk::FillVector3D(normal2, 0, 1, 0);
//Initialize PlaneGeometry:
mitk::PlaneGeometry::Pointer planeGeometry2 = mitk::PlaneGeometry::New();
planeGeometry2->InitializePlane(origin2, normal2);
//Initialize SlicedGeometry3D:
mitk::SlicedGeometry3D::Pointer secondSlicedGeometry3D = mitk::SlicedGeometry3D::New();
secondSlicedGeometry3D->InitializeEvenlySpaced(dynamic_cast<mitk::Geometry2D*>(planeGeometry2.GetPointer()), 20);
mitk::Geometry3D::Pointer secondGeometry3D = dynamic_cast< mitk::Geometry3D* > ( secondSlicedGeometry3D.GetPointer() );
secondGeometry3D->SetImageGeometry(true);
/***************************************************************/
CheckPlanesInsideBoundingBoxOnlyOnOneSlice(geometry3D);
CheckPlanesOutsideOfBoundingBox(geometry3D);
CheckPlanesInsideBoundingBox(geometry3D);
CheckIntersectionPointsOfTwoGeometry3D(geometry3D, secondGeometry3D);
/** ToDo:
* test also rotated 3D geometry!
*/
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkCoreObjectFactoryTest.cpp b/Core/Code/Testing/mitkCoreObjectFactoryTest.cpp
index 87a117be37..e86f8de9cd 100644
--- a/Core/Code/Testing/mitkCoreObjectFactoryTest.cpp
+++ b/Core/Code/Testing/mitkCoreObjectFactoryTest.cpp
@@ -1,35 +1,34 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-03-12 14:05:50 +0100 (Fri, 12 Mar 2010) $
-Version: $Revision: 17495 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include "mitkCoreObjectFactory.h"
int mitkCoreObjectFactoryTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("CoreObjectFactory")
mitk::CoreObjectFactory::Pointer instance = mitk::CoreObjectFactory::GetInstance();
MITK_TEST_CONDITION_REQUIRED(instance.IsNotNull(),"Testing instantiation");
MITK_TEST_CONDITION(strcmp(instance->GetNameOfClass(),"CoreObjectFactory") == 0,"Is this a CoreObjectFactory?");
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkDICOMLocaleTest.cpp b/Core/Code/Testing/mitkDICOMLocaleTest.cpp
index 0114105669..56116f808a 100644
--- a/Core/Code/Testing/mitkDICOMLocaleTest.cpp
+++ b/Core/Code/Testing/mitkDICOMLocaleTest.cpp
@@ -1,132 +1,131 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 1.12 $
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
/*
This test is meant to reproduce the following error:
- The machine or current user has a German locale.
- This esp. means that stream IO expects the decimal separator as a comma: ","
- DICOM files use a point "." as the decimal separator to be locale independent
- The parser used by MITK (ITK's GDCM) seems to use the current locale instead of the "C" or "POSIX" locale
- This leads to spacings (and probably other numbers) being trimmed/rounded,
e.g. the correct spacing of 0.314 is read as 1.0 etc.
*/
#include "mitkDataNodeFactory.h"
#include "mitkStandardFileLocations.h"
#include "mitkDicomSeriesReader.h"
#include "mitkTestingMacros.h"
#include <list>
#include <locale>
#include <locale.h>
bool mitkDICOMLocaleTestChangeLocale(const std::string& locale)
{
try
{
MITK_TEST_OUTPUT(<< " ** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'");
setlocale(LC_ALL, locale.c_str());
std::locale l( locale.c_str() );
std::cin.imbue(l);
return true;
}
catch(...)
{
MITK_TEST_OUTPUT(<< "Could not activate locale " << locale);
return false;
}
}
void mitkDICOMLocaleTestWithReferenceImage(std::string filename)
{
mitk::Image::Pointer image;
mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
factory->SetFileName( filename );
factory->Update();
MITK_TEST_CONDITION_REQUIRED(factory->GetNumberOfOutputs() > 0, "file " << filename << " loaded");
mitk::DataNode::Pointer node = factory->GetOutput( 0 );
image = dynamic_cast<mitk::Image*>(node->GetData());
if(image.IsNull())
{
MITK_TEST_FAILED_MSG(<< "File "<< filename << " is not an image - test will not be applied." );
return;
}
// note importance of minor differences in spacings:
// DICOM has order y-spacing, x-spacing, while in MITK we assume x-spacing, y-spacing (both meant for 0 and 1 index in array)
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(image->GetGeometry()->GetSpacing()[0], 0.3141592), "correct x spacing? found "
<< image->GetGeometry()->GetSpacing()[0]);
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(image->GetGeometry()->GetSpacing()[1], 0.3411592), "correct y spacing? found "
<< image->GetGeometry()->GetSpacing()[1]);
}
int mitkDICOMLocaleTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("DICOMLocaleTest");
MITK_TEST_CONDITION_REQUIRED(argc >= 2, "File to load has been specified on commandline");
MITK_TEST_OUTPUT(<< "Configuration: \n" << mitk::DicomSeriesReader::GetConfigurationString() );
std::string filename = argv[1];
// load a reference DICOM file with the "C" locale being set
mitkDICOMLocaleTestChangeLocale("C");
mitkDICOMLocaleTestWithReferenceImage(filename);
// load a reference DICOM file with German locales being set
typedef std::list<std::string> StringList;
StringList alllocales;
alllocales.push_back("de_DE");
alllocales.push_back("de_DE.utf8");
alllocales.push_back("de_DE.UTF8");
alllocales.push_back("de_DE@euro");
alllocales.push_back("German_Germany");
// supressing this test to be run on MacOS X
// See bug #3894
#if defined (__APPLE__) || defined(MACOSX)
alllocales.push_back("C");
#endif
unsigned int numberOfTestedGermanLocales(0);
for (StringList::iterator iter = alllocales.begin();
iter != alllocales.end();
++iter)
{
if ( mitkDICOMLocaleTestChangeLocale(*iter) )
{
++numberOfTestedGermanLocales;
mitkDICOMLocaleTestWithReferenceImage(filename);
}
}
if(numberOfTestedGermanLocales == 0)
{
MITK_TEST_OUTPUT(<< "Warning: No German locale was found on the system.");
}
//MITK_TEST_CONDITION_REQUIRED( numberOfTestedGermanLocales > 0, "Verify that at least one German locale has been tested.");
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkDataNodeFactoryTest.cpp b/Core/Code/Testing/mitkDataNodeFactoryTest.cpp
index 6e2b7975cd..f43bdfa558 100644
--- a/Core/Code/Testing/mitkDataNodeFactoryTest.cpp
+++ b/Core/Code/Testing/mitkDataNodeFactoryTest.cpp
@@ -1,72 +1,71 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDataNodeFactory.h"
#include "mitkTestingMacros.h"
#include "mitkProperties.h"
#include <itksys/SystemTools.hxx>
#include <itksys/Directory.hxx>
/**
* Test for the class "DataNodeFactory".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkDataNodeFactoryTest(int, char* argv[])
{
// always start with this!
MITK_TEST_BEGIN("DataNodeFactory")
mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
MITK_TEST_OUTPUT(<< "Loading file: " << argv[1]);
factory->SetFileName( argv[1] );
MITK_TEST_CONDITION_REQUIRED(strcmp(factory->GetFileName(),argv[1])==0,"Test for Set/GetFileName()");
factory->Update();
MITK_TEST_CONDITION_REQUIRED(factory->GetNumberOfOutputs() > 0, "file loaded");
MITK_TEST_OUTPUT(<< "Test function SetDefaultCommonProperties()");
mitk::DataNode::Pointer node = factory->GetOutput( 0 );
MITK_TEST_CONDITION_REQUIRED( node.IsNotNull(), "DataNodeFactory has returned a non-empty node.")
factory->SetDefaultCommonProperties(node);
// get file path and property
std::string filePath = itksys::SystemTools::GetFilenamePath(factory->GetFileName());
mitk::StringProperty::Pointer pathProp = dynamic_cast<mitk::StringProperty*>(node->GetProperty(mitk::StringProperty::PATH));
MITK_TEST_CONDITION_REQUIRED(strcmp(pathProp->GetValue(),filePath.c_str())==0,"Test for file path");
std::string fileName = factory->GetFileName();
std::string fileExtension = itksys::SystemTools::GetFilenameExtension(fileName);
if (fileName.substr(fileName.size()-3) == ".gz")
fileName = fileName.substr( 0, fileName.length()-3 );
fileName = fileName.substr(0,fileName.length()-fileExtension.length());
fileName = fileName.substr(filePath.length()+1, fileName.length());
mitk::StringProperty::Pointer nameProp = dynamic_cast<mitk::StringProperty*>(node->GetProperty("name"));
MITK_TEST_CONDITION_REQUIRED(strcmp(nameProp->GetValue(),fileName.c_str())==0,"Test for file name");
mitk::BoolProperty::Pointer visibleProp = dynamic_cast<mitk::BoolProperty*>(node->GetProperty("visible"));
MITK_TEST_CONDITION_REQUIRED(visibleProp->GetValue()==true,"Test for visibility");
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkDataNodeTest.cpp b/Core/Code/Testing/mitkDataNodeTest.cpp
index d4b9d52736..c8fef7f8dc 100644
--- a/Core/Code/Testing/mitkDataNodeTest.cpp
+++ b/Core/Code/Testing/mitkDataNodeTest.cpp
@@ -1,301 +1,300 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkDataNode.h"
#include <vtkWindow.h>
#include "mitkVtkPropRenderer.h"
#include "mitkTestingMacros.h"
#include "mitkGlobalInteraction.h"
#include <iostream>
//Basedata Test
#include <mitkRenderWindowFrame.h>
#include <mitkGeometryData.h>
#include <mitkGeometry2DData.h>
#include <mitkGradientBackground.h>
#include <mitkManufacturerLogo.h>
#include <mitkPointSet.h>
#include <mitkImage.h>
#include <mitkSurface.h>
//Mapper Test
#include <mitkGeometry2DDataMapper2D.h>
#include <mitkGeometry2DDataMapper2D.h>
#include <mitkImageVtkMapper2D.h>
#include <mitkPointSetGLMapper2D.h>
#include <mitkPolyDataGLMapper2D.h>
#include <mitkSurfaceGLMapper2D.h>
#include <mitkGeometry2DDataVtkMapper3D.h>
#include <mitkPointSetVtkMapper3D.h>
#include <mitkSurfaceVtkMapper3D.h>
#include <mitkVolumeDataVtkMapper3D.h>
//Interactors
#include <mitkAffineInteractor.h>
#include <mitkPointSetInteractor.h>
//Propertylist Test
/**
* Simple example for a test for the (non-existent) class "DataNode".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
class mitkDataNodeTestClass { public:
static void TestDataSetting(mitk::DataNode::Pointer dataNode)
{
mitk::BaseData::Pointer baseData;
//NULL pointer Test
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a NULL pointer was set correctly" )
baseData = mitk::RenderWindowFrame::New();
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a RenderWindowFrame object was set correctly" )
// MITK_TEST_CONDITION( baseData->GetGeometry(0)->GetVtkTransform() == dataNode->GetVtkTransform(0), "Testing if a NULL pointer was set correctly" )
baseData = mitk::GeometryData::New();
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GeometryData object was set correctly" )
baseData = mitk::Geometry2DData::New();
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Geometry2DData object was set correctly" )
baseData = mitk::GradientBackground::New();
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a GradientBackground object was set correctly" )
baseData = mitk::ManufacturerLogo::New();
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a ManufacturerLogo object was set correctly" )
baseData = mitk::PointSet::New();
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a PointSet object was set correctly" )
baseData = mitk::Image::New();
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Image object was set correctly" )
baseData = mitk::Surface::New();
dataNode->SetData(baseData);
MITK_TEST_CONDITION( baseData == dataNode->GetData(), "Testing if a Surface object was set correctly" )
}
static void TestMapperSetting(mitk::DataNode::Pointer dataNode)
{
//tests the SetMapper() method
//in dataNode is a mapper vector which can be accessed by index
//in this test method we use only slot 0 (filled with null) and slot 1
//so we also test the destructor of the mapper classes
mitk::Mapper::Pointer mapper;
dataNode->SetMapper(0,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(0), "Testing if a NULL pointer was set correctly" )
mapper = mitk::Geometry2DDataMapper2D::New();
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a Geometry2DDataMapper2D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
mapper = mitk::ImageVtkMapper2D::New();
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a ImageVtkMapper2D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
mapper = mitk::PointSetGLMapper2D::New();
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetGLMapper2D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PolyDataGLMapper2D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
mapper = mitk::SurfaceGLMapper2D::New();
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceGLMapper2D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
mapper = mitk::Geometry2DDataVtkMapper3D::New();
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a Geometry2DDataVtkMapper3D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
mapper = mitk::PointSetVtkMapper3D::New();
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a PointSetVtkMapper3D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
mapper = mitk::SurfaceVtkMapper3D::New();
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a SurfaceVtkMapper3D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
mapper = mitk::VolumeDataVtkMapper3D::New();
dataNode->SetMapper(1,mapper);
MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a VolumeDataVtkMapper3D was set correctly" )
MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
//linker error
//mapper = mitk::LineVtkMapper3D::New();
//dataNode->SetMapper(1,mapper);
//MITK_TEST_CONDITION( mapper == dataNode->GetMapper(1), "Testing if a LineVtkMapper3D was set correctly" )
//MITK_TEST_CONDITION( dataNode == mapper->GetDataNode(), "Testing if the mapper returns the right DataNode" )
}
static void TestInteractorSetting(mitk::DataNode::Pointer dataNode)
{
//this method tests the SetInteractor() and GetInteractor methods
//the Interactor base class calls the DataNode->SetInteractor method
mitk::Interactor::Pointer interactor;
MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a NULL pointer was set correctly (Interactor)" )
interactor = mitk::AffineInteractor::New("AffineInteractions click to select", dataNode);
dataNode->EnableInteractor();
dataNode->DisableInteractor();
MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a AffineInteractor was set correctly" )
interactor = mitk::PointSetInteractor::New("AffineInteractions click to select", dataNode);
MITK_TEST_CONDITION( interactor == dataNode->GetInteractor(), "Testing if a PointSetInteractor was set correctly" )
}
static void TestPropertyList(mitk::DataNode::Pointer dataNode)
{
mitk::PropertyList::Pointer propertyList = dataNode->GetPropertyList();
MITK_TEST_CONDITION(dataNode->GetPropertyList() != NULL, "Testing if the constructor set the propertylist" )
dataNode->SetIntProperty("int", -31337);
int x;
dataNode->GetIntProperty("int", x);
MITK_TEST_CONDITION(x == -31337, "Testing Set/GetIntProperty");
dataNode->SetBoolProperty("bool", true);
bool b;
dataNode->GetBoolProperty("bool", b);
MITK_TEST_CONDITION(b == true, "Testing Set/GetBoolProperty");
dataNode->SetFloatProperty("float", -31.337);
float y;
dataNode->GetFloatProperty("float", y);
MITK_TEST_CONDITION(y - -31.337 < 0.01, "Testing Set/GetFloatProperty");
dataNode->SetStringProperty("string", "MITK");
std::string s = "GANZVIELPLATZ";
dataNode->GetStringProperty("string", s);
MITK_TEST_CONDITION(s == "MITK", "Testing Set/GetStringProperty");
std::string name = "MyTestName";
dataNode->SetName(name.c_str());
MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName");
name = "MySecondTestName";
dataNode->SetName(name);
MITK_TEST_CONDITION(dataNode->GetName() == name, "Testing Set/GetName(std::string)");
MITK_TEST_CONDITION(propertyList == dataNode->GetPropertyList(), "Testing if the propertylist has changed during the last tests" )
}
static void TestSelected(mitk::DataNode::Pointer dataNode)
{
vtkRenderWindow *renderWindow = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer base = mitk::VtkPropRenderer::New( "the first renderer", renderWindow, mitk::RenderingManager::GetInstance() );
//with BaseRenderer==Null
MITK_TEST_CONDITION(!dataNode->IsSelected(), "Testing if this node is not set as selected" )
dataNode->SetSelected(true);
MITK_TEST_CONDITION(dataNode->IsSelected(), "Testing if this node is set as selected" )
dataNode->SetSelected(false);
dataNode->SetSelected(true,base);
MITK_TEST_CONDITION(dataNode->IsSelected(base), "Testing if this node with right base renderer is set as selected" )
//Delete RenderWindow correctly
renderWindow->Delete();
}
static void TestGetMTime(mitk::DataNode::Pointer dataNode)
{
unsigned long time;
time = dataNode->GetMTime();
mitk::PointSet::Pointer pointSet = mitk::PointSet::New();
dataNode->SetData(pointSet);
MITK_TEST_CONDITION( time != dataNode->GetMTime(), "Testing if the node timestamp is updated after adding data to the node" )
mitk::Point3D point;
point.Fill(3.0);
pointSet->SetPoint(0,point);
//less or equal because dataNode timestamp is little later then the basedata timestamp
MITK_TEST_CONDITION( pointSet->GetMTime() <= dataNode->GetMTime(), "Testing if the node timestamp is updated after base data was modified" )
// testing if changing anything in the property list also sets the node in a modified state
unsigned long lastModified = dataNode->GetMTime();
dataNode->SetIntProperty("testIntProp", 2344);
MITK_TEST_CONDITION( lastModified <= dataNode->GetMTime(), "Testing if the node timestamp is updated after property list was modified" )
}
}; //mitkDataNodeTestClass
int mitkDataNodeTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("DataNode")
// Global interaction must(!) be initialized
mitk::GlobalInteraction::GetInstance()->Initialize("global");
// let's create an object of our class
mitk::DataNode::Pointer myDataNode = mitk::DataNode::New();
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
MITK_TEST_CONDITION_REQUIRED(myDataNode.IsNotNull(),"Testing instantiation")
//test setData() Method
mitkDataNodeTestClass::TestDataSetting(myDataNode);
mitkDataNodeTestClass::TestMapperSetting(myDataNode);
//
//note, that no data is set to the dataNode
mitkDataNodeTestClass::TestInteractorSetting(myDataNode);
mitkDataNodeTestClass::TestPropertyList(myDataNode);
mitkDataNodeTestClass::TestSelected(myDataNode);
mitkDataNodeTestClass::TestGetMTime(myDataNode);
// write your own tests here and use the macros from mitkTestingMacros.h !!!
// do not write to std::cout and do not return from this function yourself!
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkDataStorageTest.cpp b/Core/Code/Testing/mitkDataStorageTest.cpp
index 501ca6b46e..759e652e47 100644
--- a/Core/Code/Testing/mitkDataStorageTest.cpp
+++ b/Core/Code/Testing/mitkDataStorageTest.cpp
@@ -1,876 +1,875 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <fstream>
#include <algorithm>
#include "mitkImage.h"
#include "mitkSurface.h"
#include "mitkStringProperty.h"
#include "mitkColorProperty.h"
#include "mitkGroupTagProperty.h"
#include "mitkDataNode.h"
#include "mitkReferenceCountWatcher.h"
#include "mitkDataStorage.h"
#include "mitkStandaloneDataStorage.h"
#include "mitkNodePredicateProperty.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateDimension.h"
#include "mitkNodePredicateData.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateAnd.h"
#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateSource.h"
#include "mitkMessage.h"
//#include "mitkPicFileReader.h"
#include "mitkTestingMacros.h"
#include "mitkItkImageFileReader.h"
void TestDataStorage(mitk::DataStorage* ds, std::string filename);
namespace mitk
{
class TestStandaloneDataStorage: public StandaloneDataStorage
{
public:
mitkClassMacro(TestStandaloneDataStorage, mitk::DataStorage);
itkNewMacro(Self);
std::map<const mitk::DataNode*, unsigned long>
GetModifiedObserverTags() const {return m_NodeModifiedObserverTags;}
std::map<const mitk::DataNode*, unsigned long>
GetDeletedObserverTags() const { return m_NodeDeleteObserverTags; }
protected:
TestStandaloneDataStorage() {}
};
}
class DSEventReceiver // Helper class for event testing
{
public:
const mitk::DataNode* m_NodeAdded;
const mitk::DataNode* m_NodeRemoved;
DSEventReceiver()
: m_NodeAdded(NULL), m_NodeRemoved(NULL)
{
}
void OnAdd(const mitk::DataNode* node)
{
m_NodeAdded = node;
}
void OnRemove(const mitk::DataNode* node)
{
m_NodeRemoved = node;
}
};
///
/// \brief a class for checking if the datastorage is really thread safe
///
/// Therefore it listens to a node contained in the datastorage. when this node
/// gets removed and deleted, this class gets informed by calling OnObjectDelete().
/// in OnObjectDelete() an empty node gets added. this must not cause a deadlock
///
struct ItkDeleteEventListener
{
ItkDeleteEventListener( mitk::DataStorage* ds )
: m_Node(0), m_DataStorage(ds),
m_DeleteObserverTag(0)
{
}
void SetNode( mitk::DataNode* _Node )
{
if(m_Node)
return;
m_Node = _Node;
itk::MemberCommand<ItkDeleteEventListener>::Pointer onObjectDelete =
itk::MemberCommand<ItkDeleteEventListener>::New();
onObjectDelete->SetCallbackFunction(this, &ItkDeleteEventListener::OnObjectDelete);
m_DeleteObserverTag = m_Node->AddObserver(itk::DeleteEvent(), onObjectDelete);
}
void OnObjectDelete( const itk::Object* /*caller*/, const itk::EventObject & )
{
mitk::DataNode::Pointer node = mitk::DataNode::New();
m_DataStorage->Add( node ); // SHOULD NOT CAUSE A DEADLOCK!
m_DataStorage->Remove( node ); // tidy up: remove the empty node again
m_Node = 0;
}
protected:
mitk::DataNode* m_Node;
mitk::DataStorage::Pointer m_DataStorage;
unsigned int m_DeleteObserverTag;
};
//## Documentation
//## main testing method
//## NOTE: the current Singleton implementation of DataTreeStorage will lead to crashes if a testcase fails
//## and therefore mitk::DataStorage::ShutdownSingleton() is not called.
int mitkDataStorageTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("DataStorageTest");
// muellerm: test observer tag remove
mitk::TestStandaloneDataStorage::Pointer testDS
= mitk::TestStandaloneDataStorage::New();
mitk::DataNode::Pointer n1 = mitk::DataNode::New();
testDS->Add(n1);
MITK_TEST_CONDITION_REQUIRED(
testDS->GetModifiedObserverTags().size()==1, "Testing if modified"
" observer was added.");
MITK_TEST_CONDITION_REQUIRED(
testDS->GetDeletedObserverTags().size()==1, "Testing if delete"
" observer was added.");
testDS->Remove(n1);
MITK_TEST_CONDITION_REQUIRED(
testDS->GetModifiedObserverTags().size()==0, "Testing if modified"
" observer was removed.");
MITK_TEST_CONDITION_REQUIRED(
testDS->GetDeletedObserverTags().size()==0, "Testing if delete"
" observer was removed.");
/* Create StandaloneDataStorage */
MITK_TEST_OUTPUT( << "Create StandaloneDataStorage : ");
mitk::StandaloneDataStorage::Pointer sds;
try
{
sds = mitk::StandaloneDataStorage::New();
MITK_TEST_CONDITION_REQUIRED(sds.IsNotNull(), "Testing Instatiation");
}
catch (...)
{
MITK_TEST_FAILED_MSG( << "Exception during creation of StandaloneDataStorage");
}
MITK_TEST_OUTPUT( << "Testing StandaloneDataStorage: ");
MITK_TEST_CONDITION_REQUIRED(argc>1, "Testing correct test invocation");
TestDataStorage(sds,argv[1]);
// TODO: Add specific StandaloneDataStorage Tests here
sds = NULL;
MITK_TEST_END();
}
//##Documentation
//## @brief Test for the DataStorage class and its associated classes (e.g. the predicate classes)
//## This method will be called once for each subclass of DataStorage
void TestDataStorage( mitk::DataStorage* ds, std::string filename )
{
/* DataStorage valid? */
MITK_TEST_CONDITION_REQUIRED(ds != NULL, "DataStorage valid?");
// Take the ItkImageFile Reader for the .nrrd data format.
// (was previously pic which is now deprecated format)
mitk::ItkImageFileReader::Pointer reader = mitk::ItkImageFileReader::New();
reader -> SetFileName(filename.c_str());
reader -> Update();
mitk::Image::Pointer image = reader->GetOutput();
// create some DataNodes to fill the ds
mitk::DataNode::Pointer n1 = mitk::DataNode::New(); // node with image and name property
// mitk::Image::Pointer image = mitk::Image::New();
// unsigned int imageDimensions[] = { 10, 10, 10, 10 };
// mitk::PixelType pt(typeid(int));
// image->Initialize( pt, 4, imageDimensions );
n1->SetData(image);
n1->SetProperty("name", mitk::StringProperty::New("Node 1 - Image Node"));
mitk::DataStorage::SetOfObjects::Pointer parents1 = mitk::DataStorage::SetOfObjects::New();
mitk::DataNode::Pointer n2 = mitk::DataNode::New(); // node with surface and name and color properties
mitk::Surface::Pointer surface = mitk::Surface::New();
n2->SetData(surface);
n2->SetProperty("name", mitk::StringProperty::New("Node 2 - Surface Node"));
mitk::Color color; color.Set(1.0f, 1.0f, 0.0f);
n2->SetColor(color);
n2->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New());
mitk::DataStorage::SetOfObjects::Pointer parents2 = mitk::DataStorage::SetOfObjects::New();
parents2->InsertElement(0, n1); // n1 (image node) is source of n2 (surface node)
mitk::DataNode::Pointer n3 = mitk::DataNode::New(); // node without data but with name property
n3->SetProperty("name", mitk::StringProperty::New("Node 3 - Empty Node"));
n3->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New());
n3->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New());
mitk::DataStorage::SetOfObjects::Pointer parents3 = mitk::DataStorage::SetOfObjects::New();
parents3->InsertElement(0, n2); // n2 is source of n3
mitk::DataNode::Pointer n4 = mitk::DataNode::New(); // node without data but with color property
n4->SetColor(color);
n4->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New());
mitk::DataStorage::SetOfObjects::Pointer parents4 = mitk::DataStorage::SetOfObjects::New();
parents4->InsertElement(0, n2);
parents4->InsertElement(1, n3); // n2 and n3 are sources of n4
mitk::DataNode::Pointer n5 = mitk::DataNode::New(); // extra node
n5->SetProperty("name", mitk::StringProperty::New("Node 5"));
try /* adding objects */
{
/* Add an object */
ds->Add(n1, parents1);
MITK_TEST_CONDITION_REQUIRED((ds->GetAll()->Size() == 1) && (ds->GetAll()->GetElement(0) == n1), "Testing Adding a new object");
/* Check exception on adding the same object again */
MITK_TEST_OUTPUT( << "Check exception on adding the same object again: ");
MITK_TEST_FOR_EXCEPTION(..., ds->Add(n1, parents1));
MITK_TEST_CONDITION(ds->GetAll()->Size() == 1, "Test if object count is correct after exception");
/* Add an object that has a source object */
ds->Add(n2, parents2);
MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 2, "Testing Adding an object that has a source object");
/* Add some more objects needed for further tests */
ds->Add(n3, parents3); // n3 object that has name property and one parent
ds->Add(n4, parents4); // n4 object that has color property
ds->Add(n5); // n5 has no parents
MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 5, "Adding some more objects needed for further tests");
}
catch(...)
{
MITK_TEST_FAILED_MSG( << "Exeption during object creation");
}
try /* object retrieval methods */
{
/* Requesting all Objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll();
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(stlAll.size() == 5) // check if all tree nodes are in resultset
&& (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()),
"Testing GetAll()"
);
}
/* Requesting a named object */
{
mitk::NodePredicateProperty::Pointer predicate(mitk::NodePredicateProperty::New("name", mitk::StringProperty::New("Node 2 - Surface Node")));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting a named object");
}
/* Requesting objects of specific data type */
{
mitk::NodePredicateDataType::Pointer predicate(mitk::NodePredicateDataType::New("Image"));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific data type")
}
/* Requesting objects of specific dimension */
{
mitk::NodePredicateDimension::Pointer predicate(mitk::NodePredicateDimension::New( 4 ));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific dimension")
}
/* Requesting objects with specific data object */
{
mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(image));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects with specific data object")
}
/* Requesting objects with NULL data */
{
mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(NULL));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION(
(all->Size() == 3)
&& (std::find(all->begin(), all->end(), n3) != all->end())
&& (std::find(all->begin(), all->end(), n4) != all->end())
&& (std::find(all->begin(), all->end(), n5) != all->end())
, "Requesting objects with NULL data");
}
/* Requesting objects that meet a conjunction criteria */
{
mitk::NodePredicateDataType::Pointer p1 = mitk::NodePredicateDataType::New("Surface");
mitk::NodePredicateProperty::Pointer p2 = mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color));
mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New();
predicate->AddPredicate(p1);
predicate->AddPredicate(p2); // objects must be of datatype "Surface" and have red color (= n2)
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting objects that meet a conjunction criteria");
}
/* Requesting objects that meet a disjunction criteria */
{
mitk::NodePredicateDataType::Pointer p1(mitk::NodePredicateDataType::New("Image"));
mitk::NodePredicateProperty::Pointer p2(mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color)));
mitk::NodePredicateOr::Pointer predicate = mitk::NodePredicateOr::New();
predicate->AddPredicate(p1);
predicate->AddPredicate(p2); // objects must be of datatype "Surface" or have red color (= n1, n2, n4)
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION(
(all->Size() == 3)
&& (std::find(all->begin(), all->end(), n1) != all->end())
&& (std::find(all->begin(), all->end(), n2) != all->end())
&& (std::find(all->begin(), all->end(), n4) != all->end()),
"Requesting objects that meet a disjunction criteria");
}
/* Requesting objects that do not meet a criteria */
{
mitk::ColorProperty::Pointer cp = mitk::ColorProperty::New(color);
mitk::NodePredicateProperty::Pointer proppred(mitk::NodePredicateProperty::New("color", cp));
mitk::NodePredicateNot::Pointer predicate(mitk::NodePredicateNot::New(proppred));
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 3) // check if correct objects are in resultset
&& (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()), "Requesting objects that do not meet a criteria");
}
/* Requesting *direct* source objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n3, NULL, true); // Get direct parents of n3 (=n2)
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 1) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
"Requesting *direct* source objects");
}
/* Requesting *all* source objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n3, NULL, false); // Get all parents of n3 (= n1 + n2)
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 2)
&& (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
"Requesting *all* source objects"); // check if n1 and n2 are the resultset
}
/* Requesting *all* sources of object with multiple parents */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, NULL, false); // Get all parents of n4 (= n1 + n2 + n3)
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 3)
&& (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset
, "Requesting *all* sources of object with multiple parents");
}
/* Requesting *direct* derived objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, NULL, true); // Get direct childs of n1 (=n2)
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 1)
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())// check if n1 is the resultset
, "Requesting *direct* derived objects");
}
///* Requesting *direct* derived objects with multiple parents/derivations */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n2, NULL, true); // Get direct childs of n2 (=n3 + n4)
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 2)
&& (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n3 is the resultset
&& (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()) // check if n4 is the resultset
, "Requesting *direct* derived objects with multiple parents/derivations");
}
//* Requesting *all* derived objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, NULL, false); // Get all childs of n1 (=n2, n3, n4)
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 3)
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
, "Requesting *all* derived objects");
}
/* Checking for circular source relationships */
{
parents1->InsertElement(0, n4); // make n1 derived from n4 (which is derived from n2, which is derived from n1)
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, NULL, false); // Get all parents of n4 (= n1 + n2 + n3, not n4 itself and not multiple versions of the nodes!)
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 3)
&& (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset
, "Checking for circular source relationships");
}
///* Checking for circular derivation relationships can not be performed, because the internal derivations datastructure
// can not be accessed from the outside. (Therefore it should not be possible to create these circular relations */
//* Checking GroupTagProperty */
{
mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New();
mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 1", tp));
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred);
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 2) // check if n2 and n3 are in resultset
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
, "Checking GroupTagProperty");
}
/* Checking GroupTagProperty 2 */
{
mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New();
mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 2", tp));
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred);
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 2) // check if n3 and n4 are in resultset
&& (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
, "Checking GroupTagProperty 2");
}
/* Checking direct sources with condition */
{
mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Surface");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, true);
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 1) // check if n2 is in resultset
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
, "checking direct sources with condition");
}
/* Checking all sources with condition */
{
mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Image");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false);
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 1) // check if n1 is in resultset
&& (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
, "Checking all sources with condition");
}
/* Checking all sources with condition with empty resultset */
{
mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("VesselTree");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false);
MITK_TEST_CONDITION(all->Size() == 0 , "Checking all sources with condition with empty resultset"); // check if resultset is empty
}
/* Checking direct derivations with condition */
{
mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, true);
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 1) // check if n2 is in resultset
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
, "Checking direct derivations with condition");
}
/* Checking all derivations with condition */
{
mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, false);
std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 2) // check if n2 and n4 are in resultset
&& (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
&& (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
, "Checking direct derivations with condition");
}
/* Checking named node method */
MITK_TEST_CONDITION(ds->GetNamedNode("Node 2 - Surface Node") == n2, "Checking named node method");
MITK_TEST_CONDITION(ds->GetNamedNode(std::string("Node 2 - Surface Node")) == n2, "Checking named node(std::string) method");
/* Checking named node method with wrong name */
MITK_TEST_CONDITION(ds->GetNamedNode("This name does not exist") == NULL, "Checking named node method with wrong name");
/* Checking named object method */
MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>("Node 1 - Image Node") == image, "Checking named object method");
MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>(std::string("Node 1 - Image Node")) == image, "Checking named object(std::string) method");
/* Checking named object method with wrong DataType */
MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Surface>("Node 1 - Image Node") == NULL, "Checking named object method with wrong DataType");
/* Checking named object method with wrong name */
MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>("This name does not exist") == NULL, "Checking named object method with wrong name");
/* Checking GetNamedDerivedNode with valid name and direct derivation only */
MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 2 - Surface Node", n1, true) == n2, "Checking GetNamedDerivedNode with valid name & direct derivation only");
/* Checking GetNamedDerivedNode with invalid Name and direct derivation only */
MITK_TEST_CONDITION(ds->GetNamedDerivedNode("wrong name", n1, true) == NULL, "Checking GetNamedDerivedNode with invalid name & direct derivation only");
/* Checking GetNamedDerivedNode with invalid Name and direct derivation only */
MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, false) == n3, "Checking GetNamedDerivedNode with invalid name & direct derivation only");
/* Checking GetNamedDerivedNode with valid Name but direct derivation only */
MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, true) == NULL, "Checking GetNamedDerivedNode with valid Name but direct derivation only");
/* Checking GetNode with valid predicate */
{
mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("Image"));
MITK_TEST_CONDITION(ds->GetNode(p) == n1, "Checking GetNode with valid predicate");
}
/* Checking GetNode with invalid predicate */
{
mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("PointSet"));
MITK_TEST_CONDITION(ds->GetNode(p) == NULL, "Checking GetNode with invalid predicate");
}
} // object retrieval methods
catch(...)
{
MITK_TEST_FAILED_MSG( << "Exeption during object retrieval (GetXXX() Methods)");
}
try /* object removal methods */
{
/* Checking removal of a node without relations */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
int refCountbeforeDS = watcher->GetReferenceCount();
ds->Add(extra);
MITK_TEST_CONDITION(ds->GetNamedNode("extra") == extra, "Adding extra node");
ds->Remove(extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == NULL)
&& (refCountbeforeDS == watcher->GetReferenceCount())
, "Checking removal of a node without relations");
extra = NULL;
}
/* Checking removal of a node with a parent */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
int refCountbeforeDS = watcher->GetReferenceCount();
ds->Add(extra, n1); // n1 is parent of extra
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == extra)
&& (ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1
, "Adding extra node");
ds->Remove(extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == NULL)
&& (refCountbeforeDS == watcher->GetReferenceCount())
&& (ds->GetDerivations(n1)->Size() == 1)
, "Checking removal of a node with a parent");
extra = NULL;
}
/* Checking removal of a node with two parents */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
int refCountbeforeDS = watcher->GetReferenceCount();
mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
p->push_back(n1);
p->push_back(n2);
ds->Add(extra, p); // n1 and n2 are parents of extra
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == extra)
&& (ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1
&& (ds->GetDerivations(n2)->Size() == 3)
, "add extra node");
ds->Remove(extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == NULL)
&& (refCountbeforeDS == watcher->GetReferenceCount())
&& (ds->GetDerivations(n1)->Size() == 1) // after remove, only n2 should be derived from n1
&& (ds->GetDerivations(n2)->Size() == 2) // after remove, only n3 and n4 should be derived from n2
, "Checking removal of a node with two parents");
extra = NULL;
}
/* Checking removal of a node with two derived nodes */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
int refCountbeforeDS = watcher->GetReferenceCount();
ds->Add(extra);
mitk::DataNode::Pointer d1 = mitk::DataNode::New();
d1->SetProperty("name", mitk::StringProperty::New("d1"));
ds->Add(d1, extra);
mitk::DataNode::Pointer d2 = mitk::DataNode::New();
d2->SetProperty("name", mitk::StringProperty::New("d2"));
ds->Add(d2, extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == extra)
&& (ds->GetNamedNode("d1") == d1)
&& (ds->GetNamedNode("d2") == d2)
&& (ds->GetSources(d1)->Size() == 1) // extra should be source of d1
&& (ds->GetSources(d2)->Size() == 1) // extra should be source of d2
&& (ds->GetDerivations(extra)->Size() == 2) // d1 and d2 should be derived from extra
, "add extra node");
ds->Remove(extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == NULL)
&& (ds->GetNamedNode("d1") == d1)
&& (ds->GetNamedNode("d2") == d2)
&& (refCountbeforeDS == watcher->GetReferenceCount())
&& (ds->GetSources(d1)->Size() == 0) // after remove, d1 should not have a source anymore
&& (ds->GetSources(d2)->Size() == 0) // after remove, d2 should not have a source anymore
, "Checking removal of a node with two derived nodes");
extra = NULL;
}
/* Checking removal of a node with two parents and two derived nodes */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
mitk::ReferenceCountWatcher::Pointer n1watcher = new mitk::ReferenceCountWatcher(n1);
int refCountbeforeDS = watcher->GetReferenceCount();
mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
p->push_back(n1);
p->push_back(n2);
ds->Add(extra, p); // n1 and n2 are parents of extra
mitk::DataNode::Pointer d1 = mitk::DataNode::New();
d1->SetProperty("name", mitk::StringProperty::New("d1x"));
ds->Add(d1, extra);
mitk::DataNode::Pointer d2 = mitk::DataNode::New();
d2->SetProperty("name", mitk::StringProperty::New("d2x"));
ds->Add(d2, extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == extra)
&& (ds->GetNamedNode("d1x") == d1)
&& (ds->GetNamedNode("d2x") == d2)
&& (ds->GetSources(d1)->Size() == 1) // extra should be source of d1
&& (ds->GetSources(d2)->Size() == 1) // extra should be source of d2
&& (ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1
&& (ds->GetDerivations(n2)->Size() == 3) // n3, n4 and extra should be derived from n2
&& (ds->GetDerivations(extra)->Size() == 2) // d1 and d2 should be derived from extra
, "add extra node");
ds->Remove(extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == NULL)
&& (ds->GetNamedNode("d1x") == d1)
&& (ds->GetNamedNode("d2x") == d2)
&& (refCountbeforeDS == watcher->GetReferenceCount())
&& (ds->GetDerivations(n1)->Size() == 1) // after remove, only n2 should be derived from n1
&& (ds->GetDerivations(n2)->Size() == 2) // after remove, only n3 and n4 should be derived from n2
&& (ds->GetSources(d1)->Size() == 0) // after remove, d1 should not have a source anymore
&& (ds->GetSources(d2)->Size() == 0) // after remove, d2 should not have a source anymore
, "Checking removal of a node with two parents and two derived nodes");
extra = NULL;
}
}
catch(...)
{
MITK_TEST_FAILED_MSG( << "Exeption during object removal methods");
}
/* Checking for node is it's own parent exception */
{
MITK_TEST_FOR_EXCEPTION_BEGIN(...);
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
p->push_back(n1);
p->push_back(extra); // extra is parent of extra!!!
ds->Add(extra, p);
MITK_TEST_FOR_EXCEPTION_END(...);
}
/* Checking reference count of node after add and remove */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
p->push_back(n1);
p->push_back(n3);
ds->Add(extra, p);
extra = NULL;
ds->Remove(ds->GetNamedNode("extra"));
MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Checking reference count of node after add and remove");
}
/* Checking removal of a node with two derived nodes [ dataStorage->GetDerivations( rootNode )] see bug #3426 */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
ds->Add(extra);
mitk::DataNode::Pointer d1y = mitk::DataNode::New();
d1y->SetProperty("name", mitk::StringProperty::New("d1y"));
mitk::ReferenceCountWatcher::Pointer watcherD1y = new mitk::ReferenceCountWatcher(d1y);
int refCountbeforeDS = watcherD1y->GetReferenceCount();
ds->Add(d1y, extra);
mitk::DataNode::Pointer d2y = mitk::DataNode::New();
d2y->SetProperty("name", mitk::StringProperty::New("d2y"));
ds->Add(d2y, extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == extra)
&& (ds->GetNamedNode("d1y") == d1y)
&& (ds->GetNamedNode("d2y") == d2y)
&& (ds->GetSources(d1y)->Size() == 1) // extra should be source of d1y
&& (ds->GetSources(d2y)->Size() == 1) // extra should be source of d2y
&& (ds->GetDerivations(extra)->Size() == 2) // d1y and d2y should be derived from extra
, "add extra node");
ds->Remove(ds->GetDerivations( extra));
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == extra)
&& (ds->GetNamedNode("d1y") == NULL) // d1y should be NULL now
&& (ds->GetNamedNode("d2y") == NULL) // d2y should be NULL now
&& (refCountbeforeDS == watcherD1y->GetReferenceCount())
, "Checking removal of subset of two derived nodes from one parent node");
ds->Remove(extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == NULL)
, "Checking removal of a parent node");
extra = NULL;
}
/* Checking GetGrouptags() */
{
const std::set<std::string> groupTags = ds->GetGroupTags();
MITK_TEST_CONDITION(
(groupTags.size() == 2)
&& (std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 1") != groupTags.end())
&& (std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 2") != groupTags.end())
, "Checking GetGrouptags()");
}
/* Checking Event handling */
DSEventReceiver listener;
try
{
ds->AddNodeEvent += mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
ds->RemoveNodeEvent += mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);
mitk::DataNode::Pointer extra = mitk::DataNode::New();
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
ds->Add(extra);
MITK_TEST_CONDITION(listener.m_NodeAdded == extra.GetPointer(), "Checking AddEvent");
ds->Remove(extra);
MITK_TEST_CONDITION(listener.m_NodeRemoved == extra.GetPointer(), "Checking RemoveEvent");
/* RemoveListener */
ds->AddNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
ds->RemoveNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);
listener.m_NodeAdded = NULL;
listener.m_NodeRemoved = NULL;
ds->Add(extra);
ds->Remove(extra);
MITK_TEST_CONDITION((listener.m_NodeRemoved == NULL) && (listener.m_NodeAdded == NULL), "Checking RemoveListener");
std::cout << "Pointer handling after event handling: " << std::flush;
extra = NULL; // delete reference to the node. its memory should be freed now
MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Pointer handling after event handling");
}
catch(...)
{
/* cleanup */
ds->AddNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
ds->RemoveNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);
MITK_TEST_FAILED_MSG( << "Exception during object removal methods");
}
//Checking ComputeBoundingGeometry3D method*/
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll();
mitk::TimeSlicedGeometry::Pointer geometry = ds->ComputeBoundingGeometry3D();
MITK_TEST_CONDITION(geometry->GetTimeSteps()==4, "Test for number or time steps with ComputeBoundingGeometry()");
mitk::TimeBounds timebounds = geometry->GetTimeBounds();
MITK_TEST_CONDITION((timebounds[0]==0)&&(timebounds[1]==4),"Test for timebounds with ComputeBoundingGeometry()");
for (unsigned int i=0; i<geometry->GetTimeSteps(); i++)
{
mitk::Geometry3D::Pointer subGeometry = geometry->GetGeometry3D(i);
mitk::TimeBounds bounds = subGeometry->GetTimeBounds();
MITK_TEST_CONDITION((bounds[0]==i)&&(bounds[1]==i+1),"Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()");
}
geometry = ds->ComputeBoundingGeometry3D(all);
MITK_TEST_CONDITION(geometry->GetTimeSteps()==4, "Test for number or time steps with ComputeBoundingGeometry(allNodes)");
timebounds = geometry->GetTimeBounds();
MITK_TEST_CONDITION((timebounds[0]==0)&&(timebounds[1]==4),"Test for timebounds with ComputeBoundingGeometry(allNodes)");
for (unsigned int i=0; i<geometry->GetTimeSteps(); i++)
{
mitk::Geometry3D::Pointer subGeometry = geometry->GetGeometry3D(i);
mitk::TimeBounds bounds = subGeometry->GetTimeBounds();
MITK_TEST_CONDITION((bounds[0]==i)&&(bounds[1]==i+1),"Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()");
}
// test for thread safety of DataStorage
try
{
mitk::StandaloneDataStorage::Pointer standaloneDataStorage
= mitk::StandaloneDataStorage::New();
ItkDeleteEventListener listener( standaloneDataStorage );
{
mitk::DataNode::Pointer emptyNode = mitk::DataNode::New();
mitk::DataNode* pEmptyNode = emptyNode;
listener.SetNode( emptyNode );
standaloneDataStorage->Add( emptyNode );
emptyNode = 0; // emptyNode is still alive because standaloneDataStorage
// owns it
standaloneDataStorage->Remove( pEmptyNode ); // this should not freeze the whole thing
}
}
catch(...)
{
MITK_TEST_FAILED_MSG( << "Exception during testing DataStorage thread safe");
}
/* Clear DataStorage */
ds->Remove(ds->GetAll());
MITK_TEST_CONDITION(ds->GetAll()->Size() == 0, "Checking Clear DataStorage");
}
diff --git a/Core/Code/Testing/mitkDicomSeriesReaderTest.cpp b/Core/Code/Testing/mitkDicomSeriesReaderTest.cpp
index 5bfc120a3c..9462c9c97c 100644
--- a/Core/Code/Testing/mitkDicomSeriesReaderTest.cpp
+++ b/Core/Code/Testing/mitkDicomSeriesReaderTest.cpp
@@ -1,163 +1,162 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include <iostream>
#include "mitkDicomSeriesReader.h"
#include "mitkProperties.h"
static std::map<std::string, std::map<gdcm::Tag, std::string> > GetTagInformationFromFile(mitk::DicomSeriesReader::StringContainer files)
{
gdcm::Scanner scanner;
std::map<std::string, std::map<gdcm::Tag, std::string> > tagInformations;
const gdcm::Tag tagSliceLocation(0x0020, 0x1041); // slice location
scanner.AddTag( tagSliceLocation );
const gdcm::Tag tagInstanceNumber(0x0020, 0x0013); // (image) instance number
scanner.AddTag( tagInstanceNumber );
const gdcm::Tag tagSOPInstanceNumber(0x0008, 0x0018); // SOP instance number
scanner.AddTag( tagSOPInstanceNumber );
//unsigned int slice(0);
scanner.Scan(files);
// return const_cast<gdcm::Scanner::MappingType&>(scanner.GetMappings());
gdcm::Scanner::MappingType& tagValueMappings = const_cast<gdcm::Scanner::MappingType&>(scanner.GetMappings());
for(std::vector<std::string>::const_iterator fIter = files.begin();
fIter != files.end();
++fIter)
{
std::map<gdcm::Tag, std::string> tags;
tags.insert(std::pair<gdcm::Tag, std::string> (tagSliceLocation, tagValueMappings[fIter->c_str()][tagSliceLocation]));
tags.insert(std::pair<gdcm::Tag, std::string> (tagInstanceNumber, tagValueMappings[fIter->c_str()][tagInstanceNumber]));
tags.insert(std::pair<gdcm::Tag, std::string> (tagSOPInstanceNumber, tagValueMappings[fIter->c_str()][tagSOPInstanceNumber]));
tagInformations.insert(std::pair<std::string, std::map<gdcm::Tag, std::string> > (fIter->c_str(), tags));
}
return tagInformations;
}
int mitkDicomSeriesReaderTest(int argc, char* argv[])
{
// always start with this!
MITK_TEST_BEGIN("DicomSeriesReader")
if(argc < 1)
{
MITK_ERROR << "No directory given!";
return -1;
}
char* dir;
dir = argv[1];
//check if DICOMTags have been set as property for mitk::Image
mitk::DicomSeriesReader::UidFileNamesMap seriesInFiles = mitk::DicomSeriesReader::GetSeries( dir );
std::list<mitk::Image::Pointer> images;
std::map<mitk::Image::Pointer, mitk::DicomSeriesReader::StringContainer> fileMap;
// TODO sort series UIDs, implementation of map iterator might differ on different platforms (or verify this is a standard topic??)
for (mitk::DicomSeriesReader::UidFileNamesMap::const_iterator seriesIter = seriesInFiles.begin();
seriesIter != seriesInFiles.end();
++seriesIter)
{
mitk::DicomSeriesReader::StringContainer files = seriesIter->second;
mitk::DataNode::Pointer node = mitk::DicomSeriesReader::LoadDicomSeries( files );
MITK_TEST_CONDITION_REQUIRED(node.IsNotNull(),"Testing node")
if (node.IsNotNull())
{
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>( node->GetData() );
images.push_back( image );
fileMap.insert( std::pair<mitk::Image::Pointer, mitk::DicomSeriesReader::StringContainer>(image,files));
}
}
//Test if DICOM tags have been added correctly to the mitk::image properties
const gdcm::Tag tagSliceLocation(0x0020, 0x1041); // slice location
const gdcm::Tag tagInstanceNumber(0x0020, 0x0013); // (image) instance number
const gdcm::Tag tagSOPInstanceNumber(0x0008, 0x0018); // SOP instance number
for ( std::list<mitk::Image::Pointer>::const_iterator imageIter = images.begin();
imageIter != images.end();
++imageIter )
{
const mitk::Image::Pointer image = *imageIter;
//Get tag information for all dicom files of this image
std::map<std::string, std::map<gdcm::Tag, std::string> > tagInformations = GetTagInformationFromFile((*fileMap.find(image)).second);
mitk::StringLookupTableProperty* sliceLocation = dynamic_cast<mitk::StringLookupTableProperty*>(image->GetProperty("dicom.image.0020.1041").GetPointer());
mitk::StringLookupTableProperty* instanceNumber = dynamic_cast<mitk::StringLookupTableProperty*>(image->GetProperty("dicom.image.0020.0013").GetPointer());
mitk::StringLookupTableProperty* SOPInstnaceNumber = dynamic_cast<mitk::StringLookupTableProperty*>(image->GetProperty("dicom.image.0008.0018").GetPointer());
mitk::StringLookupTableProperty* files = dynamic_cast<mitk::StringLookupTableProperty*>(image->GetProperty("files").GetPointer());
MITK_TEST_CONDITION(sliceLocation != NULL, "Test if tag for slice location has been set to mitk image");
if(sliceLocation != NULL)
{
for(int i = 0; i < (int)sliceLocation->GetValue().GetLookupTable().size(); i++)
{
if(i < (int)files->GetValue().GetLookupTable().size())
{
MITK_INFO << "Table value: " << sliceLocation->GetValue().GetTableValue(i) << " and File value: " << tagInformations[files->GetValue().GetTableValue(i).c_str()][tagSliceLocation] << std::endl;
MITK_INFO << "Filename: " << files->GetValue().GetTableValue(i).c_str() << std::endl;
MITK_TEST_CONDITION(sliceLocation->GetValue().GetTableValue(i) == tagInformations[files->GetValue().GetTableValue(i).c_str()][tagSliceLocation], "Test if value for slice location is correct");
}
}
}
MITK_TEST_CONDITION(instanceNumber != NULL, "Test if tag for image instance number has been set to mitk image");
if(instanceNumber != NULL)
{
for(int i = 0; i < (int)instanceNumber->GetValue().GetLookupTable().size(); i++)
{
if(i < (int)files->GetValue().GetLookupTable().size())
{
MITK_INFO << "Table value: " << instanceNumber->GetValue().GetTableValue(i) << " and File value: " << tagInformations[files->GetValue().GetTableValue(i).c_str()][tagInstanceNumber] << std::endl;
MITK_INFO << "Filename: " << files->GetValue().GetTableValue(i).c_str() << std::endl;
MITK_TEST_CONDITION(instanceNumber->GetValue().GetTableValue(i) == tagInformations[files->GetValue().GetTableValue(i).c_str()][tagInstanceNumber], "Test if value for instance number is correct");
}
}
}
MITK_TEST_CONDITION(SOPInstnaceNumber != NULL, "Test if tag for SOP instance number has been set to mitk image");
if(SOPInstnaceNumber != NULL)
{
for(int i = 0; i < (int)SOPInstnaceNumber->GetValue().GetLookupTable().size(); i++)
{
if(i < (int)files->GetValue().GetLookupTable().size())
{
MITK_INFO << "Table value: " << instanceNumber->GetValue().GetTableValue(i) << " and File value: " << tagInformations[files->GetValue().GetTableValue(i).c_str()][tagSOPInstanceNumber] << std::endl;
MITK_INFO << "Filename: " << files->GetValue().GetTableValue(i).c_str() << std::endl;
MITK_TEST_CONDITION(SOPInstnaceNumber->GetValue().GetTableValue(i) == tagInformations[files->GetValue().GetTableValue(i).c_str()][tagSOPInstanceNumber], "Test if value for SOP instance number is correct");
}
}
}
}
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkEnumerationPropertyTest.cpp b/Core/Code/Testing/mitkEnumerationPropertyTest.cpp
index 0ff5b67a13..51e1827496 100644
--- a/Core/Code/Testing/mitkEnumerationPropertyTest.cpp
+++ b/Core/Code/Testing/mitkEnumerationPropertyTest.cpp
@@ -1,184 +1,183 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <vtkProperty.h>
#include "mitkEnumerationProperty.h"
#include "mitkVtkInterpolationProperty.h"
#include "mitkVtkRepresentationProperty.h"
int mitkEnumerationPropertyTest( int /*argc*/, char* /*argv*/[] )
{
mitk::EnumerationProperty::Pointer enumerationProperty(mitk::EnumerationProperty::New());
std::cout << "Testing mitk::EnumerationProperty::AddEnum(...): ";
bool success = true;
success = success && enumerationProperty->AddEnum( "first", 1 );
success = success && enumerationProperty->AddEnum( "second", 2 );
success = success && enumerationProperty->AddEnum( "third", 3 );
if ( ! success )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
else
{
std::cout << "[PASSED]" << std::endl;
}
std::cout << "Testing mitk::EnumerationProperty::Size(): " ;
if ( enumerationProperty->Size() != 3 )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
else
{
std::cout << "[PASSED]" << std::endl;
}
std::cout << "Testing mitk::EnumerationProperty::AddEnum() with invalid entries: ";
if ( enumerationProperty->AddEnum( "first", 0 ) )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
else
{
std::cout << "[PASSED]" << std::endl;
}
std::cout << "Testing mitk::EnumerationProperty::SetValue(id): ";
if ( ! enumerationProperty->SetValue( 2 ) )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if ( enumerationProperty->GetValueAsId() != 2 )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if ( enumerationProperty->GetValueAsString() != "second" )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing mitk::EnumerationProperty::SetValue(name): ";
if ( ! enumerationProperty->SetValue( "third" ) )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if ( enumerationProperty->GetValueAsId() != 3 )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if ( enumerationProperty->GetValueAsString() != "third" )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing mitk::EnumerationProperty::SetValue(invalid id): ";
if ( enumerationProperty->SetValue( 100 ) )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing mitk::EnumerationProperty::SetValue(invalid name): ";
if ( enumerationProperty->SetValue( "madmax" ) )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing mitk::VtkInterpolationType::SetInterpolationToPhong(): ";
mitk::VtkInterpolationProperty::Pointer vtkInterpolationProperty(mitk::VtkInterpolationProperty::New());;
vtkInterpolationProperty->SetInterpolationToPhong();
if ( vtkInterpolationProperty->GetValueAsString() != "Phong" )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if ( vtkInterpolationProperty->GetValueAsId() != 2 )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if ( vtkInterpolationProperty->GetVtkInterpolation() != VTK_PHONG )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing mitk::VtkRepresentationType::SetRepresentationToWireframe(): ";
mitk::VtkRepresentationProperty::Pointer vtkRepresentationProperty(mitk::VtkRepresentationProperty::New());
vtkRepresentationProperty->SetRepresentationToWireframe();
if ( vtkRepresentationProperty->GetValueAsString() != "Wireframe" )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if ( vtkRepresentationProperty->GetValueAsId() != 1 )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if ( vtkRepresentationProperty->GetVtkRepresentation() != VTK_WIREFRAME )
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "[TEST DONE]" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkEventMapperTest.cpp b/Core/Code/Testing/mitkEventMapperTest.cpp
index 5fa4b7389f..258c766f5e 100644
--- a/Core/Code/Testing/mitkEventMapperTest.cpp
+++ b/Core/Code/Testing/mitkEventMapperTest.cpp
@@ -1,87 +1,86 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-09-17 17:05:25 +0200 (Do, 17 Sep 2009) $
-Version: $Revision: 19043 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkEventMapper.h>
#include <mitkEvent.h>
#include <mitkInteractionConst.h>
#include "mitkTestingMacros.h"
#include <mitkStateEvent.h>
int mitkEventMapperTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("EventMapper");
MITK_TEST_CONDITION_REQUIRED(argc >= 3, "Test if a file to load has been specified");
//construct IDs to be checked
mitk::Event* mouseButtonPressEvent = new mitk::Event(NULL, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none);
const int mouseButtonPressID = 1;
//there is no combination Type_MouseButtonPress and Keys, so use this to be sure to have unique events
mitk::Event* uniqueEventFile1 = new mitk::Event(NULL, mitk::Type_MouseButtonPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_R);
const int uniqueEventIDFile1 = 13000;
mitk::Event* uniqueEventFile2 = new mitk::Event(NULL, mitk::Type_MouseButtonPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_N);
const int uniqueEventIDFile2 = 13001;
//create statemachinefactory
mitk::EventMapper* eventMapper = mitk::EventMapper::New();
//load standard behavior
MITK_TEST_CONDITION_REQUIRED(eventMapper->LoadStandardBehavior(),"Testing LoadStandardBehavior(): ")
std::cout<<"StyleName: " << eventMapper->GetStyleName()<<"\n";
mitk::StateEvent stateEvent;
stateEvent.Set(0, mouseButtonPressEvent);
eventMapper->RefreshStateEvent(&stateEvent);
MITK_TEST_CONDITION_REQUIRED(stateEvent.GetId() == mouseButtonPressID,"Testing event mapping of standard xml-file: ")
// std::string xmlFileName1( "TestStateMachine1.xml" );
std::string xmlFileName1( argv[1] );
MITK_TEST_CONDITION_REQUIRED(!xmlFileName1.empty(),"Getting xml file 1: ")
MITK_TEST_CONDITION_REQUIRED(eventMapper->LoadBehavior(xmlFileName1),"Parsing xml file 1 should throw warning: ")
//test dubicate file loading
MITK_TEST_CONDITION_REQUIRED(eventMapper->LoadBehavior(xmlFileName1) == true,"Double parsing should be avoided and not throw warnings.")
stateEvent.Set(0, uniqueEventFile1);
eventMapper->RefreshStateEvent(&stateEvent);
MITK_TEST_CONDITION_REQUIRED(stateEvent.GetId() == uniqueEventIDFile1,"Testing event mapping of first additionally loaded xml-file: ")
//global still accessible?
stateEvent.Set(0, mouseButtonPressEvent);
eventMapper->RefreshStateEvent(&stateEvent);
MITK_TEST_CONDITION_REQUIRED(stateEvent.GetId() == mouseButtonPressID,"Testing if standard information still available: ")
// std::string xmlFileName2( "TestStateMachine2.xml" );
std::string xmlFileName2( argv[2] );
MITK_TEST_CONDITION_REQUIRED(!xmlFileName2.empty(),"Getting xml file 2: ")
MITK_TEST_CONDITION_REQUIRED(eventMapper->LoadBehavior(xmlFileName2),"Parsing xml file 2. Warning of double entry should be thrown: ")
stateEvent.Set(0, uniqueEventFile2);
eventMapper->RefreshStateEvent(&stateEvent);
MITK_TEST_CONDITION_REQUIRED(stateEvent.GetId() == uniqueEventIDFile2,"Testing event mapping of second additionally loaded xml-file: ")
//global still accessible?
stateEvent.Set(0, mouseButtonPressEvent);
eventMapper->RefreshStateEvent(&stateEvent);
MITK_TEST_CONDITION_REQUIRED(stateEvent.GetId() == mouseButtonPressID,"Testing if standard information still available: ")
eventMapper->Delete();
// always end with this!
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkEventTest.cpp b/Core/Code/Testing/mitkEventTest.cpp
index 82d0538d01..e602f961a6 100644
--- a/Core/Code/Testing/mitkEventTest.cpp
+++ b/Core/Code/Testing/mitkEventTest.cpp
@@ -1,54 +1,53 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkEvent.h"
#include "mitkVtkPropRenderer.h"
#include "mitkTestingMacros.h"
#include "mitkGlobalInteraction.h"
int mitkEventTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("Event")
// Global interaction must(!) be initialized if used
mitk::GlobalInteraction::GetInstance()->Initialize("global");
vtkRenderWindow* renWin = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer renderer = mitk::VtkPropRenderer::New( "ContourRenderer",renWin, mitk::RenderingManager::GetInstance() );
//Create Event
mitk::Event * event = new mitk::Event(renderer, 0, 1, 2, 3);
//check Get...
MITK_TEST_CONDITION_REQUIRED(
event->GetSender() == renderer ||
event->GetType() == 0 ||
event->GetButton() == 1 ||
event->GetButtonState() == 2 ||
event->GetKey() == 3
, "Checking Get methods of mitk::Event");
renWin->Delete();
delete event;
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkExceptionTest.cpp b/Core/Code/Testing/mitkExceptionTest.cpp
index d642b74927..4101f85cd0 100644
--- a/Core/Code/Testing/mitkExceptionTest.cpp
+++ b/Core/Code/Testing/mitkExceptionTest.cpp
@@ -1,223 +1,222 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkExceptionMacro.h"
#include "mitkTestingMacros.h"
#include <itkObject.h>
#include <itkObjectFactory.h>
#include <mitkCommon.h>
class SpecializedTestException : public mitk::Exception
{
public:
mitkExceptionClassMacro(SpecializedTestException,mitk::Exception);
};
class ExceptionTestClass : public itk::Object
{
public:
mitkClassMacro( ExceptionTestClass , itk::Object );
itkNewMacro(Self);
void throwExceptionManually()
//this method is ONLY to test the constructor and no code example
//normally exceptions should only be thrown by using the exception macro!
{
throw mitk::Exception("test.cpp",155,"","");
}
void throwSpecializedExceptionManually()
//this method is ONLY to test the constructor and no code example
//normally exceptions should only be thrown by using the exception macro!
{
throw SpecializedTestException("test.cpp",155,"","");
}
void throwExceptionManually(std::string message1, std::string message2)
//this method is ONLY to test methods of mitk::Exception and no code example
//normally exceptions should only be thrown by using the exception macro!
{
throw mitk::Exception("testfile.cpp",155,message1.c_str(),"") << message2;
}
void throwExceptionWithThrowMacro()
{
mitkThrow()<<"TEST EXCEPION THROWING WITH mitkThrow()";
}
void throwExceptionWithThrowMacro(std::string message)
{
mitkThrow()<<message.c_str();
}
void throwSpecializedExceptionWithThrowMacro(std::string message)
{
mitkThrowException(mitk::Exception)<<message;
}
void throwSpecializedExceptionWithThrowMacro2(std::string message)
{
mitkThrowException(SpecializedTestException)<<message;
}
static void TestExceptionConstructor()
{
bool exceptionThrown = false;
ExceptionTestClass::Pointer myExceptionTestObject = ExceptionTestClass::New();
try
{
myExceptionTestObject->throwExceptionManually();
}
catch(mitk::Exception)
{
exceptionThrown = true;
}
MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing constructor of mitkException");
exceptionThrown = false;
try
{
myExceptionTestObject->throwSpecializedExceptionManually();
}
catch(SpecializedTestException)
{
exceptionThrown = true;
}
MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing constructor specialized exception (deriving from mitkException)");
}
static void TestExceptionMessageStream()
{
//##### this method is ONLY to test the streaming operators of the exceptions and
//##### NO code example. Please do not instantiate exceptions by yourself in normal code!
//##### Normally exceptions should only be thrown by using the exception macro!
mitk::Exception myException = mitk::Exception("testfile.cpp",111,"testmessage");
myException << " and additional stream";
MITK_TEST_CONDITION_REQUIRED(myException.GetDescription() == std::string("testmessage and additional stream"),"Testing mitkException message stream (adding std::string)");
myException.SetDescription("testmessage2");
myException << ' ' << 'a' << 'n' << 'd' << ' ' << 'c' << 'h' << 'a' << 'r' << 's';
MITK_TEST_CONDITION_REQUIRED(myException.GetDescription() == std::string("testmessage2 and chars"),"Testing mitkException message stream (adding single chars)");
myException.SetDescription("testmessage3");
myException << myException; //adding the object itself makes no sense but should work
MITK_TEST_CONDITION_REQUIRED(myException.GetDescription() != std::string(""),"Testing mitkException message stream (adding object)");
SpecializedTestException mySpecializedException = SpecializedTestException("testfile.cpp",111,"testmessage","test");
mySpecializedException << " and additional stream";
MITK_TEST_CONDITION_REQUIRED(mySpecializedException.GetDescription() == std::string("testmessage and additional stream"),"Testing specialized exception message stream (adding std::string)");
}
static void TestExceptionMessageStreamThrowing()
{
bool exceptionThrown = false;
ExceptionTestClass::Pointer myExceptionTestObject = ExceptionTestClass::New();
std::string thrownMessage = "";
try
{
myExceptionTestObject->throwExceptionManually("message1"," and message2");
}
catch(mitk::Exception e)
{
thrownMessage = e.GetDescription();
exceptionThrown = true;
}
MITK_TEST_CONDITION_REQUIRED(exceptionThrown && (thrownMessage == std::string("message1 and message2")),"Testing throwing and streaming of mitk::Exception together.")
}
static void TestMitkThrowMacro()
{
bool exceptionThrown = false;
ExceptionTestClass::Pointer myExceptionTestObject = ExceptionTestClass::New();
//case 1: test throwing
try
{
myExceptionTestObject->throwExceptionWithThrowMacro();
}
catch(mitk::Exception)
{
exceptionThrown = true;
}
MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing mitkThrow()");
//case 2: test message text
exceptionThrown = false;
std::string messageText = "";
try
{
myExceptionTestObject->throwExceptionWithThrowMacro("test123");
}
catch(mitk::Exception e)
{
exceptionThrown = true;
messageText = e.GetDescription();
}
MITK_TEST_CONDITION_REQUIRED((exceptionThrown && (messageText=="test123")),"Testing message test of mitkThrow()");
//case 3: specialized exception / command mitkThrow(mitk::Exception)
exceptionThrown = false;
messageText = "";
try
{
myExceptionTestObject->throwSpecializedExceptionWithThrowMacro("test123");
}
catch(mitk::Exception e)
{
exceptionThrown = true;
messageText = e.GetDescription();
}
MITK_TEST_CONDITION_REQUIRED(exceptionThrown && messageText=="test123","Testing special exception with mitkThrow(mitk::Exception)");
//case 4: specialized exception / command mitkThrow(mitk::SpecializedException)
exceptionThrown = false;
messageText = "";
try
{
myExceptionTestObject->throwSpecializedExceptionWithThrowMacro2("test123");
}
catch(SpecializedTestException e)
{
exceptionThrown = true;
messageText = e.GetDescription();
}
MITK_TEST_CONDITION_REQUIRED(exceptionThrown && messageText=="test123","Testing special exception with mitkThrow(mitk::SpecializedException)");
}
};
int mitkExceptionTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("MITKException");
ExceptionTestClass::TestExceptionConstructor();
ExceptionTestClass::TestExceptionMessageStream();
ExceptionTestClass::TestExceptionMessageStreamThrowing();
ExceptionTestClass::TestMitkThrowMacro();
MITK_TEST_END();
}
\ No newline at end of file
diff --git a/Core/Code/Testing/mitkFocusManagerTest.cpp b/Core/Code/Testing/mitkFocusManagerTest.cpp
index 1b81a366bd..56b9412be1 100644
--- a/Core/Code/Testing/mitkFocusManagerTest.cpp
+++ b/Core/Code/Testing/mitkFocusManagerTest.cpp
@@ -1,92 +1,91 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-13 14:52:01 +0200 (Mi, 13 Mai 2009) $
-Version: $Revision: 17230 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkFocusManager.h"
#include "mitkTestingMacros.h"
#include "mitkVtkPropRenderer.h"
#include "mitkGlobalInteraction.h"
int mitkFocusManagerTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("FocusManager");
// Global interaction must(!) be initialized if used
mitk::GlobalInteraction::GetInstance()->Initialize("global");
mitk::RenderingManager::Pointer rm = mitk::RenderingManager::GetInstance();
//building up necessary objects
vtkRenderWindow* renderWindow = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer element1 = mitk::VtkPropRenderer::New( "renderer1", renderWindow, rm );
mitk::VtkPropRenderer::Pointer element2 = mitk::VtkPropRenderer::New( "renderer2", renderWindow, rm );
mitk::VtkPropRenderer::Pointer element3 = mitk::VtkPropRenderer::New( "renderer3", renderWindow, rm );
//the FocusManager itself
mitk::FocusManager::Pointer focusManager = mitk::FocusManager::New();
//testing
MITK_TEST_CONDITION_REQUIRED(focusManager.IsNotNull(), "Testing Instatiation");
MITK_TEST_CONDITION_REQUIRED(element1.IsNotNull(), "Testing Instatiation of an element");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element is focused on");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing of an element");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == NULL, "Testing focused on an empty list");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element; Elements in list: 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element2), "Testing addition of a second element; Elements in list: 1 2");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element3), "Testing addition of a third element; Elements in list: 1 2 3");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element1), "Testing setting focused to element 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "focus on element 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element2), "Testing setting focused to element 2");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "focus on element 2");
MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element3), "Testing setting focused to element 3");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element3, "focus on element 3");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing first element; Elements in list: 2 3");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is the one behind the deleted one: 2");
MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element again; Elements in list: 2 3 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element3), "Testing removing element 3; Elements in list: 2 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if focused element is the one behind the deleted one: 1");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing last element 1; Elements in list: 2 ");
MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is 2");
MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing same element");
MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element2), "Testing removing last element in list (2)");
MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element3), "Testing removing from empty list ");
MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element2), "Testing removing from empty list with different object");
MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing from empty list with different object again");
focusManager = NULL;
//TODO: test IsLast() IsFirst() GetFirst() GetLast() GoToNext() GetIter() SetLoop(bool loop)
//Delete renderWindo correctly
renderWindow->Delete();
MITK_TEST_END();
}
\ No newline at end of file
diff --git a/Core/Code/Testing/mitkGenericPropertyTest.cpp b/Core/Code/Testing/mitkGenericPropertyTest.cpp
index b2829eb5c3..71c7904ab6 100644
--- a/Core/Code/Testing/mitkGenericPropertyTest.cpp
+++ b/Core/Code/Testing/mitkGenericPropertyTest.cpp
@@ -1,110 +1,109 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include "mitkGenericProperty.h"
#include "mitkStringProperty.h"
#include "mitkProperties.h"
#include "mitkVector.h"
#include <iostream>
#include <string>
// call with testValue1 != testValue2
template <typename T>
int TestGenericPropertyForDataType(typename T::ValueType testValue1, typename T::ValueType testValue2, std::string testValue1AsString, std::string testValue2AsString, std::string type)
{
std::cout << "Testing mitk::GenericProperty<" << type << ">(" << testValue1AsString << ", " << testValue2AsString << ") \n";
typename T::Pointer prop(T::New());
typename T::Pointer prop2(T::New(testValue1));
typename T::Pointer prop3(T::New(testValue2));
unsigned long tBefore = prop->GetMTime();
prop->SetValue(testValue1);
unsigned long tAfter = prop->GetMTime();
prop->SetValue(testValue1);
unsigned long tAfterAll = prop->GetMTime();
MITK_TEST_CONDITION_REQUIRED(prop->GetValue() == testValue1 && prop->GetValueAsString() == testValue1AsString,"Testing SetValue")
MITK_TEST_CONDITION_REQUIRED((*prop == *prop2),"Testing equality operator (operator==)");
prop->SetValue(testValue2);
unsigned long tAfterEverything = prop->GetMTime();
std::cout << " Testing MTime correctness when changing property value: ";
if (tBefore >= tAfter || tAfterAll != tAfter || tAfterEverything <= tAfterAll) {
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
prop->SetValue(testValue1);
std::cout << " Testing Assignment: ";
prop->AssignProperty(*prop3);
if ( (! (*prop == *prop3)) || (*prop == *prop2) ) {
std::cout << " [FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << std::endl;
return EXIT_SUCCESS;
}
int mitkGenericPropertyTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN(GenericPropertyTest)
// testing for some different data types
TestGenericPropertyForDataType<mitk::IntProperty>(1, 2, "1", "2", "int");
TestGenericPropertyForDataType<mitk::BoolProperty>(true, false, "1", "0", "bool");
TestGenericPropertyForDataType<mitk::FloatProperty>(1.0, -1.0, "1", "-1", "float");
TestGenericPropertyForDataType<mitk::DoubleProperty>(1.0, -1.0, "1", "-1", "double");
TestGenericPropertyForDataType<mitk::StringProperty>(std::string("eins"), std::string("zwei"), std::string("eins"), std::string("zwei"), "std::string");
{
mitk::Point3D p1; p1[0] = 2.0; p1[1] = 3.0; p1[2] = 4.0;
mitk::Point3D p2; p2[0] =-1.0; p2[1] = 2.0; p2[2] = 3.0;
TestGenericPropertyForDataType<mitk::Point3dProperty>( p1, p2, "[2, 3, 4]", "[-1, 2, 3]", "mitk::Point3D");
}
{
mitk::Point4D p1; p1[0] = 2.0; p1[1] = 3.0; p1[2] = 4.0; p1[3] =-2.0;
mitk::Point4D p2; p2[0] =-1.0; p2[1] = 2.0; p2[2] = 3.0; p2[3] = 5.0;
TestGenericPropertyForDataType<mitk::Point4dProperty>( p1, p2, "[2, 3, 4, -2]", "[-1, 2, 3, 5]", "mitk::Point4D");
}
/* THIS won't compile because of the interface of XMLWriter... that should be reworked perhaps
{
mitk::Vector2D p1; p1[0] = 2.0; p1[1] = 3.0;
mitk::Vector2D p2; p2[0] =-1.0; p2[1] = 2.0;
TestGenericPropertyForDataType<mitk::Vector2D>( p1, p2, "[2, 3]", "[-1, 2]", "mitk::Vector2D");
}
*/
{
mitk::Vector3D p1; p1[0] = 2.0; p1[1] = 3.0; p1[2] = 4.0;
mitk::Vector3D p2; p2[0] =-1.0; p2[1] = 2.0; p2[2] = 3.0;
TestGenericPropertyForDataType<mitk::Vector3DProperty>( p1, p2, "[2, 3, 4]", "[-1, 2, 3]", "mitk::Vector3D");
}
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkGeometry3DTest.cpp b/Core/Code/Testing/mitkGeometry3DTest.cpp
index 85b686a818..cd1b3c9d82 100644
--- a/Core/Code/Testing/mitkGeometry3DTest.cpp
+++ b/Core/Code/Testing/mitkGeometry3DTest.cpp
@@ -1,550 +1,549 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGeometry3D.h"
#include <vnl/vnl_quaternion.h>
#include <vnl/vnl_quaternion.txx>
#include "mitkRotationOperation.h"
#include "mitkInteractionConst.h"
#include <mitkMatrixConvert.h>
#include <mitkImageCast.h>
#include "mitkTestingMacros.h"
#include <fstream>
#include <mitkVector.h>
bool testGetAxisVectorVariants(mitk::Geometry3D* geometry)
{
int direction;
for(direction=0; direction<3; ++direction)
{
mitk::Vector3D frontToBack;
switch(direction)
{
case 0: frontToBack = geometry->GetCornerPoint(false, false, false)-geometry->GetCornerPoint(true , false, false); break; //7-3
case 1: frontToBack = geometry->GetCornerPoint(false, false, false)-geometry->GetCornerPoint(false, true , false); break; //7-5
case 2: frontToBack = geometry->GetCornerPoint(false, false, false)-geometry->GetCornerPoint(false , false, true); break; //7-2
}
std::cout << "Testing GetAxisVector(int) vs GetAxisVector(bool, bool, bool): ";
if(mitk::Equal(geometry->GetAxisVector(direction), frontToBack) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return false;
}
std::cout<<"[PASSED]"<<std::endl;
}
return true;
}
bool testGetAxisVectorExtent(mitk::Geometry3D* geometry)
{
int direction;
for(direction=0; direction<3; ++direction)
{
if(mitk::Equal(geometry->GetAxisVector(direction).GetNorm(), geometry->GetExtentInMM(direction)) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return false;
}
std::cout<<"[PASSED]"<<std::endl;
}
return true;
}
// a part of the test requires axis-parallel coordinates
int testIndexAndWorldConsistency(mitk::Geometry3D* geometry3d)
{
MITK_TEST_OUTPUT( << "Testing consistency of index and world coordinate systems: ");
mitk::Point3D origin = geometry3d->GetOrigin();
mitk::Point3D dummy;
MITK_TEST_OUTPUT( << " Testing index->world->index conversion consistency");
geometry3d->WorldToIndex(origin, dummy);
geometry3d->IndexToWorld(dummy, dummy);
MITK_TEST_CONDITION_REQUIRED(dummy == origin, "");
MITK_TEST_OUTPUT( << " Testing WorldToIndex(origin, mitk::Point3D)==(0,0,0)");
mitk::Point3D globalOrigin;
mitk::FillVector3D(globalOrigin, 0,0,0);
mitk::Point3D originContinuousIndex;
geometry3d->WorldToIndex(origin, originContinuousIndex);
MITK_TEST_CONDITION_REQUIRED(originContinuousIndex == globalOrigin, "");
MITK_TEST_OUTPUT( << " Testing WorldToIndex(origin, itk::Index)==(0,0,0)");
itk::Index<3> itkindex;
geometry3d->WorldToIndex(origin, itkindex);
itk::Index<3> globalOriginIndex;
mitk::vtk2itk(globalOrigin, globalOriginIndex);
MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
MITK_TEST_OUTPUT( << " Testing WorldToIndex(origin-0.5*spacing, itk::Index)==(0,0,0)");
mitk::Vector3D halfSpacingStep = geometry3d->GetSpacing()*0.5;
mitk::Matrix3D rotation;
mitk::Point3D originOffCenter = origin-halfSpacingStep;
geometry3d->WorldToIndex(originOffCenter, itkindex);
MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
MITK_TEST_OUTPUT( << " Testing WorldToIndex(origin+0.5*spacing-eps, itk::Index)==(0,0,0)");
originOffCenter = origin+halfSpacingStep;
originOffCenter -= 0.0001;
geometry3d->WorldToIndex( originOffCenter, itkindex);
MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
MITK_TEST_OUTPUT( << " Testing WorldToIndex(origin+0.5*spacing, itk::Index)==(1,1,1)");
originOffCenter = origin+halfSpacingStep;
itk::Index<3> global111;
mitk::FillVector3D(global111, 1,1,1);
geometry3d->WorldToIndex( originOffCenter, itkindex);
MITK_TEST_CONDITION_REQUIRED(itkindex == global111, "");
MITK_TEST_OUTPUT( << " Testing WorldToIndex(GetCenter())==BoundingBox.GetCenter: ");
mitk::Point3D center = geometry3d->GetCenter();
mitk::Point3D centerContIndex;
geometry3d->WorldToIndex(center, centerContIndex);
mitk::BoundingBox::ConstPointer boundingBox = geometry3d->GetBoundingBox();
mitk::BoundingBox::PointType centerBounds = boundingBox->GetCenter();
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(centerContIndex,centerBounds), "");
MITK_TEST_OUTPUT( << " Testing GetCenter()==IndexToWorld(BoundingBox.GetCenter): ");
center = geometry3d->GetCenter();
mitk::Point3D centerBoundsInWorldCoords;
geometry3d->IndexToWorld(centerBounds, centerBoundsInWorldCoords);
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(center,centerBoundsInWorldCoords), "");
return EXIT_SUCCESS;
}
int testIndexAndWorldConsistencyForVectors(mitk::Geometry3D* geometry3d)
{
MITK_TEST_OUTPUT( << "Testing consistency of index and world coordinate systems for vectors: ");
mitk::Vector3D xAxisMM = geometry3d->GetAxisVector(0);
mitk::Vector3D xAxisContinuousIndex;
mitk::Vector3D xAxisContinuousIndexDeprecated;
mitk::Point3D p, pIndex, origin;
origin = geometry3d->GetOrigin();
p[0] = xAxisMM[0];
p[1] = xAxisMM[1];
p[2] = xAxisMM[2];
geometry3d->WorldToIndex(p,pIndex);
geometry3d->WorldToIndex(xAxisMM, xAxisContinuousIndexDeprecated);
geometry3d->WorldToIndex(xAxisMM,xAxisContinuousIndex);
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == pIndex[0],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == pIndex[1],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == pIndex[2],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == xAxisContinuousIndexDeprecated[0],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == xAxisContinuousIndexDeprecated[1],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == xAxisContinuousIndexDeprecated[2],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[0] == pIndex[0],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[1] == pIndex[1],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[2] == pIndex[2],"");
geometry3d->IndexToWorld(xAxisContinuousIndex,xAxisContinuousIndex);
geometry3d->IndexToWorld(xAxisContinuousIndexDeprecated,xAxisContinuousIndexDeprecated);
geometry3d->IndexToWorld(pIndex,p);
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex == xAxisMM,"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[0] == p[0],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[1] == p[1],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndex[2] == p[2],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated == xAxisMM,"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[0] == p[0],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[1] == p[1],"");
MITK_TEST_CONDITION_REQUIRED(xAxisContinuousIndexDeprecated[2] == p[2],"");
return EXIT_SUCCESS;
}
#include <itkImage.h>
int testItkImageIsCenterBased()
{
MITK_TEST_OUTPUT(<< "Testing whether itk::Image coordinates are center-based.");
typedef itk::Image<int,3> ItkIntImage3D;
ItkIntImage3D::Pointer itkintimage = ItkIntImage3D::New();
ItkIntImage3D::SizeType size;
size.Fill(10);
mitk::Point3D origin;
mitk::FillVector3D(origin, 2,3,7);
itkintimage->Initialize();
itkintimage->SetRegions(size);
itkintimage->SetOrigin(origin);
std::cout<<"[PASSED]"<<std::endl;
MITK_TEST_OUTPUT( << " Testing itk::Image::TransformPhysicalPointToContinuousIndex(origin)==(0,0,0)");
mitk::Point3D globalOrigin;
mitk::FillVector3D(globalOrigin, 0,0,0);
itk::ContinuousIndex<mitk::ScalarType, 3> originContinuousIndex;
itkintimage->TransformPhysicalPointToContinuousIndex(origin, originContinuousIndex);
MITK_TEST_CONDITION_REQUIRED(originContinuousIndex == globalOrigin, "");
MITK_TEST_OUTPUT( << " Testing itk::Image::TransformPhysicalPointToIndex(origin)==(0,0,0)");
itk::Index<3> itkindex;
itkintimage->TransformPhysicalPointToIndex(origin, itkindex);
itk::Index<3> globalOriginIndex;
mitk::vtk2itk(globalOrigin, globalOriginIndex);
MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
MITK_TEST_OUTPUT( << " Testing itk::Image::TransformPhysicalPointToIndex(origin-0.5*spacing)==(0,0,0)");
mitk::Vector3D halfSpacingStep = itkintimage->GetSpacing()*0.5;
mitk::Matrix3D rotation;
mitk::Point3D originOffCenter = origin-halfSpacingStep;
itkintimage->TransformPhysicalPointToIndex(originOffCenter, itkindex);
MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
MITK_TEST_OUTPUT( << " Testing itk::Image::TransformPhysicalPointToIndex(origin+0.5*spacing-eps, itk::Index)==(0,0,0)");
originOffCenter = origin+halfSpacingStep;
originOffCenter -= 0.0001;
itkintimage->TransformPhysicalPointToIndex( originOffCenter, itkindex);
MITK_TEST_CONDITION_REQUIRED(itkindex == globalOriginIndex, "");
MITK_TEST_OUTPUT( << " Testing itk::Image::TransformPhysicalPointToIndex(origin+0.5*spacing, itk::Index)==(1,1,1)");
originOffCenter = origin+halfSpacingStep;
itk::Index<3> global111;
mitk::FillVector3D(global111, 1,1,1);
itkintimage->TransformPhysicalPointToIndex( originOffCenter, itkindex);
MITK_TEST_CONDITION_REQUIRED(itkindex == global111, "");
MITK_TEST_OUTPUT( << "=> Yes, itk::Image coordinates are center-based.");
return EXIT_SUCCESS;
}
int testGeometry3D(bool imageGeometry)
{
// Build up a new image Geometry
mitk::Geometry3D::Pointer geometry3d = mitk::Geometry3D::New();
float bounds[ ] = {-10.0, 17.0, -12.0, 188.0, 13.0, 211.0};
MITK_TEST_OUTPUT( << "Initializing");
geometry3d->Initialize();
MITK_TEST_OUTPUT(<< "Setting ImageGeometry to " << imageGeometry);
geometry3d->SetImageGeometry(imageGeometry);
MITK_TEST_OUTPUT(<< "Setting bounds by SetFloatBounds(): " << bounds);
geometry3d->SetFloatBounds(bounds);
MITK_TEST_OUTPUT( << "Testing AxisVectors");
if(testGetAxisVectorVariants(geometry3d) == false)
return EXIT_FAILURE;
if(testGetAxisVectorExtent(geometry3d) == false)
return EXIT_FAILURE;
MITK_TEST_OUTPUT( << "Creating an AffineTransform3D transform");
mitk::AffineTransform3D::MatrixType matrix;
matrix.SetIdentity();
matrix(1,1) = 2;
mitk::AffineTransform3D::Pointer transform;
transform = mitk::AffineTransform3D::New();
transform->SetMatrix(matrix);
MITK_TEST_OUTPUT( << "Testing a SetIndexToWorldTransform");
geometry3d->SetIndexToWorldTransform(transform);
MITK_TEST_OUTPUT( << "Testing correctness of value returned by GetSpacing");
const mitk::Vector3D& spacing1 = geometry3d->GetSpacing();
mitk::Vector3D expectedSpacing;
expectedSpacing.Fill(1.0);
expectedSpacing[1] = 2;
if( mitk::Equal(spacing1, expectedSpacing) == false )
{
MITK_TEST_OUTPUT( << " [FAILED]");
return EXIT_FAILURE;
}
MITK_TEST_OUTPUT( << "Testing a Compose(transform)");
geometry3d->Compose(transform);
MITK_TEST_OUTPUT( << "Testing correctness of value returned by GetSpacing");
const mitk::Vector3D& spacing2 = geometry3d->GetSpacing();
expectedSpacing[1] = 4;
if( mitk::Equal(spacing2, expectedSpacing) == false )
{
MITK_TEST_OUTPUT( << " [FAILED]");
return EXIT_FAILURE;
}
MITK_TEST_OUTPUT( << "Testing correctness of SetSpacing");
mitk::Vector3D newspacing;
mitk::FillVector3D(newspacing, 1.5, 2.5, 3.5);
geometry3d->SetSpacing(newspacing);
const mitk::Vector3D& spacing3 = geometry3d->GetSpacing();
if( mitk::Equal(spacing3, newspacing) == false )
{
MITK_TEST_OUTPUT( << " [FAILED]");
return EXIT_FAILURE;
}
// Seperate Test function for Index and World consistency
testIndexAndWorldConsistency(geometry3d);
testIndexAndWorldConsistencyForVectors(geometry3d);
MITK_TEST_OUTPUT( << "Testing a rotation of the geometry");
double angle = 35.0;
mitk::Vector3D rotationVector; mitk::FillVector3D( rotationVector, 1, 0, 0 );
mitk::Point3D center = geometry3d->GetCenter();
mitk::RotationOperation* op = new mitk::RotationOperation( mitk::OpROTATE, center, rotationVector, angle );
geometry3d->ExecuteOperation(op);
MITK_TEST_OUTPUT( << "Testing mitk::GetRotation() and success of rotation");
mitk::Matrix3D rotation;
mitk::GetRotation(geometry3d, rotation);
mitk::Vector3D voxelStep=rotation*newspacing;
mitk::Vector3D voxelStepIndex;
geometry3d->WorldToIndex(voxelStep, voxelStepIndex);
mitk::Vector3D expectedVoxelStepIndex;
expectedVoxelStepIndex.Fill(1);
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(voxelStepIndex,expectedVoxelStepIndex), "");
delete op;
std::cout<<"[PASSED]"<<std::endl;
MITK_TEST_OUTPUT( << "Testing that ImageGeometry is still " << imageGeometry);
MITK_TEST_CONDITION_REQUIRED(geometry3d->GetImageGeometry() == imageGeometry, "");
return EXIT_SUCCESS;
}
int testGeometryAfterCasting()
{
// Epsilon. Allowed difference for rotationvalue
float eps = 0.0001;
// Cast ITK and MITK images and see if geometry stays
typedef itk::Image<double,2> Image2DType;
typedef itk::Image<double,3> Image3DType;
// Create 3D ITK Image from Scratch, cast to 3D MITK image, compare Geometries
Image3DType::Pointer image3DItk = Image3DType::New();
Image3DType::RegionType myRegion;
Image3DType::SizeType mySize;
Image3DType::IndexType myIndex;
Image3DType::SpacingType mySpacing;
Image3DType::DirectionType myDirection, rotMatrixX, rotMatrixY, rotMatrixZ;
mySpacing[0] = 31;
mySpacing[1] = 0.1;
mySpacing[2] = 2.9;
myIndex[0] = -15;
myIndex[1] = 15;
myIndex[2] = 12.1;
mySize[0] = 10;
mySize[1] = 2;
mySize[2] = 555.5;
myRegion.SetSize( mySize);
myRegion.SetIndex( myIndex );
image3DItk->SetSpacing(mySpacing);
image3DItk->SetRegions( myRegion);
image3DItk->Allocate();
image3DItk->FillBuffer(0);
myDirection.SetIdentity();
rotMatrixX.SetIdentity();
rotMatrixY.SetIdentity();
rotMatrixZ.SetIdentity();
mitk::Image::Pointer mitkImage;
// direction [row] [coloum]
MITK_TEST_OUTPUT( << "Casting a rotated 3D ITK Image to a MITK Image and check if Geometry is still same" );
for (double rotX=0; rotX < (itk::Math::pi*2); rotX+=0.4 )
{
// Set Rotation X
rotMatrixX[1][1] = cos( rotX );
rotMatrixX[1][2] = -sin( rotX );
rotMatrixX[2][1] = sin( rotX );
rotMatrixX[2][2] = cos( rotX );
for (double rotY=0; rotY < (itk::Math::pi*2); rotY+=0.33 )
{
// Set Rotation Y
rotMatrixY[0][0] = cos( rotY );
rotMatrixY[0][2] = sin( rotY );
rotMatrixY[2][0] = -sin( rotY );
rotMatrixY[2][2] = cos( rotY );
for (double rotZ=0; rotZ < (itk::Math::pi*2); rotZ+=0.5 )
{
// Set Rotation Z
rotMatrixZ[0][0] = cos( rotZ );
rotMatrixZ[0][1] = -sin( rotZ );
rotMatrixZ[1][0] = sin( rotZ );
rotMatrixZ[1][1] = cos( rotZ );
// Multiply matrizes
myDirection = myDirection * rotMatrixX * rotMatrixY * rotMatrixZ;
image3DItk->SetDirection(myDirection);
mitk::CastToMitkImage(image3DItk, mitkImage);
const mitk::AffineTransform3D::MatrixType& matrix = mitkImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix();
for (int row=0; row<3; row++)
{
for (int col=0; col<3; col++)
{
double mitkValue = matrix[row][col] / mitkImage->GetGeometry()->GetSpacing()[col];
double itkValue = myDirection[row][col];
double diff = mitkValue - itkValue;
// if you decrease this value, you can see that there might be QUITE high inaccuracy!!!
if (diff > eps) // need to check, how exact it SHOULD be .. since it is NOT EXACT!
{
std::cout << "Had a difference of : " << diff;
std::cout << "Error: Casting altered Geometry!";
std::cout << "ITK Matrix:\n" << myDirection;
std::cout << "Mitk Matrix (With Spacing):\n" << matrix;
std::cout << "Mitk Spacing: " << mitkImage->GetGeometry()->GetSpacing();
MITK_TEST_CONDITION_REQUIRED(false == true, "");
return false;
}
}
}
}
}
}
// Create 2D ITK Image from Scratch, cast to 2D MITK image, compare Geometries
Image2DType::Pointer image2DItk = Image2DType::New();
Image2DType::RegionType myRegion2D;
Image2DType::SizeType mySize2D;
Image2DType::IndexType myIndex2D;
Image2DType::SpacingType mySpacing2D;
Image2DType::DirectionType myDirection2D, rotMatrix;
mySpacing2D[0] = 31;
mySpacing2D[1] = 0.1;
myIndex2D[0] = -15;
myIndex2D[1] = 15;
mySize2D[0] = 10;
mySize2D[1] = 2;
myRegion2D.SetSize( mySize2D);
myRegion2D.SetIndex( myIndex2D );
image2DItk->SetSpacing(mySpacing2D);
image2DItk->SetRegions( myRegion2D);
image2DItk->Allocate();
image2DItk->FillBuffer(0);
myDirection2D.SetIdentity();
rotMatrix.SetIdentity();
// direction [row] [coloum]
MITK_TEST_OUTPUT( << "Casting a rotated 2D ITK Image to a MITK Image and check if Geometry is still same" );
for (double rotTheta=0; rotTheta < (itk::Math::pi*2); rotTheta+=0.1 )
{
// Set Rotation
rotMatrix[0][0] = cos(rotTheta);
rotMatrix[0][1] = -sin(rotTheta);
rotMatrix[1][0] = sin(rotTheta);
rotMatrix[1][1] = cos(rotTheta);
// Multiply matrizes
myDirection2D = myDirection2D * rotMatrix;
image2DItk->SetDirection(myDirection2D);
mitk::CastToMitkImage(image2DItk, mitkImage);
const mitk::AffineTransform3D::MatrixType& matrix = mitkImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix();
// Compare MITK and ITK matrix
for (int row=0; row<3; row++)
{
for (int col=0; col<3; col++)
{
double mitkValue = matrix[row][col] / mitkImage->GetGeometry()->GetSpacing()[col];
if ((row == 2) && (col == row))
{
if (mitkValue != 1)
{
MITK_TEST_OUTPUT(<< "After casting a 2D ITK to 3D MITK images, MITK matrix values for 0|2, 1|2, 2|0, 2|1 MUST be 0 and value for 2|2 must be 1");
return false;
}
}
else if ((row == 2) || (col == 2))
{
if (mitkValue != 0)
{
MITK_TEST_OUTPUT(<< "After casting a 2D ITK to 3D MITK images, MITK matrix values for 0|2, 1|2, 2|0, 2|1 MUST be 0 and value for 2|2 must be 1");
return false;
}
}
else
{
double itkValue = myDirection2D[row][col];
double diff = mitkValue - itkValue;
// if you decrease this value, you can see that there might be QUITE high inaccuracy!!!
if (diff > eps) // need to check, how exact it SHOULD be .. since it is NOT EXACT!
{
std::cout << "Had a difference of : " << diff;
std::cout << "Error: Casting altered Geometry!";
std::cout << "ITK Matrix:\n" << myDirection2D;
std::cout << "Mitk Matrix (With Spacing):\n" << matrix;
std::cout << "Mitk Spacing: " << mitkImage->GetGeometry()->GetSpacing();
MITK_TEST_CONDITION_REQUIRED(false == true, "");
return false;
}
}
}
}
}
// THIS WAS TESTED:
// 2D ITK -> 2D MITK,
// 3D ITK -> 3D MITK,
// Still need to test: 2D MITK Image with ADDITIONAL INFORMATION IN MATRIX -> 2D ITK
// 1. Possibility: 3x3 MITK matrix can be converted without loss into 2x2 ITK matrix
// 2. Possibility: 3x3 MITK matrix can only be converted with loss into 2x2 ITK matrix
// .. before implementing this, we wait for further development in geometry classes (e.g. Geoemtry3D::SetRotation(..))
return EXIT_SUCCESS;
}
int mitkGeometry3DTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN(mitkGeometry3DTest);
int result;
MITK_TEST_CONDITION_REQUIRED( (result = testItkImageIsCenterBased()) == EXIT_SUCCESS, "");
MITK_TEST_OUTPUT(<< "Running main part of test with ImageGeometry = false");
MITK_TEST_CONDITION_REQUIRED( (result = testGeometry3D(false)) == EXIT_SUCCESS, "");
MITK_TEST_OUTPUT(<< "Running main part of test with ImageGeometry = true");
MITK_TEST_CONDITION_REQUIRED( (result = testGeometry3D(true)) == EXIT_SUCCESS, "");
MITK_TEST_OUTPUT(<< "Running test to see if Casting MITK to ITK and the other way around destroys geometry");
MITK_TEST_CONDITION_REQUIRED( (result = testGeometryAfterCasting()) == EXIT_SUCCESS, "");
MITK_TEST_END();
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkGeometryDataToSurfaceFilterTest.cpp b/Core/Code/Testing/mitkGeometryDataToSurfaceFilterTest.cpp
index 23ae92b2dd..9cfeccf569 100644
--- a/Core/Code/Testing/mitkGeometryDataToSurfaceFilterTest.cpp
+++ b/Core/Code/Testing/mitkGeometryDataToSurfaceFilterTest.cpp
@@ -1,254 +1,253 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkGeometry2DDataToSurfaceFilter.h"
#include "mitkSurface.h"
#include "mitkPlaneGeometry.h"
#include "mitkGeometry2DData.h"
#include "vtkPolyData.h"
#include <fstream>
template <typename TScalarType>
int testExpectedIndexBoundingBox(mitk::Geometry3D* geometry, TScalarType expectedIndexBounds[6])
{
mitk::BoundingBox* bb = const_cast<mitk::BoundingBox*>(geometry->GetBoundingBox());
mitk::BoundingBox::BoundsArrayType bounds = bb->GetBounds();
int i;
for(i=0;i<6;++i)
{
if( mitk::Equal(bounds[i], expectedIndexBounds[i]) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
}
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
template <typename TScalarType>
int testExpectedAxisParallelBoundingBox(mitk::Geometry3D* geometry, TScalarType expectedAxisParallelBounds[6])
{
mitk::BoundingBox::Pointer bb = geometry->CalculateBoundingBoxRelativeToTransform(NULL);
mitk::BoundingBox::BoundsArrayType bounds = bb->GetBounds();
int i;
for(i=0;i<6;++i)
{
if( mitk::Equal(bounds[i], expectedAxisParallelBounds[i]) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
}
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
int testSurfaceBoundingBoxConsistency(mitk::Surface* surface, bool expectIdentityTransform)
{
int result;
std::cout << " Testing surface contents: ";
if ((surface == NULL )
|| (surface->GetVtkPolyData() == NULL)
|| (surface->GetVtkPolyData()->GetNumberOfPoints() == 0 )) {
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
else {
std::cout<<"[PASSED]"<<std::endl;
}
vtkFloatingPointType bounds[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
vtkPolyData* polys = surface->GetVtkPolyData();
polys->ComputeBounds();
polys->GetBounds( bounds );
int i;
if(expectIdentityTransform == false)
{
mitk::Geometry2D::Pointer geometry = mitk::Geometry2D::New();
geometry->SetFloatBounds(bounds);
geometry->SetIndexToWorldTransform(surface->GetGeometry()->GetIndexToWorldTransform());
mitk::BoundingBox::BoundsArrayType bb = const_cast<mitk::BoundingBox*>(geometry->GetBoundingBox())->GetBounds();
for(i=0;i<6;++i)
bounds[i]=bb[i];
}
std::cout << " Testing GetBoundingBox() ";
if((result=testExpectedIndexBoundingBox(surface->GetGeometry(), bounds)) != EXIT_SUCCESS)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
int testGeometryDataToSurfaceFilter(mitk::Geometry2DDataToSurfaceFilter* geometryToSurfaceFilter, mitk::ScalarType expectedIndexBounds[6], mitk::ScalarType expectedAxisParallelBounds[6], bool expectIdentityTransform)
{
int result;
std::cout << "Testing SetRequestedRegionToLargestPossibleRegion(): ";
geometryToSurfaceFilter->GetOutput()->SetRequestedRegionToLargestPossibleRegion();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing UpdateOutputInformation(): ";
geometryToSurfaceFilter->UpdateOutputInformation();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing correctness of bounding-box after UpdateOutputInformation(): ";
if((result=testExpectedIndexBoundingBox(geometryToSurfaceFilter->GetOutput()->GetGeometry(), expectedIndexBounds)) != EXIT_SUCCESS) {
return result;
}
std::cout << "Testing correctness of axis-parallel bounding-box after UpdateOutputInformation(): ";
if((result=testExpectedAxisParallelBoundingBox(geometryToSurfaceFilter->GetOutput()->GetGeometry(), expectedAxisParallelBounds)) != EXIT_SUCCESS) {
return result;
}
std::cout << "Testing Update(): ";
geometryToSurfaceFilter->Update();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing correctness of bounding-box after Update(): ";
if((result=testExpectedIndexBoundingBox(geometryToSurfaceFilter->GetOutput()->GetGeometry(), expectedIndexBounds)) != EXIT_SUCCESS) {
return result;
}
std::cout << "Testing correctness of axis-parallel bounding-box after UpdateOutputInformation(): ";
if((result=testExpectedAxisParallelBoundingBox(geometryToSurfaceFilter->GetOutput()->GetGeometry(), expectedAxisParallelBounds)) != EXIT_SUCCESS) {
return result;
}
std::cout << "Testing bounding-box consistency: "<<std::endl;
if((result=testSurfaceBoundingBoxConsistency(geometryToSurfaceFilter->GetOutput(), expectIdentityTransform)) != EXIT_SUCCESS) {
std::cout<<"[FAILED]"<<std::endl;
return result;
}
else {
std::cout<<"[PASSED]"<<std::endl;
}
return EXIT_SUCCESS;
}
int mitkGeometryDataToSurfaceFilterTest(int /*argc*/, char* /*argv*/[])
{
int result;
std::cout << "Testing mitk::Geometry2DDataToSurfaceFilter: " << std::endl;
mitk::Geometry2DDataToSurfaceFilter::Pointer geometryToSurfaceFilter;
std::cout << "Testing Geometry2DDataToSurfaceFilter::New(): ";
geometryToSurfaceFilter = mitk::Geometry2DDataToSurfaceFilter::New();
if (geometryToSurfaceFilter.IsNull()) {
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
else {
std::cout<<"[PASSED]"<<std::endl;
}
mitk::Point3D origin;
mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New();
plane->InitializeStandardPlane(50, 100);
mitk::FillVector3D(origin, 1.0, 2.0, 3.0);
plane->SetOrigin(origin);
mitk::Geometry2DData::Pointer geometryData = mitk::Geometry2DData::New();
geometryData->SetGeometry2D(plane);
std::cout << "Testing SetInput(): ";
geometryToSurfaceFilter->SetInput(geometryData);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetInput(): ";
if (geometryToSurfaceFilter->GetInput() != geometryData ) {
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
else {
std::cout<<"[PASSED]"<<std::endl;
}
std::cout << "Testing default of Geometry2DDataToSurfaceFilter::m_PlaceByGeometry (expected is false): ";
if (geometryToSurfaceFilter->GetPlaceByGeometry() != false ) {
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
else {
std::cout<<"[PASSED]"<<std::endl;
}
// test with m_PlaceByGeometry==false
mitk::ScalarType expectedBoundsFinal[6] = {1.0, 51.0, 2.0, 102.0, 3.0, 3.0};
if((result=testGeometryDataToSurfaceFilter(geometryToSurfaceFilter, expectedBoundsFinal, expectedBoundsFinal, true)) != EXIT_SUCCESS) {
return result;
}
std::cout << "Testing Geometry2DDataToSurfaceFilter::SetPlaceByGeometry(true): ";
geometryToSurfaceFilter->SetPlaceByGeometry(true);
if (geometryToSurfaceFilter->GetPlaceByGeometry() != true ) {
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
else {
std::cout<<"[PASSED]"<<std::endl;
}
// test with m_PlaceByGeometry==true
mitk::ScalarType expectedIndexBounds[6] = {0.0, 50.0, 0.0, 100.0, 0.0, 0.0};
mitk::ScalarType expectedAxisParallelBounds[6] = {1.0, 51.0, 2.0, 102.0, 3.0, 3.0};
if((result=testGeometryDataToSurfaceFilter(geometryToSurfaceFilter, expectedIndexBounds, expectedAxisParallelBounds, true)) != EXIT_SUCCESS) {
return result;
}
// test with specified BoundingBox (m_PlaceByGeometry is irrelevant for this test)
mitk::BoundingBox::Pointer boundingBox = mitk::BoundingBox::New();
mitk::Point3D bbMin, bbMax;
mitk::FillVector3D( bbMin, 10.0, 10.0, -6.0 );
mitk::FillVector3D( bbMax, 40.0, 90.0, 6.0 );
mitk::BoundingBox::PointsContainer::Pointer pointsContainer = mitk::BoundingBox::PointsContainer::New();
pointsContainer->InsertElement( 0, bbMin );
pointsContainer->InsertElement( 1, bbMax );
boundingBox->SetPoints( pointsContainer );
boundingBox->ComputeBoundingBox();
geometryToSurfaceFilter->SetPlaceByGeometry( true );
geometryToSurfaceFilter->SetBoundingBox( boundingBox );
mitk::ScalarType expectedIndexBoundsWithBB[6] = {9.0, 39.0, 8.0, 88.0, 0.0, 0.0};
mitk::ScalarType expectedAxisParallelBoundsWithBB[6] = {10.0, 40.0, 10.0, 90.0, 3.0, 3.0};
if((result=testGeometryDataToSurfaceFilter(geometryToSurfaceFilter, expectedIndexBoundsWithBB, expectedAxisParallelBoundsWithBB, true)) != EXIT_SUCCESS) {
return result;
}
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkGlobalInteractionTest.cpp b/Core/Code/Testing/mitkGlobalInteractionTest.cpp
index 35a77865d3..dcbbd84c6c 100644
--- a/Core/Code/Testing/mitkGlobalInteractionTest.cpp
+++ b/Core/Code/Testing/mitkGlobalInteractionTest.cpp
@@ -1,123 +1,122 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkGlobalInteraction.h>
#include <mitkPointSetInteractor.h>
#include "mitkTestingMacros.h"
#include <fstream>
int mitkGlobalInteractionTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("GlobalInteraction")
//get static instance of globalInteraction
mitk::GlobalInteraction::Pointer globalInteraction = mitk::GlobalInteraction::GetInstance();
MITK_TEST_CONDITION_REQUIRED(globalInteraction.IsNotNull(),"testing singleton initialization: ")
MITK_TEST_CONDITION_REQUIRED(globalInteraction->IsInitialized() == false ,"testing initial initialization: not initialized")
// Initialize with default values
MITK_TEST_CONDITION_REQUIRED(globalInteraction->Initialize("global"),"testing to initialize: ")
//testing initialization
MITK_TEST_CONDITION_REQUIRED(globalInteraction->IsInitialized(),"testing initial initialization: initialized")
MITK_TEST_CONDITION_REQUIRED(globalInteraction->Initialize("global") == false ,"testing double initialization")
MITK_TEST_CONDITION_REQUIRED(globalInteraction->IsInitialized(),"still initialized: ")
MITK_TEST_CONDITION_REQUIRED(globalInteraction.IsNotNull() ,"Testing 'instantiation' of 'global' static GlobalInteraction")
//testing creating non singleton instance
mitk::GlobalInteraction::Pointer myGlobalInteraction = mitk::GlobalInteraction::New();
MITK_TEST_CONDITION_REQUIRED(myGlobalInteraction.IsNotNull(),"testing non singleton initialization: ")
MITK_TEST_CONDITION_REQUIRED(myGlobalInteraction->IsInitialized() == false ,"testing initial initialization of non singleton: not initialized")
MITK_TEST_CONDITION_REQUIRED(myGlobalInteraction->Initialize("global"),"testing to initialize non singleton: ")
MITK_TEST_CONDITION_REQUIRED(myGlobalInteraction->IsInitialized() ,"testing initialization of non singleton: initialized")
//testing if it really is a different instance than singleton
MITK_TEST_CONDITION_REQUIRED(myGlobalInteraction != globalInteraction ,"Testing whether new instance equals the global satic one (must not be!)")
//getting singleton over non singleton instance: bug or feature???
MITK_TEST_CONDITION_REQUIRED(myGlobalInteraction->GetInstance() == globalInteraction ,"Testing singleton from non singleton instance")
//destroy non singleton class
myGlobalInteraction = NULL;
//now test adding and removing of Interactors and Listeners
//create Interactors
mitk::PointSetInteractor::Pointer firstInteractor = mitk::PointSetInteractor::New("pointsetinteractor", NULL, 1);
mitk::PointSetInteractor::Pointer secondInteractor = mitk::PointSetInteractor::New("pointsetinteractor", NULL, 10);
globalInteraction->AddInteractor(firstInteractor);
MITK_TEST_CONDITION_REQUIRED(globalInteraction->InteractorRegistered(firstInteractor),"Add first interactor to globalInteraction and check if is is registered: ")
globalInteraction->AddInteractor(secondInteractor);
MITK_TEST_CONDITION_REQUIRED(globalInteraction->InteractorRegistered(secondInteractor),"Add second interactor to globalInteraction and check if is is registered: ")
//remove Interactor
MITK_TEST_CONDITION_REQUIRED(globalInteraction->RemoveInteractor(firstInteractor),"Remove the first Interactor: ")
MITK_TEST_CONDITION_REQUIRED(!globalInteraction->RemoveInteractor(firstInteractor),"Remove the first Interactor a second time: ")
//check if really removed
MITK_TEST_CONDITION_REQUIRED(!globalInteraction->InteractorRegistered(firstInteractor),"Check if the first is not registered: ")
//check if second still present
MITK_TEST_CONDITION_REQUIRED(globalInteraction->InteractorRegistered(secondInteractor),"Check if the second is still registered: ")
//remove the second too
MITK_TEST_CONDITION_REQUIRED(globalInteraction->RemoveInteractor(secondInteractor),"Remove the second Interactor: ")
MITK_TEST_CONDITION_REQUIRED(!globalInteraction->RemoveInteractor(secondInteractor),"Remove the second Interactor a second time: ")
MITK_TEST_CONDITION_REQUIRED(!globalInteraction->InteractorRegistered(secondInteractor),"Check if the second is not registered: ")
//------------------
//now check the same with Listener
std::cout << "Check the addition of a Listener the same way: ";
std::cout << "Add two interactors as listeners (usually you add statemachines, not interactors). Are they both registered?: ";
std::cout << "Add listener1 (ITK popup with warning should come up: ";
globalInteraction->AddListener(firstInteractor);
MITK_TEST_CONDITION_REQUIRED(globalInteraction->ListenerRegistered(firstInteractor),"registered listener1: ")
MITK_TEST_CONDITION_REQUIRED(!globalInteraction->ListenerRegistered(secondInteractor),"not yet registered listener2: ")
std::cout << "Add listener2: ";
globalInteraction->AddListener(secondInteractor);
MITK_TEST_CONDITION_REQUIRED(globalInteraction->ListenerRegistered(secondInteractor),"registered listener2: ")
MITK_TEST_CONDITION_REQUIRED(globalInteraction->ListenerRegistered(firstInteractor),"listener1 still registered: ")
//remove Listener
MITK_TEST_CONDITION_REQUIRED(globalInteraction->RemoveListener(secondInteractor),"Remove listener2: ")
MITK_TEST_CONDITION_REQUIRED(!globalInteraction->ListenerRegistered(secondInteractor),"listener2 not registered anymore: ")
MITK_TEST_CONDITION_REQUIRED(globalInteraction->ListenerRegistered(firstInteractor),"but listener1: ")
//remove first too
MITK_TEST_CONDITION_REQUIRED(globalInteraction->RemoveListener(firstInteractor),"Remove listener1: ")
MITK_TEST_CONDITION_REQUIRED(!globalInteraction->ListenerRegistered(firstInteractor),"listener1 not registered anymore: ")
MITK_TEST_CONDITION_REQUIRED(!globalInteraction->ListenerRegistered(secondInteractor),"listener2 also not registered: ")
//now add them as interactors again
std::cout << "Now add the two interactors as interactors again: ";
globalInteraction->AddInteractor(firstInteractor);
globalInteraction->AddInteractor(secondInteractor);
std::cout << "and free the instances!";
//releasing smartpointer of interactors; should be kept in GlobalInteraction
firstInteractor = NULL;
secondInteractor = NULL;
globalInteraction = NULL;
// always end with this!
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkITKThreadingTest.cpp b/Core/Code/Testing/mitkITKThreadingTest.cpp
index bcf4977be0..545c489e42 100644
--- a/Core/Code/Testing/mitkITKThreadingTest.cpp
+++ b/Core/Code/Testing/mitkITKThreadingTest.cpp
@@ -1,161 +1,160 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <itkMultiThreader.h>
#include <itkSemaphore.h>
#include <itkFastMutexLock.h>
/*
int main()
{
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
*/
// to pass some parameter to thread
class UserData
{
public:
int* intPointer;
itk::FastMutexLock* mutex;
itk::Semaphore* semaphore;
itk::Semaphore* mayIRun;
};
// this will be executed in a thread
ITK_THREAD_RETURN_TYPE ThreadedFunction(void* param)
{
std::cout<<"Getting thread info data... ";
itk::MultiThreader::ThreadInfoStruct* threadInfo = static_cast<itk::MultiThreader::ThreadInfoStruct*>(param);
if (!threadInfo)
{
std::cout<<"[FAILED]"<<std::endl;
exit(EXIT_FAILURE);
}
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"Getting user data from thread... ";
UserData* userData = static_cast<UserData*>(threadInfo->UserData);
if (!userData)
{
std::cout<<"[FAILED]"<<std::endl;
exit(EXIT_FAILURE);
}
std::cout<<"[PASSED]"<<std::endl;
// inc variable FOR main thread
std::cout<<"generate 10000 results";
for (int i = 1; i <= 10000; ++i)
{
userData->mutex->Lock();
*(userData->intPointer) += 1; // generate one "result"
userData->mutex->Unlock();
userData->semaphore->Up(); // signal "work done"
}
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"waiting for main thread's signal... "<<std::endl;;
userData->mayIRun->Down(); // wait for signal
std::cout<<"got main thread's signal... "<<std::endl;
// inc variable TOGETHER WITH main thread
for (int i = 1; i <= 10000; ++i)
{
userData->mutex->Lock();
*(userData->intPointer) += 1;
userData->mutex->Unlock();
}
userData->semaphore->Up(); // signal "job done"
return ITK_THREAD_RETURN_VALUE;
}
int mitkITKThreadingTest(int /*argc*/, char* /*argv*/[])
{
itk::MultiThreader::Pointer threader = itk::MultiThreader::New();
int localInt(0); // this will be modified by both threads
itk::Semaphore::Pointer m_ResultAvailable = itk::Semaphore::New();
m_ResultAvailable->Initialize(0); // no pieces left (thread has to create one)
itk::Semaphore::Pointer m_RunThreadRun = itk::Semaphore::New();
m_RunThreadRun->Initialize(0); // no pieces left (thread has to create one)
itk::FastMutexLock::Pointer m_Mutex = itk::FastMutexLock::New();
UserData userData;
userData.intPointer = &localInt;
userData.mutex = m_Mutex.GetPointer();
userData.semaphore = m_ResultAvailable.GetPointer();
userData.mayIRun = m_RunThreadRun.GetPointer();
itk::ThreadFunctionType pointer = &ThreadedFunction;
int thread_id = threader->SpawnThread( pointer, &userData );
// let thread generate 10 results
for (int i = 1; i <= 10000; ++i)
m_ResultAvailable->Down();
std::cout<<"signaling by semaphore thread->main ";
if (localInt == 10000)
std::cout<<"[PASSED]"<<std::endl;
else
{
std::cout<<"[FAILED] localInt == "<< localInt <<std::endl;
return EXIT_FAILURE;
}
// increase int simultaneously with thread (coordinated by mutex)
localInt = 0;
m_RunThreadRun->Up(); // let thread work again
for (int i = 1; i <= 10000; ++i)
{
m_Mutex->Lock();
++localInt;
m_Mutex->Unlock();
}
std::cout<<"waiting for thread's signal"<<std::endl;;
m_ResultAvailable->Down(); // wait for thread
std::cout<<"got thread's signal"<<std::endl;;
std::cout<<"sharing a mutex protected variable among threads";
if (localInt == 20000)
std::cout<<"[PASSED]"<<std::endl;
else
{
std::cout<<"[FAILED] localInt == "<< localInt <<std::endl;
return EXIT_FAILURE;
}
// terminating work thread
std::cout<<"waiting for idling thread ";
threader->TerminateThread( thread_id );
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"Whole test [PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkImageDataItemTest.cpp b/Core/Code/Testing/mitkImageDataItemTest.cpp
index a0d1fa7ec5..45b6bb31ee 100644
--- a/Core/Code/Testing/mitkImageDataItemTest.cpp
+++ b/Core/Code/Testing/mitkImageDataItemTest.cpp
@@ -1,34 +1,33 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkImageDataItem.h"
#include <fstream>
int mitkImageDataItemTest(int /*argc*/, char* /*argv*/[])
{
unsigned long *pixels = new unsigned long [100];
void * data = pixels;
std::cout << "Testing pseudo-type independent deleting: ";
delete [] (unsigned char*) data;
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkImageGeneratorTest.cpp b/Core/Code/Testing/mitkImageGeneratorTest.cpp
index 766687d687..115b299f9f 100644
--- a/Core/Code/Testing/mitkImageGeneratorTest.cpp
+++ b/Core/Code/Testing/mitkImageGeneratorTest.cpp
@@ -1,63 +1,62 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkTestingMacros.h>
#include "mitkImage.h"
#include "mitkImageStatisticsHolder.h"
#include "mitkImageGenerator.h"
int mitkImageGeneratorTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("ToFImageWriter");
//create some images with arbitrary parameters (corner cases)
mitk::Image::Pointer image2Da = mitk::ImageGenerator::GenerateRandomImage<float>(120, 205, 0, 0, 577, 23);
mitk::Image::Pointer image2Db = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(1, 1, 0, 0);
mitk::Image::Pointer image3Da = mitk::ImageGenerator::GenerateRandomImage<int>(512, 205, 1, 0);
mitk::Image::Pointer image3Db = mitk::ImageGenerator::GenerateRandomImage<double>(512, 532, 112, 0);
mitk::Image::Pointer image4Da = mitk::ImageGenerator::GenerateRandomImage<float>(120, 205, 78, 1);
mitk::Image::Pointer image4Db = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(550, 33, 78, 150);
MITK_TEST_CONDITION_REQUIRED(image2Da->GetDimension() == 2, "Testing if the dimension is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image2Db->GetDimension() == 2, "Testing if the dimension is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image3Da->GetDimension() == 2, "Testing if the dimension is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image3Db->GetDimension() == 3, "Testing if the dimension is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image4Da->GetDimension() == 3, "Testing if the dimension is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image4Db->GetDimension() == 4, "Testing if the dimension is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image2Da->GetDimension(0) == 120, "Testing if the dimensions are set correctly.");
MITK_TEST_CONDITION_REQUIRED(image2Db->GetDimension(1) == 1, "Testing if the dimensions are set correctly.");
MITK_TEST_CONDITION_REQUIRED(image3Da->GetDimension(2) == 1, "Testing if the dimensions are set correctly.");
MITK_TEST_CONDITION_REQUIRED(image3Db->GetDimension(2) == 112, "Testing if the dimensions are set correctly.");
MITK_TEST_CONDITION_REQUIRED(image4Da->GetDimension(3) == 1, "Testing if the dimensions are set correctly.");
MITK_TEST_CONDITION_REQUIRED(image4Db->GetDimension(3) == 150, "Testing if the dimensions are set correctly.");
MITK_TEST_CONDITION_REQUIRED(image2Da->GetPixelType() == typeid(float), "Testing if the data type is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image2Db->GetPixelType() == typeid(unsigned char), "Testing if the data type is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image3Da->GetPixelType() == typeid(int), "Testing if the data type is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image3Db->GetPixelType() == typeid(double), "Testing if the data type is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image4Da->GetPixelType() == typeid(float), "Testing if the data type is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image4Db->GetPixelType() == typeid(unsigned char), "Testing if the ddata type is set correctly.");
MITK_TEST_CONDITION_REQUIRED(image2Da->GetStatistics()->GetScalarValueMax() <= 577, "Testing if max value holds");
MITK_TEST_CONDITION_REQUIRED(image2Da->GetStatistics()->GetScalarValueMin() >= 23, "Testing if min value holds");
MITK_TEST_CONDITION_REQUIRED(image3Da->GetStatistics()->GetScalarValueMax() <= 1000, "Testing if max value holds");
MITK_TEST_CONDITION_REQUIRED(image3Da->GetStatistics()->GetScalarValueMin() >= 0, "Testing if min value holds");
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkImageMapper2DTest.cpp b/Core/Code/Testing/mitkImageMapper2DTest.cpp
index 669fea350b..2b82b227dc 100644
--- a/Core/Code/Testing/mitkImageMapper2DTest.cpp
+++ b/Core/Code/Testing/mitkImageMapper2DTest.cpp
@@ -1,203 +1,202 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkImage.h>
//#include <mitkRenderWindow.h>
#include <mitkImageMapperGL2D.h>
#include <mitkLevelWindow.h>
#include <mitkLevelWindowProperty.h>
#include <mitkVtkPropRenderer.h>
#include <mitkVolumeDataVtkMapper3D.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkTransferFunction.h>
#include <mitkNativeRenderWindowInteractor.h>
#include "mitkReferenceCountWatcher.h"
#include <fstream>
int mitkImageMapper2DTest(int /*argc*/, char* /*argv*/[])
{
//Create Image out of nowhere
mitk::Image::Pointer image;
mitk::PixelType pt(typeid(int));
unsigned int dim[]={100,100,20};
std::cout << "Creating image: ";
image=mitk::Image::New();
image->Initialize(pt, 3, dim);
int *p = (int*)image->GetData();
int size = dim[0]*dim[1]*dim[2];
int i;
for(i=0; i<size; ++i, ++p)
*p=i;
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating node: ";
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(image);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating DataStorage: ";
mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of tree: ";
mitk::ReferenceCountWatcher::Pointer dsWatcher = new mitk::ReferenceCountWatcher(ds, "DataStorage");
if(dsWatcher->GetReferenceCount() != 1)
{
std::cout << dsWatcher->GetReferenceCount()<<"!=1 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of node: ";
mitk::ReferenceCountWatcher::Pointer nodeWatcher = new mitk::ReferenceCountWatcher(node, "node");
if(nodeWatcher->GetReferenceCount()!=1)
{
std::cout<<nodeWatcher->GetReferenceCount()<<"!=1 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Adding node via DataStorage: ";
ds->Add(node);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Adding level-window property: ";
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( image );
levWinProp->SetLevelWindow( levelwindow );
node->GetPropertyList()->SetProperty( "levelwindow", levWinProp );
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating VtkPropRenderer: ";
vtkRenderWindow *renderWindow = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer propRenderer = mitk::VtkPropRenderer::New( "the renderer", renderWindow );
std::cout<<"[PASSED]"<<std::endl;
std::cout << "BaseRenderer::SetData(iterator): ";
propRenderer->SetDataStorage(ds);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of node: ";
if(nodeWatcher->GetReferenceCount()!=2)
{
std::cout<<nodeWatcher->GetReferenceCount()<<"!=2 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing if an mitk::ImageMapperGL2D was created: ";
if(dynamic_cast<mitk::ImageMapperGL2D*>(node->GetMapper(mitk::BaseRenderer::Standard2D))==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing if an mitk::VolumeDataVtkMapper3D was created: ";
if(dynamic_cast<mitk::VolumeDataVtkMapper3D*>(node->GetMapper(mitk::BaseRenderer::Standard3D))==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing if an mitk::TransferFunctionProperty was created: ";
mitk::TransferFunctionProperty::Pointer transferFctProperty;
if(node->GetProperty<mitk::TransferFunctionProperty>(transferFctProperty, "TransferFunction") == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing if an mitk::TransferFunctionProperty contains an mitk::TransferFunction: ";
mitk::TransferFunction::Pointer transferFct = transferFctProperty->GetValue();
if(transferFct.IsNull())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of mitk::TransferFunctionProperty: ";
mitk::ReferenceCountWatcher::Pointer transferFctPropertyWatcher = new mitk::ReferenceCountWatcher(transferFctProperty, "transferFctProperty");
transferFctProperty = NULL;
if(transferFctPropertyWatcher->GetReferenceCount()!=1)
{
std::cout<<transferFctPropertyWatcher->GetReferenceCount()<<"!=1 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of mitk::TransferFunctionProperty: ";
mitk::ReferenceCountWatcher::Pointer transferFctWatcher = new mitk::ReferenceCountWatcher(transferFct, "transferFct");
transferFct = NULL;
if(transferFctWatcher->GetReferenceCount()!=1)
{
std::cout<<transferFctWatcher->GetReferenceCount()<<"!=1 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Deleting renderwindow, node and tree: ";
renderWindow->Delete();
node = NULL;
ds = NULL;
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of tree: ";
if(dsWatcher->GetReferenceCount() != 0)
{
std::cout << ds->GetReferenceCount()<<"!=0 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of node: ";
if(nodeWatcher->GetReferenceCount()!=0)
{
std::cout<<nodeWatcher->GetReferenceCount()<<"!=0 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of mitk::TransferFunctionProperty: ";
if(transferFctPropertyWatcher->GetReferenceCount()!=0)
{
std::cout<<transferFctPropertyWatcher->GetReferenceCount()<<"!=0 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count of mitk::TransferFunctionProperty: ";
if(transferFctWatcher->GetReferenceCount()!=0)
{
std::cout<<transferFctWatcher->GetReferenceCount()<<"!=0 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkImageSliceSelectorTest.cpp b/Core/Code/Testing/mitkImageSliceSelectorTest.cpp
index abe1dfca30..49ad1bdad0 100644
--- a/Core/Code/Testing/mitkImageSliceSelectorTest.cpp
+++ b/Core/Code/Testing/mitkImageSliceSelectorTest.cpp
@@ -1,222 +1,221 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkImage.h>
#include <mitkDataNodeFactory.h>
#include <mitkCylindricToCartesianFilter.h>
#include <mitkImageSliceSelector.h>
#include <itksys/SystemTools.hxx>
#include <fstream>
int mitkImageSliceSelectorTest(int argc, char* argv[])
{
int slice_nr = 1;
std::cout << "Loading file: ";
if(argc==0)
{
std::cout<<"no file specified [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
mitk::Image::Pointer image = NULL;
mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
try
{
std::cout<<argv[1]<<std::endl;
factory->SetFileName( argv[1] );
factory->Update();
if(factory->GetNumberOfOutputs()<1)
{
std::cout<<"file could not be loaded [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
mitk::DataNode::Pointer node = factory->GetOutput( 0 );
image = dynamic_cast<mitk::Image*>(node->GetData());
if(image.IsNull())
{
std::cout<<"file not an image - test will not be applied [PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
}
catch ( itk::ExceptionObject & ex )
{
std::cout << "Exception: " << ex << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
if(image->GetDimension(2)<2)
slice_nr = 0;
//Take a slice
mitk::ImageSliceSelector::Pointer slice = mitk::ImageSliceSelector::New();
slice->SetInput(image);
slice->SetSliceNr(slice_nr);
slice->Update();
std::cout << "Testing IsInitialized(): ";
if(slice->GetOutput()->IsInitialized()==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing IsSliceSet(): ";
if(slice->GetOutput()->IsSliceSet(0)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
if(itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameExtension(argv[1])).find(".pic")!=std::string::npos)
{
std::cout << "Testing whether the slice is identical with a slice loaded by mitkIpPicGetSlice:";
mitkIpPicDescriptor *picslice = mitkIpPicGetSlice(argv[1], NULL, (image->GetDimension(2)-1-slice_nr)+1);
int i, size = _mitkIpPicSize(picslice);
char * p1 = (char*)slice->GetPic()->data;
char * p2 = (char*)picslice->data;
//picslice->info->write_protect=mitkIpFalse;
//mitkIpPicPut("C:\\1aaaaIPPIC.pic", picslice);
//mitkIpPicPut("C:\\1aaaaSEL.pic", slice->GetPic());
for(i=0; i<size; ++i, ++p1, ++p2)
{
if((*p1) != (*p2))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
}
std::cout<<"[PASSED]"<<std::endl;
mitkIpPicFree(picslice);
}
try
{
std::cout << "Testing another, smaller (!!) input with the same slice-selector(): ";
//Use CylindricToCartesianFilter
mitk::CylindricToCartesianFilter::Pointer cyl2cart = mitk::CylindricToCartesianFilter::New();
cyl2cart->SetInput(image);
//the output size of this filter is smaller than the of the input!!
cyl2cart->SetTargetXSize( 64 );
//Use the same slice-selector again, this time to take a slice of the filtered image
//which is smaller than the one of the old input!!
slice->SetInput(cyl2cart->GetOutput());
slice->SetSliceNr(1);
//The requested region is still the old one,
//therefore the following results in most ITK versions
//in an exception!
slice->Update();
//If no exception occured, check that the requested region is now
//the one of the smaller image
if(cyl2cart->GetOutput()->GetLargestPossibleRegion().GetSize()[0]!=64)
{
std::cout<<"Part 1 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"Part 1 (without exception) [PASSED] ";
//Check that the size of the output is now the one of the smaller image
if((cyl2cart->GetOutput()->GetDimensions()[0]!=64) || (cyl2cart->GetOutput()->GetDimensions()[1]!=64))
{
std::cout<<"Part 1b [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"Part 1b [PASSED] ";
}
catch ( itk::ExceptionObject &err)
{
std::cout<<"Part 1(with expected exception) ... seems to be not ITK 2.0.0 [PASSED]"<<std::endl;
std::cout<<err<<std::endl;
//after such an exception, we need to call ResetPipeline.
slice->ResetPipeline();
}
try
{
slice->UpdateLargestPossibleRegion();
}
catch ( itk::ExceptionObject )
{
std::cout<<"Part 2 [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"Part 2 [PASSED]"<<std::endl;
std::cout << "Testing IsInitialized(): ";
if(slice->GetOutput()->IsInitialized()==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing IsSliceSet(): ";
if(slice->GetOutput()->IsSliceSet(0)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
if(image->GetDimension(3) > 1)
{
int time=image->GetDimension(3)-1;
std::cout << "Testing 3D+t: Setting time to " << time << ": ";
slice->SetTimeNr(time);
if(slice->GetTimeNr()!=time)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing 3D+t: Updating slice: ";
slice->Update();
if(slice->GetOutput()->IsInitialized()==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing 3D+t: IsSliceSet(): ";
if(slice->GetOutput()->IsSliceSet(0)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing 3D+t: First slice in reader available: ";
if(image->IsSliceSet(0, time)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
}
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkImageTest.cpp b/Core/Code/Testing/mitkImageTest.cpp
index 3b7fca625f..3fa1c680fa 100644
--- a/Core/Code/Testing/mitkImageTest.cpp
+++ b/Core/Code/Testing/mitkImageTest.cpp
@@ -1,342 +1,341 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
// mitk includes
#include <mitkImage.h>
#include <mitkImageDataItem.h>
#include <mitkImageCast.h>
#include "mitkItkImageFileReader.h"
#include <mitkTestingMacros.h>
#include <mitkImageStatisticsHolder.h>
// itk includes
#include <itkImage.h>
#include <itkMersenneTwisterRandomVariateGenerator.h>
// stl includes
#include <fstream>
// vtk includes
#include <vtkImageData.h>
int mitkImageTest(int argc, char* argv[])
{
MITK_TEST_BEGIN(mitkImageTest);
//Create Image out of nowhere
mitk::Image::Pointer imgMem = mitk::Image::New();
mitk::PixelType pt = mitk::MakeScalarPixelType<int>();
unsigned int dim[]={100,100,20};
MITK_TEST_CONDITION_REQUIRED( imgMem.IsNotNull(), "An image was created. ");
// Initialize image
imgMem->Initialize( pt, 3, dim);
MITK_TEST_CONDITION_REQUIRED( imgMem->IsInitialized(), "Image::IsInitialized() ?");
MITK_TEST_CONDITION_REQUIRED( imgMem->GetPixelType() == pt, "PixelType was set correctly.");
int *p = (int*)imgMem->GetData();
MITK_TEST_CONDITION( p != NULL, "GetData() returned not-NULL pointer.");
// FIXME: this is directly changing the image data
// filling image
const unsigned int size = dim[0]*dim[1]*dim[2];
for(unsigned int i=0; i<size; ++i, ++p)
*p= (signed int)i;
// Getting it again and compare with filled values:
int *p2 = (int*)imgMem->GetData();
MITK_TEST_CONDITION( p2 != NULL, "GetData() returned not-NULL pointer.");
bool isEqual = true;
for(unsigned int i=0; i<size; ++i, ++p2)
{
if(*p2 != (signed int) i )
{
isEqual = false;
}
}
MITK_TEST_CONDITION( isEqual, "The values previously set as data are correct [pixelwise comparison].");
// Testing GetSliceData() and compare with filled values:
p2 = (int*)imgMem->GetSliceData(dim[2]/2)->GetData();
MITK_TEST_CONDITION_REQUIRED( p2 != NULL, "Valid slice data returned");
unsigned int xy_size = dim[0]*dim[1];
unsigned int start_mid_slice = (dim[2]/2)*xy_size;
isEqual = true;
for(unsigned int i=0; i<xy_size; ++i, ++p2)
{
if(*p2!=(signed int)(i+start_mid_slice))
{
isEqual = false;
}
}
MITK_TEST_CONDITION( isEqual, "The SliceData are correct [pixelwise comparison]. ");
imgMem = mitk::Image::New();
// testing re-initialization of test image
mitk::PixelType pType = mitk::MakePixelType<int, int, 1>();
imgMem->Initialize( pType , 3, dim);
MITK_TEST_CONDITION_REQUIRED(imgMem->GetDimension()== 3, "Testing initialization parameter dimension!");
MITK_TEST_CONDITION_REQUIRED(imgMem->GetPixelType() == pType, "Testing initialization parameter pixeltype!");
MITK_TEST_CONDITION_REQUIRED(imgMem->GetDimension(0) == dim[0] &&
imgMem->GetDimension(1)== dim[1] && imgMem->GetDimension(2)== dim[2], "Testing initialization of dimensions!");
MITK_TEST_CONDITION( imgMem->IsInitialized(), "Image is initialized.");
// Setting volume again:
imgMem->SetVolume(imgMem->GetData());
//-----------------
// geometry information for image
mitk::Point3D origin;
mitk::Vector3D right, bottom;
mitk::Vector3D spacing;
mitk::FillVector3D(origin, 17.0, 19.92, 7.83);
mitk::FillVector3D(right, 1.0, 2.0, 3.0);
mitk::FillVector3D(bottom, 0.0, -3.0, 2.0);
mitk::FillVector3D(spacing, 0.78, 0.91, 2.23);
//InitializeStandardPlane(rightVector, downVector, spacing)
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing);
planegeometry->SetOrigin(origin);
// Testing Initialize(const mitk::PixelType& type, const mitk::Geometry3D& geometry, unsigned int slices) with PlaneGeometry and GetData(): ";
imgMem->Initialize( mitk::MakePixelType<int, int, 1>(), *planegeometry);
MITK_TEST_CONDITION_REQUIRED( imgMem->GetGeometry()->GetOrigin() == static_cast<mitk::Geometry3D*>(planegeometry)->GetOrigin(), "Testing correct setting of geometry via initialize!");
p = (int*)imgMem->GetData();
MITK_TEST_CONDITION_REQUIRED( p!=NULL, "GetData() returned valid pointer.");
// Testing Initialize(const mitk::PixelType& type, int sDim, const mitk::PlaneGeometry& geometry) and GetData(): ";
imgMem->Initialize( mitk::MakePixelType<int, int, 1>() , 40, *planegeometry);
p = (int*)imgMem->GetData();
MITK_TEST_CONDITION_REQUIRED( p!=NULL, "GetData() returned valid pointer.");
//-----------------
// testing origin information and methods
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetGeometry()->GetOrigin(), origin), "Testing correctness of origin via GetGeometry()->GetOrigin(): ");
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetTimeSlicedGeometry()->GetOrigin(), origin), "Testing correctness of origin via GetTimeSlicedGeometry()->GetOrigin(): ");
// Setting origin via SetOrigin(origin): ";
mitk::FillVector3D(origin, 37.0, 17.92, 27.83);
imgMem->SetOrigin(origin);
// Test origin
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetGeometry()->GetOrigin(), origin), "Testing correctness of changed origin via GetGeometry()->GetOrigin(): ");
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetTimeSlicedGeometry()->GetOrigin(), origin), "Testing correctness of changed origin via GetTimeSlicedGeometry()->GetOrigin(): ");
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetSlicedGeometry()->GetGeometry2D(0)->GetOrigin(), origin), "Testing correctness of changed origin via GetSlicedGeometry()->GetGeometry2D(0)->GetOrigin(): ");
//-----------------
// testing spacing information and methods
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetSpacing(), spacing), "Testing correct spacing from Geometry3D!");
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetTimeSlicedGeometry()->GetSpacing(), spacing), "Testing correctspacing from TimeSlicedGeometry!");
mitk::FillVector3D(spacing, 7.0, 0.92, 1.83);
imgMem->SetSpacing(spacing);
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetGeometry()->GetSpacing(), spacing), "Testing correctness of changed spacing via GetGeometry()->GetSpacing(): ");
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetTimeSlicedGeometry()->GetSpacing(), spacing), "Testing correctness of changed spacing via GetTimeSlicedGeometry()->GetSpacing(): ");
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetSlicedGeometry()->GetGeometry2D(0)->GetSpacing(), spacing), "Testing correctness of changed spacing via GetSlicedGeometry()->GetGeometry2D(0)->GetSpacing(): ");
mitk::Image::Pointer vecImg = mitk::Image::New();
vecImg->Initialize( imgMem->GetPixelType(), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/ );
vecImg->SetImportChannel(imgMem->GetData(), 0, mitk::Image::CopyMemory );
vecImg->SetImportChannel(imgMem->GetData(), 1, mitk::Image::CopyMemory );
MITK_TEST_CONDITION_REQUIRED(vecImg->GetChannelData(0)->GetData() != NULL && vecImg->GetChannelData(1)->GetData() != NULL, "Testing set and return of channel data!");
MITK_TEST_CONDITION_REQUIRED( vecImg->IsValidSlice(0,0,1) , "");
MITK_TEST_OUTPUT(<< " Testing whether CopyMemory worked");
MITK_TEST_CONDITION_REQUIRED(imgMem->GetData() != vecImg->GetData(), "");
MITK_TEST_OUTPUT(<< " Testing destruction after SetImportChannel");
vecImg = NULL;
MITK_TEST_CONDITION_REQUIRED(vecImg.IsNull() , "testing destruction!");
//-----------------
MITK_TEST_OUTPUT(<< "Testing initialization via vtkImageData");
MITK_TEST_OUTPUT(<< " Setting up vtkImageData");
vtkImageData* vtkimage = vtkImageData::New();
vtkimage->Initialize();
vtkimage->SetDimensions( 2, 3, 4);
double vtkorigin[] = {-350,-358.203, -1363.5};
vtkimage->SetOrigin(vtkorigin);
mitk::Point3D vtkoriginAsMitkPoint;
mitk::vtk2itk(vtkorigin, vtkoriginAsMitkPoint);
double vtkspacing[] = {1.367, 1.367, 2};
vtkimage->SetSpacing(vtkspacing);
vtkimage->SetScalarType( VTK_SHORT );
vtkimage->AllocateScalars();
std::cout<<"[PASSED]"<<std::endl;
MITK_TEST_OUTPUT(<< " Testing mitk::Image::Initialize(vtkImageData*, ...)");
mitk::Image::Pointer mitkByVtkImage = mitk::Image::New();
mitkByVtkImage ->Initialize(vtkimage);
MITK_TEST_CONDITION_REQUIRED(mitkByVtkImage->IsInitialized(), "");
vtkimage->Delete();
MITK_TEST_OUTPUT(<< " Testing whether spacing has been correctly initialized from vtkImageData");
mitk::Vector3D spacing2 = mitkByVtkImage->GetGeometry()->GetSpacing();
mitk::Vector3D vtkspacingAsMitkVector;
mitk::vtk2itk(vtkspacing, vtkspacingAsMitkVector);
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(spacing2,vtkspacingAsMitkVector), "");
MITK_TEST_OUTPUT(<< " Testing whether GetSlicedGeometry(0)->GetOrigin() has been correctly initialized from vtkImageData");
mitk::Point3D origin2 = mitkByVtkImage->GetSlicedGeometry(0)->GetOrigin();
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2,vtkoriginAsMitkPoint), "");
MITK_TEST_OUTPUT(<< " Testing whether GetGeometry()->GetOrigin() has been correctly initialized from vtkImageData");
origin2 = mitkByVtkImage->GetGeometry()->GetOrigin();
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2,vtkoriginAsMitkPoint), "");
MITK_TEST_OUTPUT(<< " Testing whether GetTimeSlicedGeometry()->GetOrigin() has been correctly initialized from vtkImageData");
origin2 = mitkByVtkImage->GetTimeSlicedGeometry()->GetOrigin();
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2,vtkoriginAsMitkPoint), "");
// TODO test the following initializers on channel-incorporation
// void mitk::Image::Initialize(const mitk::PixelType& type, unsigned int dimension, unsigned int *dimensions, unsigned int channels)
// void mitk::Image::Initialize(const mitk::PixelType& type, int sDim, const mitk::Geometry2D& geometry2d, bool flipped, unsigned int channels, int tDim )
// void mitk::Image::Initialize(const mitk::Image* image)
// void mitk::Image::Initialize(const mitkIpPicDescriptor* pic, int channels, int tDim, int sDim)
//mitk::Image::Pointer vecImg = mitk::Image::New();
//vecImg->Initialize(PixelType(typeid(float), 6, itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/, false /*shiftBoundingBoxMinimumToZero*/ );
//vecImg->Initialize(PixelType(typeid(itk::Vector<float,6>)), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/, false /*shiftBoundingBoxMinimumToZero*/ );
// testing access by index coordinates and by world coordinates
MITK_TEST_CONDITION_REQUIRED(argc == 2, "Check if test image is accessible!");
const std::string filename = std::string(argv[1]);
mitk::ItkImageFileReader::Pointer imageReader = mitk::ItkImageFileReader::New();
try
{
imageReader->SetFileName(filename);
imageReader->Update();
}
catch(...) {
MITK_TEST_FAILED_MSG(<< "Could not read file for testing: " << filename);
return 0;
}
mitk::Image::Pointer image = imageReader->GetOutput();
// generate a random point in world coordinates
mitk::Point3D xMax, yMax, zMax, xMaxIndex, yMaxIndex, zMaxIndex;
xMaxIndex.Fill(0.0f);
yMaxIndex.Fill(0.0f);
zMaxIndex.Fill(0.0f);
xMaxIndex[0] = image->GetLargestPossibleRegion().GetSize()[0];
yMaxIndex[1] = image->GetLargestPossibleRegion().GetSize()[1];
zMaxIndex[2] = image->GetLargestPossibleRegion().GetSize()[2];
image->GetGeometry()->IndexToWorld(xMaxIndex, xMax);
image->GetGeometry()->IndexToWorld(yMaxIndex, yMax);
image->GetGeometry()->IndexToWorld(zMaxIndex, zMax);
MITK_INFO << "Origin " << image->GetGeometry()->GetOrigin()[0] << " "<< image->GetGeometry()->GetOrigin()[1] << " "<< image->GetGeometry()->GetOrigin()[2] << "";
MITK_INFO << "MaxExtend " << xMax[0] << " "<< yMax[1] << " "<< zMax[2] << "";
mitk::Point3D point;
itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randomGenerator = itk::Statistics::MersenneTwisterRandomVariateGenerator::New();
randomGenerator->Initialize( std::rand() ); // initialize with random value, to get sensible random points for the image
point[0] = randomGenerator->GetUniformVariate( image->GetGeometry()->GetOrigin()[0], xMax[0]);
point[1] = randomGenerator->GetUniformVariate( image->GetGeometry()->GetOrigin()[1], yMax[1]);
point[2] = randomGenerator->GetUniformVariate( image->GetGeometry()->GetOrigin()[2], zMax[2]);
MITK_INFO << "RandomPoint " << point[0] << " "<< point[1] << " "<< point[2] << "";
// test values and max/min
mitk::ScalarType imageMin = image->GetStatistics()->GetScalarValueMin();
mitk::ScalarType imageMax = image->GetStatistics()->GetScalarValueMax();
mitk::ScalarType value = image->GetPixelValueByWorldCoordinate(point);
MITK_INFO << imageMin << " "<< imageMax << " "<< value << "";
MITK_TEST_CONDITION( (value >= imageMin && value <= imageMax), "Value returned is between max/min");
// testing the clone method of mitk::Image
mitk::Image::Pointer cloneImage = image->Clone();
MITK_TEST_CONDITION_REQUIRED(cloneImage->GetDimension() == image->GetDimension(), "Clone (testing dimension)");
MITK_TEST_CONDITION_REQUIRED(cloneImage->GetPixelType() == image->GetPixelType(), "Clone (testing pixel type)");
// After cloning an image the geometry of both images should be equal too
MITK_TEST_CONDITION_REQUIRED(cloneImage->GetGeometry()->GetOrigin() == image->GetGeometry()->GetOrigin(), "Clone (testing origin)");
MITK_TEST_CONDITION_REQUIRED(cloneImage->GetGeometry()->GetSpacing() == image->GetGeometry()->GetSpacing(), "Clone (testing spacing)");
MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualElementWise(cloneImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix(), image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix()),
"Clone (testing transformation matrix)");
for (unsigned int i = 0u; i < cloneImage->GetDimension(); ++i)
{
MITK_TEST_CONDITION_REQUIRED(cloneImage->GetDimension(i) == image->GetDimension(i), "Clone (testing dimension " << i << ")");
}
//access via itk
if(image->GetDimension()> 3) // CastToItk only works with 3d images so we need to check for 4d images
{
mitk::ImageTimeSelector::Pointer selector = mitk::ImageTimeSelector::New();
selector->SetTimeNr(0);
selector->SetInput(image);
selector->Update();
image = selector->GetOutput();
}
if(image->GetDimension()==3)
{
typedef itk::Image<float,3> ItkFloatImage3D;
ItkFloatImage3D::Pointer itkimage;
mitk::CastToItkImage(image, itkimage);
MITK_TEST_CONDITION_REQUIRED(itkimage.IsNotNull(), "Test conversion to itk::Image!");
mitk::Point3D itkPhysicalPoint;
image->GetGeometry()->WorldToItkPhysicalPoint(point, itkPhysicalPoint);
MITK_INFO << "ITKPoint " << itkPhysicalPoint[0] << " "<< itkPhysicalPoint[1] << " "<< itkPhysicalPoint[2] << "";
mitk::Point3D backTransformedPoint;
image->GetGeometry()->ItkPhysicalPointToWorld(itkPhysicalPoint, backTransformedPoint);
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(point,backTransformedPoint), "Testing world->itk-physical->world consistency");
itk::Index<3> idx;
bool status = itkimage->TransformPhysicalPointToIndex(itkPhysicalPoint, idx);
MITK_INFO << "ITK Index " << idx[0] << " "<< idx[1] << " "<< idx[2] << "";
if(status)
{
float valByItk = itkimage->GetPixel(idx);
MITK_TEST_CONDITION_REQUIRED( mitk::Equal(valByItk, value), "Compare value of pixel returned by mitk in comparison to itk");
}
else
{
MITK_WARN<< "Index is out buffered region!";
}
}
else
{
MITK_INFO << "Image does not contain three dimensions, some test cases are skipped!";
}
// clone generated 3D image with one slice in z direction (cf. bug 11058)
unsigned int* threeDdim = new unsigned int[3];
threeDdim[0] = 100;
threeDdim[1] = 200;
threeDdim[2] = 1;
mitk::Image::Pointer threeDImage = mitk::Image::New();
threeDImage->Initialize(mitk::MakeScalarPixelType<float>(), 3, threeDdim);
mitk::Image::Pointer cloneThreeDImage = threeDImage->Clone();
// check that the clone image has the same dimensionality as the source image
MITK_TEST_CONDITION_REQUIRED( cloneThreeDImage->GetDimension() == 3, "Testing if the clone image initializes with 3D!");
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkImageTimeSelectorTest.cpp b/Core/Code/Testing/mitkImageTimeSelectorTest.cpp
index 1631e1ae00..51b9149627 100644
--- a/Core/Code/Testing/mitkImageTimeSelectorTest.cpp
+++ b/Core/Code/Testing/mitkImageTimeSelectorTest.cpp
@@ -1,91 +1,90 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkDataNodeFactory.h"
#include "mitkImageTimeSelector.h"
#include <itksys/SystemTools.hxx>
#include <fstream>
int mitkImageTimeSelectorTest(int argc, char* argv[])
{
std::cout << "Loading file: ";
if(argc==0)
{
std::cout<<"no file specified [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
mitk::Image::Pointer image = NULL;
mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
try
{
factory->SetFileName( argv[1] );
factory->Update();
if(factory->GetNumberOfOutputs()<1)
{
std::cout<<"file could not be loaded [FAILED]"<<std::endl;
return EXIT_FAILURE;
}
mitk::DataNode::Pointer node = factory->GetOutput( 0 );
image = dynamic_cast<mitk::Image*>(node->GetData());
if(image.IsNull())
{
std::cout<<"file not an image - test will not be applied [PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
}
catch ( itk::ExceptionObject & ex )
{
std::cout << "Exception: " << ex << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
//Take a time step
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput(image);
timeSelector->SetTimeNr( 0 );
timeSelector->UpdateLargestPossibleRegion();
mitk::Image::Pointer result = timeSelector->GetOutput();
std::cout << "Testing IsInitialized(): ";
if(result->IsInitialized()==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing if Volume is set ";
//result->DisconnectPipeline();
//timeSelector = NULL;
if( result->IsVolumeSet(0) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkImageToItkTest.cpp b/Core/Code/Testing/mitkImageToItkTest.cpp
index df403c3a1b..d0f99761a9 100644
--- a/Core/Code/Testing/mitkImageToItkTest.cpp
+++ b/Core/Code/Testing/mitkImageToItkTest.cpp
@@ -1,271 +1,270 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkITKImageImport.h"
#include "mitkReferenceCountWatcher.h"
#include "itkDiffusionTensor3D.h"
#include "itkConfidenceDiffusionTensor3D.h"
#include <mitkImageCast.h>
#include <fstream>
int compareGeometries(mitk::Geometry3D* geometry1, mitk::Geometry3D* geometry2)
{
std::cout << "Testing transfer of GetGeometry()->GetOrigin(): " << std::flush;
if(mitk::Equal(geometry1->GetOrigin(), geometry2->GetOrigin()) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing transfer of GetGeometry()->GetSpacing(): " << std::flush;
if(mitk::Equal(geometry1->GetSpacing(), geometry2->GetSpacing()) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
int i;
for(i=0; i<3; ++i)
{
std::cout << "Testing transfer of GetGeometry()->GetAxisVector(" << i << "): " << std::flush;
if(mitk::Equal(geometry1->GetAxisVector(i), geometry2->GetAxisVector(i)) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
}
return EXIT_SUCCESS;
}
template <class ImageType>
int testBackCasting(mitk::Image* imgMem, typename ImageType::Pointer & itkImage, bool disconnectAfterImport)
{
int result;
if(itkImage.IsNull())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
int *p = (int*)itkImage->GetBufferPointer();
if(p==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::CastToMitkImage: " << std::flush;
mitk::Image::Pointer mitkImage = mitk::Image::New();
mitk::CastToMitkImage( itkImage, mitkImage );
std::cout<<"[PASSED]"<<std::endl;
result = compareGeometries(imgMem->GetGeometry(), mitkImage->GetGeometry());
if(result != EXIT_SUCCESS)
return result;
std::cout << "Testing whether data after mitk::CastToMitkImage is available: " << std::flush;
if(mitkImage->IsChannelSet()==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::ImportItkImage: " << std::flush;
mitkImage = mitk::ImportItkImage(itkImage);
std::cout<<"[PASSED]"<<std::endl;
if(disconnectAfterImport)
{
std::cout << "Testing DisconnectPipeline() on mitk::Image into which was imported : " << std::flush;
mitkImage->DisconnectPipeline();
std::cout<<"[PASSED]"<<std::endl;
}
result = compareGeometries(imgMem->GetGeometry(), mitkImage->GetGeometry());
if(result != EXIT_SUCCESS)
return result;
std::cout << "Testing whether data after mitk::ImportItkImage is available: " << std::flush;
if(mitkImage->IsChannelSet()==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
template <unsigned int dim>
int testImageToItkAndBack(mitk::Image* imgMem)
{
int result;
int *p = (int*)imgMem->GetData();
if(p==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing for dimension " << dim << ": " << std::flush;
std::cout << "Testing mitk::ImageToItk: " << std::flush;
typedef itk::Image<int,dim> ImageType;
typename mitk::ImageToItk<ImageType>::Pointer toItkFilter = mitk::ImageToItk<ImageType>::New();
toItkFilter->SetInput(imgMem);
toItkFilter->Update();
typename ImageType::Pointer itkImage = toItkFilter->GetOutput();
result = testBackCasting<ImageType>(imgMem, itkImage, false);
if(result != EXIT_SUCCESS)
return result;
std::cout << "Testing mitk::ImageToItk (with subsequent DisconnectPipeline, see below): " << std::flush;
result = testBackCasting<ImageType>(imgMem, itkImage, true);
if(result != EXIT_SUCCESS)
return result;
return EXIT_SUCCESS;
}
int mitkImageToItkTest(int /*argc*/, char* /*argv*/[])
{
int result;
//Create Image out of nowhere
mitk::Image::Pointer imgMem;
mitk::PixelType pt(typeid(int));
std::cout << "Testing creation of Image: ";
imgMem=mitk::Image::New();
if(imgMem.IsNull())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
// geometry information for image
mitk::Point3D origin;
mitk::Vector3D right, bottom;
mitk::Vector3D spacing;
mitk::FillVector3D(origin, 17.0, 19.92, 7.83);
mitk::FillVector3D(right, 1.0, 2.0, 3.0);
mitk::FillVector3D(bottom, 0.0, -3.0, 2.0);
mitk::FillVector3D(spacing, 0.78, 0.91, 2.23);
std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing): " << std::flush;
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing);
planegeometry->SetOrigin(origin);
std::cout << "done" << std::endl;
std::cout << "Testing Initialize(const mitk::PixelType& type, int sDim, const mitk::PlaneGeometry& geometry) and GetData(): ";
imgMem->Initialize(mitk::PixelType(typeid(int)), 40, *planegeometry); //XXXXXXXXXXXXXXXXXXXXXCHANGE!
result = testImageToItkAndBack<3>(imgMem);
if(result != EXIT_SUCCESS)
return result;
std::cout << "Testing mitk::CastToItkImage with casting (mitk int to itk float): " << std::flush;
typedef itk::Image<float,3> ImageType;
ImageType::Pointer itkImage;
mitk::CastToItkImage( imgMem, itkImage );
result = testBackCasting<ImageType>(imgMem, itkImage, false);
if(result != EXIT_SUCCESS)
return result;
result = testBackCasting<ImageType>(imgMem, itkImage, true);
if(result != EXIT_SUCCESS)
return result;
std::cout << "Testing Initialize(const mitk::PixelType& type, int sDim, const mitk::PlaneGeometry& geometry) and GetData(): ";
imgMem->Initialize(mitk::PixelType(typeid(int)), 40, *planegeometry, false, 1, 6);
result = testImageToItkAndBack<4>(imgMem);
if(result != EXIT_SUCCESS)
return result;
std::cout << "Testing mitk::CastToItkImage again (mitk float to itk float): " << std::flush;
imgMem->Initialize(mitk::PixelType(typeid(float)), 40, *planegeometry);
mitk::CastToItkImage( imgMem, itkImage );
std::cout<<"[PASSED]"<<std::endl;
mitk::ImageDataItem::Pointer imageDataItem = imgMem->GetChannelData().GetPointer();
std::cout << "Testing destruction of original mitk::Image: " << std::flush;
imgMem = NULL;
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count mitk::ImageDataItem, which is responsible for the memory still used within the itk::Image: " << std::flush;
if(imageDataItem->GetReferenceCount()-1 != 1) // 1 count by imageDataItem itself
{
std::cout<< imageDataItem->GetReferenceCount()-1 << " != 1. [FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing destruction of itk::Image: " << std::flush;
itkImage = NULL;
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing reference count mitk::ImageDataItem, which should now have been freed by itk::Image: " << std::flush;
if(imageDataItem->GetReferenceCount()-1 != 0) // 1 count by imageDataItem itself
{
std::cout<< imageDataItem->GetReferenceCount()-1 << " != 0. [FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
imgMem=mitk::Image::New();
itk::Image<itk::DiffusionTensor3D<float>,3>::Pointer diffImage;
imgMem->Initialize(mitk::PixelType(typeid(itk::DiffusionTensor3D<float>)), 40, *planegeometry);
mitk::CastToItkImage( imgMem, diffImage );
imgMem->InitializeByItk(diffImage.GetPointer());
std::cout<<"[PASSED]"<<std::endl;
itk::Image<itk::DiffusionTensor3D<double>,3>::Pointer diffImage2;
imgMem->Initialize(mitk::PixelType(typeid(itk::DiffusionTensor3D<double>)), 40, *planegeometry);
mitk::CastToItkImage( imgMem, diffImage2 );
imgMem->InitializeByItk(diffImage2.GetPointer());
std::cout<<"[PASSED]"<<std::endl;
itk::Image<itk::ConfidenceDiffusionTensor3D<float>,3>::Pointer confDiffImage;
imgMem->Initialize(mitk::PixelType(typeid(itk::ConfidenceDiffusionTensor3D<float>)), 40, *planegeometry);
mitk::CastToItkImage( imgMem, confDiffImage );
imgMem->InitializeByItk(confDiffImage.GetPointer());
std::cout<<"[PASSED]"<<std::endl;
itk::Image<itk::ConfidenceDiffusionTensor3D<double>,3>::Pointer confDiffImage2;
imgMem->Initialize(mitk::PixelType(typeid(itk::ConfidenceDiffusionTensor3D<double>)), 40, *planegeometry);
mitk::CastToItkImage( imgMem, confDiffImage2 );
imgMem->InitializeByItk(confDiffImage2.GetPointer());
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkImageVtkMapper2DTest.cpp b/Core/Code/Testing/mitkImageVtkMapper2DTest.cpp
index c8010cc619..f677e9d2af 100644
--- a/Core/Code/Testing/mitkImageVtkMapper2DTest.cpp
+++ b/Core/Code/Testing/mitkImageVtkMapper2DTest.cpp
@@ -1,124 +1,123 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include "mitkDataNodeFactory.h"
#include "mitkStandaloneDataStorage.h"
#include <vtkImageData.h>
#include <vtkSmartPointer.h>
#include <vtkPNGWriter.h>
#include <vtkRegressionTestImage.h> // nice one
#include <vector>
#include <algorithm>
#include "mitkRenderingTestHelper.h"
#include <mitkLevelWindow.h>
class mitkRenderingTestHelperClass
{
public:
static mitk::BaseData::Pointer AddToStorage(const std::string& filename)
{
mitk::DataNodeFactory::Pointer reader = mitk::DataNodeFactory::New();
try
{
reader->SetFileName( filename );
reader->Update();
if(reader->GetNumberOfOutputs()<1)
{
MITK_TEST_FAILED_MSG(<< "Could not find test data '" << filename << "'");
}
mitk::DataNode::Pointer node = reader->GetOutput( 0 );
mitkRenderingTestHelperClass::s_DataStorage->Add(node);
return node->GetData();
}
catch ( itk::ExceptionObject & e )
{
MITK_TEST_FAILED_MSG(<< "Failed loading test data '" << filename << "': " << e.what());
}
}
static mitk::DataStorage::Pointer s_DataStorage;
}; // end test helper class
mitk::DataStorage::Pointer mitkRenderingTestHelperClass::s_DataStorage;
int mitkImageVtkMapper2DTest(int argc, char* argv[])
{
// load all arguments into a datastorage, take last argument as reference rendering
// setup a renderwindow of fixed size X*Y
// render the datastorage
// compare rendering to reference image
MITK_TEST_BEGIN("mitkImageVtkMapper2DTest")
// enough parameters?
if ( argc < 2 )
{
MITK_TEST_OUTPUT( << "Usage: " << std::string(*argv) << " [file1 file2 ...] outputfile" )
MITK_TEST_OUTPUT( << "Will render a central transversal slice of all given files into outputfile" )
exit( EXIT_SUCCESS );
}
// parse parameters
std::vector<std::string> inputFileNames;
for (int i = 1; i < argc-1; ++i)
{
//add everything to a list but -T and -V
std::string tmp = argv[i];
if((tmp.compare("-T")) && (tmp.compare("-V")))
{
inputFileNames.push_back( tmp );
}
}
// std::string outputFileName( argv[argc-1] );
// load all input into a data storage
mitkRenderingTestHelperClass::s_DataStorage = mitk::StandaloneDataStorage::New().GetPointer();
MITK_TEST_CONDITION_REQUIRED(mitkRenderingTestHelperClass::s_DataStorage.IsNotNull(),"StandaloneDataStorage instantiation");
std::for_each( inputFileNames.begin(), inputFileNames.end(), mitkRenderingTestHelperClass::AddToStorage );
// create a mitkRenderWindow, let it render the scene and get the vtkRenderWindow
mitkRenderingTestHelper renderingHelper( 640, 480, mitkRenderingTestHelperClass::s_DataStorage );
//use this to generate a reference screenshot or save the file:
bool generateReferenceScreenshot = false;
if(generateReferenceScreenshot)
{
renderingHelper.SaveAsPNG("/home/kilgus/Pictures/RenderingTestData/output.png");
}
int retVal = vtkRegressionTestImage( renderingHelper.GetVtkRenderWindow() );
//retVal meanings: (see VTK/Rendering/vtkTesting.h)
//0 = test failed
//1 = test passed
//2 = test not run
//3 = something with vtkInteraction
MITK_TEST_CONDITION( retVal == 1, "VTK test result positive" );
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkImageWriterTest.cpp b/Core/Code/Testing/mitkImageWriterTest.cpp
index 99f3f79459..859160a7b3 100644
--- a/Core/Code/Testing/mitkImageWriterTest.cpp
+++ b/Core/Code/Testing/mitkImageWriterTest.cpp
@@ -1,201 +1,200 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImageWriter.h"
#include "mitkDataNodeFactory.h"
#include "mitkTestingMacros.h"
#include <iostream>
#include <fstream>
#ifdef WIN32
#include "process.h"
#endif
std::string AppendExtension(const std::string &filename, const char *extension)
{
std::string new_filename = filename;
new_filename += extension;
return new_filename;
}
/**
* test for "ImageWriter".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkImageWriterTest(int argc , char* argv[])
{
// always start with this!
MITK_TEST_BEGIN("ImageWriter")
// let's create an object of our class
mitk::ImageWriter::Pointer myImageWriter = mitk::ImageWriter::New();
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
MITK_TEST_CONDITION_REQUIRED(myImageWriter.IsNotNull(),"Testing instantiation")
// write your own tests here and use the macros from mitkTestingMacros.h !!!
// do not write to std::cout and do not return from this function yourself!
// load image
MITK_TEST_CONDITION_REQUIRED(argc != 0, "File to load has been specified");
mitk::Image::Pointer image = NULL;
mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New();
try
{
MITK_TEST_OUTPUT(<< "Loading file: " << argv[1]);
factory->SetFileName( argv[1] );
factory->Update();
MITK_TEST_CONDITION_REQUIRED(factory->GetNumberOfOutputs() > 0, "file loaded");
mitk::DataNode::Pointer node = factory->GetOutput( 0 );
image = dynamic_cast<mitk::Image*>(node->GetData());
if(image.IsNull())
{
std::cout<<"file "<< argv[1]<< "is not an image - test will not be applied."<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
}
catch (itk::ExceptionObject & ex)
{
MITK_TEST_FAILED_MSG(<< "Exception during file loading: " << ex.GetDescription());
}
MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(),"loaded image not NULL")
std::stringstream filename_stream;
#ifdef WIN32
filename_stream << "test" << _getpid();
#else
filename_stream << "test" << getpid();
#endif
std::string filename = filename_stream.str();
// test set/get methods
myImageWriter->SetInput(image);
MITK_TEST_CONDITION_REQUIRED(myImageWriter->GetInput()==image,"test Set/GetInput()");
myImageWriter->SetFileName(filename);
MITK_TEST_CONDITION_REQUIRED(!strcmp(myImageWriter->GetFileName(),filename.c_str()),"test Set/GetFileName()");
myImageWriter->SetFilePrefix("pref");
MITK_TEST_CONDITION_REQUIRED(!strcmp(myImageWriter->GetFilePrefix(),"pref"),"test Set/GetFilePrefix()");
myImageWriter->SetFilePattern("pattern");
MITK_TEST_CONDITION_REQUIRED(!strcmp(myImageWriter->GetFilePattern(),"pattern"),"test Set/GetFilePattern()");
// write ITK .mhd image (2D and 3D only)
if( image->GetDimension() <= 3 )
{
try
{
myImageWriter->SetExtension(".mhd");
myImageWriter->Update();
std::fstream fin, fin2;
fin.open(AppendExtension(filename, ".mhd").c_str(),std::ios::in);
std::string rawExtension = ".raw";
fin2.open(AppendExtension(filename, ".raw").c_str(),std::ios::in);
if( !fin2.is_open() )
{
rawExtension = ".zraw";
fin2.open(AppendExtension(filename, ".zraw").c_str(),std::ios::in);
}
MITK_TEST_CONDITION_REQUIRED(fin.is_open(),"Write .mhd file");
MITK_TEST_CONDITION_REQUIRED(fin2.is_open(),"Write .raw file");
fin.close();
fin2.close();
remove(AppendExtension(filename, ".mhd").c_str());
remove(AppendExtension(filename, rawExtension.c_str()).c_str());
}
catch (...)
{
MITK_TEST_FAILED_MSG(<< "Exception during .mhd file writing");
}
}
//testing more component image writing as nrrd files
try
{
myImageWriter->SetExtension(".nrrd");
myImageWriter->Update();
std::fstream fin;
fin.open(AppendExtension(filename, ".nrrd").c_str(),std::ios::in);
MITK_TEST_CONDITION_REQUIRED(fin.is_open(),"Write .nrrd file");
fin.close();
remove(AppendExtension(filename, ".nrrd").c_str());
}
catch(...)
{
MITK_TEST_FAILED_MSG(<< "Exception during .nrrd file writing");
}
// testing image writing as png files
// test only for 2D images since the PNG is using a series writer in case a 3D image
// should be saved -> the output name comparison would fail and also the use case
// is very uncommon
// write ITK .mhd image (2D and 3D only)
if( image->GetDimension() == 2 )
{
try
{
myImageWriter->SetExtension(".png");
myImageWriter->Update();
std::fstream fin;
fin.open(AppendExtension(filename, ".png").c_str(),std::ios::in);
MITK_TEST_CONDITION_REQUIRED(fin.is_open(),"Write .png file");
fin.close();
remove(AppendExtension(filename, ".png").c_str());
}
catch(itk::ExceptionObject &e)
{
MITK_TEST_FAILED_MSG(<< "Exception during .png file writing: " << e.what() );
}
}
// test for exception handling
try
{
MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject)
myImageWriter->SetInput(image);
myImageWriter->SetFileName("/usr/bin");
myImageWriter->Update();
MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject)
}
catch(...) {
//this means that a wrong exception (i.e. no itk:Exception) has been thrown
MITK_TEST_FAILED_MSG(<< "Wrong exception (i.e. no itk:Exception) caught during write");
}
// always end with this!
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkInstantiateAccessFunctionTest.cpp b/Core/Code/Testing/mitkInstantiateAccessFunctionTest.cpp
index f3a4546cb9..4786aface5 100644
--- a/Core/Code/Testing/mitkInstantiateAccessFunctionTest.cpp
+++ b/Core/Code/Testing/mitkInstantiateAccessFunctionTest.cpp
@@ -1,50 +1,49 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 17495 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include <mitkInstantiateAccessFunctions.h>
// This is a "compile test", meaning that this file calls all InstantiateAccessFunction macros
// and must successfully compile.
class InstantiateAccessFunctionTest
{
public:
template<typename TPixel, unsigned int VDimension>
void AccessItkImage(itk::Image<TPixel, VDimension>*, int)
{ }
};
#define InstantiateAccessFunction_AccessItkImage(Pixel, Dim) \
template void InstantiateAccessFunctionTest::AccessItkImage(itk::Image<Pixel, Dim>*, int);
InstantiateAccessFunctionForFixedPixelType(AccessItkImage, (float)(double))
InstantiateAccessFunctionForIntegralPixelTypes(AccessItkImage)
int mitkInstantiateAccessFunctionTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("InstantiateAccessFunction")
MITK_TEST_OUTPUT(<< "Successfully compiled")
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkInteractorTest.cpp b/Core/Code/Testing/mitkInteractorTest.cpp
index 8710a01139..ef6b484b06 100644
--- a/Core/Code/Testing/mitkInteractorTest.cpp
+++ b/Core/Code/Testing/mitkInteractorTest.cpp
@@ -1,92 +1,91 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkInteractor.h"
#include "mitkEvent.h"
#include "mitkStateEvent.h"
#include "mitkInteractionConst.h"
#include "mitkGlobalInteraction.h"
#include "mitkTestingMacros.h"
#include <iostream>
int mitkInteractorTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("Interactor")
// Global interaction must(!) be initialized if used
mitk::GlobalInteraction::GetInstance()->Initialize("global");
//create interactor; use pattern InteractorTestPattern
mitk::Interactor::Pointer interactor = mitk::Interactor::New("InteractorTestPattern", NULL);
//load interactor
std::cout << "Testing to initialize the interactor";
MITK_TEST_CONDITION_REQUIRED(interactor.IsNotNull(),"Testing to initialize the interactor")
std::cout<<"The pattern of the interactor is called: "<<interactor->GetType()<<std::endl;
//creating an event to go from state 0 to state 1:
//<!-- middle MouseButton -->
//<event NAME="middle MouseBN" ID="4" TYPE="Type_MouseButtonPress" BUTTON="BS_MidButton" BUTTONSTATE="0x0000" KEY="Key_none" />
mitk::Event *event = new mitk::Event(NULL, mitk::Type_MouseButtonPress, mitk::BS_MidButton, mitk::BS_NoButton, mitk::Key_none);
mitk::StateEvent *stateEvent = new mitk::StateEvent(4, event);
MITK_TEST_CONDITION_REQUIRED(interactor->HandleEvent(stateEvent),"Testing to send an event to go from State 0 to State 1")
MITK_TEST_CONDITION_REQUIRED(interactor->GetMode() == mitk::Interactor::SMSELECTED,"Testing right Mode and thus right action behavior")
//statemachine should have called transition "initmove", executed action with he id 9 and currentState should be 1 = "move"
delete event;
//send next event to stay in State1
//<!-- middle MouseButton and MouseMove -->
//<event NAME="middleBN+MouseMove" ID="533" TYPE="Type_MouseMove" BUTTON="BS_NoButton" BUTTONSTATE="0x0004" KEY="Key_none" />
event = new mitk::Event(NULL, mitk::Type_MouseMove, mitk::BS_NoButton, mitk::BS_MidButton, mitk::Key_none);
stateEvent->Set(533, event);
MITK_TEST_CONDITION_REQUIRED(interactor->HandleEvent(stateEvent),"Staying in State 1")
MITK_TEST_CONDITION_REQUIRED(interactor->GetMode() == mitk::Interactor::SMSELECTED,"Testing for the same Mode")
delete event;
//create a new event
//<!-- MiddleMouseButtonRelease -->
//<event NAME="MiddleMouseRelease" ID="506" TYPE="Type_MouseButtonRelease" BUTTON="BS_MidButton" BUTTONSTATE="0x0004" KEY="Key_none" />
event = new mitk::Event(NULL, mitk::Type_MouseButtonRelease, mitk::BS_MidButton, mitk::BS_MidButton, mitk::Key_none);
stateEvent->Set(506, event);
//because the statemachine is waiting for this event, 0.5 should be returned
float returnvalue = interactor->CanHandleEvent(stateEvent);
MITK_TEST_CONDITION_REQUIRED(returnvalue == 0.5,"Testing to call CanHandleEvent with next event")
std::cout<<"CanHandleEvent returned: "<<returnvalue<<std::endl;
//The transition "finish" should call no action an lead into state 0 = startState
MITK_TEST_CONDITION_REQUIRED(interactor->HandleEvent(stateEvent),"Testing to send next event leading back to startState0")
MITK_TEST_CONDITION_REQUIRED(interactor->GetMode() == mitk::Interactor::SMDESELECTED,"Testing right Mode and thus right action behavior")
delete event;
event = NULL;
stateEvent->Set(4, event);
MITK_TEST_CONDITION_REQUIRED(interactor->HandleEvent(stateEvent),"Testing to send event == NULL to interactor")
delete stateEvent;
stateEvent = NULL;
MITK_TEST_CONDITION_REQUIRED( ! interactor->HandleEvent(stateEvent),"Testing to send stateEvent == NULL to interactor")
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkLevelWindowManagerTest.cpp b/Core/Code/Testing/mitkLevelWindowManagerTest.cpp
index 228db7b90f..db725cc418 100644
--- a/Core/Code/Testing/mitkLevelWindowManagerTest.cpp
+++ b/Core/Code/Testing/mitkLevelWindowManagerTest.cpp
@@ -1,98 +1,97 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkLevelWindowManager.h"
#include "mitkStandaloneDataStorage.h"
int mitkLevelWindowManagerTest(int, char* [])
{
mitk::LevelWindowManager::Pointer manager;
std::cout << "Testing mitk::LevelWindowManager::New(): ";
manager = mitk::LevelWindowManager::New();
if (manager.IsNull())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating DataStorage: ";
mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindowManager SetDataStorage ";
manager->SetDataStorage(ds);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindowManager GetDataStorage ";
if (ds != manager->GetDataStorage())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindowManager SetLevelWindowProperty ";
mitk::LevelWindowProperty::Pointer levelWindowProperty = mitk::LevelWindowProperty::New();
manager->SetLevelWindowProperty(levelWindowProperty);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindowManager GetLevelWindowProperty ";
if (levelWindowProperty != manager->GetLevelWindowProperty())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindowManager isAutoTopMost ";
if (manager->isAutoTopMost())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindowManager GetLevelWindow ";
try
{
const mitk::LevelWindow levelWindow = manager->GetLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindowManager SetLevelWindow ";
manager->SetLevelWindow(levelWindow);
std::cout<<"[PASSED]"<<std::endl;
}
catch (...)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout << "Testing mitk::LevelWindowManager SetAutoTopMostImage ";
manager->SetAutoTopMostImage(true);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindowManager isAutoTopMost ";
if (!(manager->isAutoTopMost()))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkLevelWindowTest.cpp b/Core/Code/Testing/mitkLevelWindowTest.cpp
index f438aa8070..2efbdfe166 100644
--- a/Core/Code/Testing/mitkLevelWindowTest.cpp
+++ b/Core/Code/Testing/mitkLevelWindowTest.cpp
@@ -1,645 +1,644 @@
-/*=========================================================================
-
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
-
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
-This software is distributed WITHOUT ANY WARRANTY; without even
-the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the above copyright notices for more information.
-
-=========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkLevelWindow.h"
#include <mitkImage.h>
int mitkLevelWindowTest(int, char* [])
{
std::cout << "Testing mitk::LevelWindow "<<std::endl;
std::cout << "Testing mitk::LevelWindow constructor with Level and Window ";
mitk::LevelWindow* levWin = new mitk::LevelWindow(256, 500);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetDefaultWindow ";
mitk::ScalarType defaultWindow = levWin->GetDefaultWindow();
if (!(defaultWindow == 500))
{
std::cout<<(int)(defaultWindow) + "[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetDefaultLevel ";
mitk::ScalarType defaultLevel = levWin->GetDefaultLevel();
if (!(defaultLevel == 256))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetWindow ";
mitk::ScalarType window = levWin->GetWindow();
if (!(window == 500))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetMin ";
if (!(levWin->GetLowerWindowBound() == 6))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetMax ";
if (!(levWin->GetUpperWindowBound() == 506))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetLevel ";
mitk::ScalarType level = levWin->GetLevel();
if (!(level == 256))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetWindow : GetDefaultWindow ";
if (!(defaultWindow == window))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetLevel : GetDefaultLevel ";
if (!(defaultLevel == level))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetLevelWindow ";
levWin->SetLevelWindow(20, 100);
if (!(levWin->GetLevel() == 20))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
if (!(levWin->GetWindow() == 100))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetLevelWindow ";
levWin->SetLevelWindow(levWin->GetDefaultLevel(), levWin->GetDefaultWindow());
if (!(levWin->GetLevel() == 256) && !(levWin->GetWindow() == 500))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetDefaultLevelWindow ";
levWin->SetDefaultLevelWindow(20, 200);
if (!(levWin->GetDefaultLevel() == 20) && !(levWin->GetDefaultWindow() == 200))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow ResetDefaultLevelWindow ";
levWin->SetLevelWindow(100, 50);
levWin->ResetDefaultLevelWindow();
//double a = levWin->GetLevel();
//double d = levWin->GetWindow();
if (!((levWin->GetLevel() == 20) &&(levWin->GetWindow() == 200)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetWindowBounds ";
levWin->SetWindowBounds(0, 2);
if (!((levWin->GetLowerWindowBound() == 0) && (levWin->GetUpperWindowBound() == 2) && (levWin->GetLevel() == 1) && (levWin->GetWindow() == 2)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with rangemin = rangemax";
levWin->SetRangeMinMax(2000, 2000);
if (!(levWin->GetRangeMin() == 1999 && levWin->GetRangeMax() == 2000))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with rangemin > rangemax";
levWin->SetRangeMinMax(2100, 2000);
if (!(levWin->GetRangeMin() == 2000 && levWin->GetRangeMax() == 2100))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax ";
levWin->SetRangeMinMax(-1000, 2000);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetRangeMin ";
if (!(levWin->GetRangeMin() == -1000))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetRangeMax ";
if (!(levWin->GetRangeMax() == 2000))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetRange ";
if (!((levWin->GetRangeMax() - levWin->GetRangeMin()) == levWin->GetRange()))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetDefaultBoundaries with rangemin = rangemax";
levWin->SetDefaultBoundaries(2000, 2000);
if (!(levWin->GetDefaultLowerBound() == 1999 && levWin->GetDefaultUpperBound() == 2000))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetDefaultBoundaries with rangemin > rangemax";
levWin->SetDefaultBoundaries(2100, 2000);
if (!(levWin->GetDefaultLowerBound() == 2000 && levWin->GetDefaultUpperBound() == 2100))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetDefaultBoundaries ";
levWin->SetDefaultBoundaries(-2000, 8000);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetDefaultLowerBound ";
if (!(levWin->GetDefaultLowerBound() == -2000))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow GetDefaultUpperBound ";
if (!(levWin->GetDefaultUpperBound() == 8000))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow ResetDefaultRangeMinMax ";
levWin->ResetDefaultRangeMinMax();
if (!((levWin->GetRangeMin() == levWin->GetDefaultLowerBound()) && (levWin->GetRangeMax() == levWin->GetDefaultUpperBound())))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow minRange > maxRange ";
levWin->SetRangeMinMax(2000, 1000);
if (!((levWin->GetRangeMin() == 1000) && (levWin->GetRangeMax() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetRangeMinMax(2000, -1000);
if (!((levWin->GetRangeMin() == -1000) && (levWin->GetRangeMax() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetRangeMinMax(-2000, -3000);
if (!((levWin->GetRangeMin() == -3000) && (levWin->GetRangeMax() == -2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetRangeMinMax(0, -1000);
if (!((levWin->GetRangeMin() == -1000) && (levWin->GetRangeMax() == 0)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetRangeMinMax(2000, 0);
if (!((levWin->GetRangeMin() == 0) && (levWin->GetRangeMax() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetRangeMinMax(-10000, 10000);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow defaultMinRange > defaultMaxRange ";
levWin->SetDefaultBoundaries(2000, 1000);
if (!((levWin->GetDefaultLowerBound() == 1000) && (levWin->GetDefaultUpperBound() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetDefaultBoundaries(2000, -1000);
if (!((levWin->GetDefaultLowerBound() == -1000) && (levWin->GetDefaultUpperBound() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetDefaultBoundaries(-2000, -3000);
if (!((levWin->GetDefaultLowerBound() == -3000) && (levWin->GetDefaultUpperBound() == -2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetDefaultBoundaries(0, -1000);
if (!((levWin->GetDefaultLowerBound() == -1000) && (levWin->GetDefaultUpperBound() == 0)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetDefaultBoundaries(2000, 0);
if (!((levWin->GetDefaultLowerBound() == 0) && (levWin->GetDefaultUpperBound() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetDefaultBoundaries(-10000, 10000);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min > max ";
levWin->SetWindowBounds(2000, 1000);
if (!((levWin->GetLowerWindowBound() == 1000) && (levWin->GetUpperWindowBound() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetWindowBounds(2000, -1000);
if (!((levWin->GetLowerWindowBound() == -1000) && (levWin->GetUpperWindowBound() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetWindowBounds(-2000, -3000);
if (!((levWin->GetLowerWindowBound() == -3000) && (levWin->GetUpperWindowBound() == -2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetWindowBounds(0, -1000);
if (!((levWin->GetLowerWindowBound() == -1000) && (levWin->GetUpperWindowBound() == 0)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->SetWindowBounds(2000, 0);
if (!((levWin->GetLowerWindowBound() == 0) && (levWin->GetUpperWindowBound() == 2000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
//minmax > maxrange, minmax < minrange, min<maxrange & max >maxrange, min < minrange & max > minrange
// max < minrange & min > minrange, min > maxrange & max < maxrange, min < minrange & max > maxrange
// min > maxrange & max < minrange
std::cout << "Testing mitk::LevelWindow max > min > maxrange ";
levWin->SetWindowBounds(11000, 12000);
if (!((levWin->GetLowerWindowBound() == 9999) && (levWin->GetUpperWindowBound() == 10000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min > max > maxrange ";
levWin->SetWindowBounds(12000, 11000);
if (!((levWin->GetLowerWindowBound() == 9999) && (levWin->GetUpperWindowBound() == 10000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min < max < minrange ";
levWin->SetWindowBounds(-12000, -11000);
if (!((levWin->GetLowerWindowBound() == -10000) && (levWin->GetUpperWindowBound() == -9999)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow max < min < minrange ";
levWin->SetWindowBounds(-11000, -12000);
if (!((levWin->GetLowerWindowBound() == -10000) && (levWin->GetUpperWindowBound() == -9999)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min < maxrang & max > maxrange ";
levWin->SetWindowBounds(9999, 12000);
if (!((levWin->GetLowerWindowBound() == 9999) && (levWin->GetUpperWindowBound() == 10000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min < minrange & max > minrange ";
levWin->SetWindowBounds(-11000, -9999);
if (!((levWin->GetLowerWindowBound() == -10000) && (levWin->GetUpperWindowBound() == -9999)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min < minrange & max > maxrange ";
levWin->SetWindowBounds(-11000, 11000);
if (!((levWin->GetLowerWindowBound() == -10000) && (levWin->GetUpperWindowBound() == 10000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow maxrange > min = max > minrange ";
levWin->SetWindowBounds(5000, 5000);
if (!((levWin->GetLowerWindowBound() == 4999) && (levWin->GetUpperWindowBound() == 5000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min = max = minrange ";
levWin->SetWindowBounds(-10000, -10000);
if (!((levWin->GetLowerWindowBound() == -10000) && (levWin->GetUpperWindowBound() == -9999)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min = max = maxrange ";
levWin->SetWindowBounds(10000, 10000);
if (!((levWin->GetLowerWindowBound() == 9999) && (levWin->GetUpperWindowBound() == 10000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min = max > maxrange ";
levWin->SetWindowBounds(11000, 11000);
if (!((levWin->GetLowerWindowBound() == 9999) && (levWin->GetUpperWindowBound() == 10000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min = max < minrange ";
levWin->SetWindowBounds(-11000, -11000);
if (!((levWin->GetLowerWindowBound() == -10000) && (levWin->GetUpperWindowBound() == -9999)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow maxrange > min > minrange > max ";
levWin->SetWindowBounds(-9000, -11000);
if (!((levWin->GetLowerWindowBound() == -10000) && (levWin->GetUpperWindowBound() == -9000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow min > maxrange > minrange > max ";
levWin->SetWindowBounds(11000, -11000);
if (!((levWin->GetLowerWindowBound() == -10000) && (levWin->GetUpperWindowBound() == 10000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with maxrange < min < max ";
levWin->SetRangeMinMax(-20000, -15000);
if (!((levWin->GetLowerWindowBound() == -15001) && (levWin->GetUpperWindowBound() == -15000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with minrange > maxrange & maxrange < min < max ";
levWin->ResetDefaultLevelWindow();
levWin->SetRangeMinMax(-15000, -20000);
if (!((levWin->GetLowerWindowBound() == -15001) && (levWin->GetUpperWindowBound() == -15000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with minrange < min < maxrange < max ";
levWin->SetRangeMinMax(-80, 1000);
levWin->SetWindowBounds(-1000,110);
if (!((levWin->GetLowerWindowBound() == -80) && (levWin->GetUpperWindowBound() == 110)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with maxrange < minrange & minrange < min < maxrange < max ";
levWin->SetRangeMinMax(1000,-80);
levWin->SetWindowBounds(-1000,110);
if (!((levWin->GetLowerWindowBound() == -80) && (levWin->GetUpperWindowBound() == 110)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with min < minrange < maxrange <max ";
levWin->SetRangeMinMax(20, 110);
if (!((levWin->GetLowerWindowBound() == 20) && (levWin->GetUpperWindowBound() == 110)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with minRange > maxRange & min < maxrange < max ";
levWin->SetWindowBounds(-90,1000);
levWin->SetRangeMinMax(100, -80);
if (!((levWin->GetLowerWindowBound() == -80) && (levWin->GetUpperWindowBound() == 100)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with minRange > maxRange & min < minrange < maxrange <max ";
levWin->SetRangeMinMax(20, 100);
if (!((levWin->GetLowerWindowBound() == 20) && (levWin->GetUpperWindowBound() == 100)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with min < max < minrange ";
levWin->SetRangeMinMax(20000, 15000);
if (!((levWin->GetLowerWindowBound() == 15000) && (levWin->GetUpperWindowBound() == 15001)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with minrange > maxrange & min < max < minrange ";
levWin->SetRangeMinMax(20000, 15000);
if (!((levWin->GetLowerWindowBound() == 15000) && (levWin->GetUpperWindowBound() == 15001)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetRangeMinMax with min < minrange <max ";
levWin->SetRangeMinMax(-20000, -15000);
if (!((levWin->GetLowerWindowBound() == -15001) && (levWin->GetUpperWindowBound() == -15000)))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
levWin->ResetDefaultRangeMinMax();
levWin->ResetDefaultLevelWindow();
std::cout<<"[PASSED]"<<std::endl;
// auch für default levelwindow und default range
//Create Image out of nowhere
mitk::Image::Pointer image;
//mitk::PixelType pt(typeid(int));
unsigned int dim[]={100,100,20};
std::cout << "Creating image: ";
image = mitk::Image::New();
//image->DebugOn();
image->Initialize( mitk::MakePixelType<int, int, 1>(), 3, dim);
int *p = (int*)image->GetData();
int size = dim[0]*dim[1]*dim[2];
int i;
for(i=0; i<size; ++i, ++p)
*p=i;
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow SetAuto ";
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( image );
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow constructor with mitkLevelWindow ";
const mitk::LevelWindow* lw = new mitk::LevelWindow(levelwindow);
if (!(lw->GetRange() == levelwindow.GetRange()))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mitk::LevelWindow destructor ";
delete levWin;
delete lw;
std::cout<<"[PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkLookupTableTest.cpp b/Core/Code/Testing/mitkLookupTableTest.cpp
index 966ed23c50..9ea74b2358 100644
--- a/Core/Code/Testing/mitkLookupTableTest.cpp
+++ b/Core/Code/Testing/mitkLookupTableTest.cpp
@@ -1,80 +1,79 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-05-12 19:14:45 +0200 (Tue, 12 May 2009) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkLookupTable.h>
#include "mitkTestingMacros.h"
#include <iostream>
/**
* Simple example for a test for the (non-existent) class "ClassName".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkLookupTableTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("LookupTable")
// let's create an object of our class
mitk::LookupTable::Pointer myLookupTable = mitk::LookupTable::New();
// create a vtkLookupTable and add two values
vtkLookupTable *lut = vtkLookupTable::New();
lut->SetTableValue(0, 0.5, 0.5, 0.5, 1.0);
lut->SetTableValue(0, 0.5, 0.5, 0.5, 0.5);
myLookupTable->SetVtkLookupTable(lut);
// check if the same lookuptable is returned
vtkLookupTable *lut2 = myLookupTable->GetVtkLookupTable();
MITK_TEST_CONDITION_REQUIRED(lut == lut2,"Input and output table are not equal")
myLookupTable->ChangeOpacityForAll(0.5);
myLookupTable->ChangeOpacityForAll(0.5);
myLookupTable->ChangeOpacity(0, 1.0);
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
MITK_TEST_CONDITION_REQUIRED(myLookupTable.IsNotNull(),"Testing instantiation")
// write your own tests here and use the macros from mitkTestingMacros.h !!!
// do not write to std::cout and do not return from this function yourself!
lut->Delete();
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkMaterialTest.cpp b/Core/Code/Testing/mitkMaterialTest.cpp
index f59dc2831c..c0b47cece3 100644
--- a/Core/Code/Testing/mitkMaterialTest.cpp
+++ b/Core/Code/Testing/mitkMaterialTest.cpp
@@ -1,384 +1,383 @@
-/*=========================================================================
+/*===================================================================
- Program: Medical Imaging & Interaction Toolkit
- Language: C++
- Date: $Date$
- Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
- Copyright () German Cancer Research Center, Division of Medical and
- Biological Informatics. All rights reserved.
- See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkMaterial.h"
#include "mitkBaseProperty.h"
#include "mitkBaseRenderer.h"
#include "mitkTestingMacros.h"
#include "mitkDataNode.h"
#include <mitkVtkPropRenderer.h>
#include <mitkColorProperty.h>
#include <iostream>
/**
* Simple example for a test for the () class "ClassName".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests ().
*/
class MaterialTest
{
public:
mitk::Material::Pointer myMP;
MaterialTest(){myMP = NULL;}
void testConstructor()
{
myMP = mitk::Material::New();
MITK_TEST_CONDITION_REQUIRED(myMP.IsNotNull(),"Testing instantiation")
}
void testConstructorWithColorOpacity()
{
mitk::Color color;
color.Set(0, 0, 0);
vtkFloatingPointType opacity = 1.0f;
myMP = mitk::Material::New(color, opacity);
MITK_TEST_CONDITION_REQUIRED(myMP.IsNotNull(),"Testing instantiation")
MITK_TEST_CONDITION( color==myMP->GetColor(), "Testing if a Color object was set correctly" )
MITK_TEST_CONDITION( opacity==myMP->GetOpacity(), "Testing if a Opacity object was set correctly" )
}
void testConstructorWithRedGreenBlueOpacity()
{
mitk::Material::Color color;
color.Set(0, 0, 0);
vtkFloatingPointType opacity = 1.0f;
vtkFloatingPointType rgb = 0;
myMP = mitk::Material::New(rgb, rgb, rgb, opacity);
MITK_TEST_CONDITION_REQUIRED(myMP.IsNotNull(),"Testing instantiation")
MITK_TEST_CONDITION( color==myMP->GetColor(), "Testing if a Color object was set correctly" )
MITK_TEST_CONDITION( opacity==myMP->GetOpacity(), "Testing if a Opacity object was set correctly" )
}
void testConstructorRedGreenBlueColorCoefficientSpecularCoefficientSpecularPowerOpacity()
{
mitk::Material::Color color;
color.Set(0, 0, 0);
vtkFloatingPointType opacity = 1.0f;
vtkFloatingPointType rgb = 0;
vtkFloatingPointType colorCoefficient = 0;
vtkFloatingPointType specularCoefficient = 0;
vtkFloatingPointType specularPower = 0;
myMP = mitk::Material::New(rgb, rgb, rgb, colorCoefficient,
specularCoefficient, specularPower, opacity);
MITK_TEST_CONDITION_REQUIRED(myMP.IsNotNull(),"Testing instantiation")
MITK_TEST_CONDITION( color==myMP->GetColor(), "Testing if a Color object was set correctly" )
MITK_TEST_CONDITION( opacity==myMP->GetOpacity(), "Testing if a Opacity object was set correctly" )
MITK_TEST_CONDITION( specularCoefficient==myMP->GetSpecularCoefficient(), "Testing if a Coefficient object was set correctly" )
MITK_TEST_CONDITION( specularPower==myMP->GetSpecularPower(), "Testing if a SpecularPower object was set correctly" )
MITK_TEST_CONDITION( colorCoefficient==myMP->GetColorCoefficient(), "Testing if a colorCoefficient object was set correctly" )
}
void testConstructorColorColorCoefficientSpecularCoefficientSpecularPowerOpacity()
{
mitk::Material::Color color;
color.Set(0, 0, 0);
vtkFloatingPointType opacity = 1.0f;
vtkFloatingPointType rgb = 0;
vtkFloatingPointType colorCoefficient = 0;
vtkFloatingPointType specularCoefficient = 0;
vtkFloatingPointType specularPower = 0;
myMP = mitk::Material::New(rgb, rgb, rgb, colorCoefficient,
specularCoefficient, specularPower, opacity);
MITK_TEST_CONDITION_REQUIRED(myMP.IsNotNull(),"Testing instantiation")
MITK_TEST_CONDITION( color==myMP->GetColor(), "Testing if a Color object was set correctly" )
MITK_TEST_CONDITION( opacity==myMP->GetOpacity(), "Testing if a Opacity object was set correctly" )
MITK_TEST_CONDITION( specularCoefficient==myMP->GetSpecularCoefficient(), "Testing if a Coefficient object was set correctly" )
MITK_TEST_CONDITION( specularPower==myMP->GetSpecularPower(), "Testing if a SpecularPower object was set correctly" )
}
void testConstructorPropertyRedGreenBlueOpacityAndName()
{
mitk::Material::Pointer reference = myMP;
vtkFloatingPointType opacity = 1.0f;
vtkFloatingPointType rgb = 0;
std::string name = "Hans Wurst";
myMP = mitk::Material::New(*reference, rgb, rgb, rgb, opacity, name);
MITK_TEST_CONDITION_REQUIRED(myMP.IsNotNull(),"Testing instantiation")
MITK_TEST_CONDITION( opacity==myMP->GetOpacity(), "Testing if a Opacity object was set correctly" )
//MITK_TEST_CONDITION( name.compare(myMP->GetName(),0,9), "Testing if a Name object was set correctly" )
}
void testSetColor()
{
mitk::Material::Color color;
color.Set(0,0,0);
myMP = mitk::Material::New();
myMP->SetColor(color);
MITK_TEST_CONDITION_REQUIRED(myMP.IsNotNull(),"Testing instantiation")
MITK_TEST_CONDITION(color==myMP->GetColor(),"Testing if a color was set correctly")
color.Set(0,0,0);
myMP->SetColor(color);
MITK_TEST_CONDITION(color==myMP->GetColor(),"Testing if a color was set correctly")
}
void testSetColorCoefficient()
{
vtkFloatingPointType colorCoefficient = 0;
myMP = mitk::Material::New();
myMP->SetColorCoefficient(colorCoefficient);
MITK_TEST_CONDITION(colorCoefficient == myMP->GetColorCoefficient(), "Testing if a colorcoefficent was set correctly")
}
void testSetSpecularColor()
{
mitk::Material::Color color;
color.Set(0,0,0);
myMP = mitk::Material::New();
myMP->SetSpecularColor(color);
MITK_TEST_CONDITION(color == myMP->GetSpecularColor(),"Testing if a SpecularColor was set correctly")
}
void testSetSpecularCoefficient()
{
myMP = mitk::Material::New();
vtkFloatingPointType specularCoefficient = 1;
myMP->SetSpecularCoefficient(specularCoefficient);
MITK_TEST_CONDITION(specularCoefficient == myMP->GetSpecularCoefficient(),"Testing if a SpecularCoefficient was set correctly")
}
void testSetSpecularPower()
{
myMP = mitk::Material::New();
vtkFloatingPointType specularPower = 1;
myMP->SetSpecularPower(specularPower);
MITK_TEST_CONDITION(specularPower==myMP->GetSpecularPower(), "Testing if a SpecularPower was set correctly")
}
void testSetOpacity()
{
myMP = mitk::Material::New();
vtkFloatingPointType opacity = 1;
myMP->SetOpacity(opacity);
MITK_TEST_CONDITION(opacity==myMP->GetOpacity(), "Testing if a Opacity was set correctly")
}
void testSetInterpolation()
{
myMP = mitk::Material::New();
mitk::Material::InterpolationType interpolation = mitk::Material::Flat;
myMP->SetInterpolation(interpolation);
MITK_TEST_CONDITION(interpolation == myMP->GetInterpolation(), "Testing if a Interpolation was set correctly")
}
void testSetRepresentation()
{
myMP = mitk::Material::New();
mitk::Material::RepresentationType representation = mitk::Material::Wireframe;
myMP->SetRepresentation(representation);
MITK_TEST_CONDITION(representation == myMP->GetRepresentation(), "Testing if a Representation was set correctly")
}
void testSetLineWidth()
{
myMP = mitk::Material::New();
vtkFloatingPointType lineWidth = 1;
myMP->SetLineWidth(lineWidth);
MITK_TEST_CONDITION(lineWidth==myMP->GetLineWidth(), "Testing if a LineWidth was set correctly")
}
void testInitialize()
{
mitk::Material::Color color;
color.Set(0, 0, 0);
vtkFloatingPointType opacity = 1.0f;
vtkFloatingPointType rgb = 0;
vtkFloatingPointType colorCoefficient = 0;
vtkFloatingPointType specularCoefficient = 0;
vtkFloatingPointType specularPower = 0;
myMP = mitk::Material::New(rgb, rgb, rgb, colorCoefficient,
specularCoefficient, specularPower, opacity);
vtkFloatingPointType lineWidth = 1;
myMP->SetLineWidth(lineWidth);
mitk::Material::RepresentationType representation = mitk::Material::Wireframe;
myMP->SetRepresentation(representation);mitk::Material::InterpolationType interpolation = mitk::Material::Flat;
myMP->SetInterpolation(interpolation);
myMP->SetSpecularColor(color);
std::string name = "Hans Wurst";
myMP->SetName(name);
mitk::Material::Pointer myMP2 = mitk::Material::New();
myMP2->Initialize(*myMP);
MITK_TEST_CONDITION(*myMP == *myMP2, "testing equality after .Intitialize")
}
void testOperatorequality()
{
{
mitk::Material::Color color;
color.Set(0, 0, 0);
vtkFloatingPointType opacity = 1.0f;
vtkFloatingPointType rgb = 0;
vtkFloatingPointType colorCoefficient = 0;
vtkFloatingPointType specularCoefficient = 0;
vtkFloatingPointType specularPower = 0;
myMP = mitk::Material::New(rgb, rgb, rgb, colorCoefficient,
specularCoefficient, specularPower, opacity);
vtkFloatingPointType lineWidth = 1;
myMP->SetLineWidth(lineWidth);
mitk::Material::RepresentationType representation = mitk::Material::Wireframe;
myMP->SetRepresentation(representation);mitk::Material::InterpolationType interpolation = mitk::Material::Flat;
myMP->SetInterpolation(interpolation);
myMP->SetSpecularColor(color);
std::string name = "Hans Wurst";
myMP->SetName(name);
mitk::Material::Color color2;
color2.Set(0, 0, 0);
vtkFloatingPointType opacity2 = 1.0f;
vtkFloatingPointType rgb2 = 0;
vtkFloatingPointType colorCoefficient2 = 0;
vtkFloatingPointType specularCoefficient2 = 0;
vtkFloatingPointType specularPower2 = 0;
mitk::Material::Pointer myMP2 = mitk::Material::New(rgb2, rgb2, rgb2, colorCoefficient2,
specularCoefficient2, specularPower2, opacity2);
vtkFloatingPointType lineWidth2 = 1;
myMP2->SetLineWidth(lineWidth2);
mitk::Material::RepresentationType representation2 = mitk::Material::Wireframe;
myMP2->SetRepresentation(representation2);
mitk::Material::InterpolationType interpolation2 = mitk::Material::Flat;
myMP2->SetInterpolation(interpolation2);
myMP2->SetSpecularColor(color2);
std::string name2 = "Hans Wurst";
myMP2->SetName(name2);
MITK_TEST_CONDITION(*myMP == *myMP2, "testing equality Operator")
}
{
mitk::Material::Color color;
color.Set(0, 0, 0);
vtkFloatingPointType opacity = 1.0f;
vtkFloatingPointType rgb = 0;
vtkFloatingPointType colorCoefficient = 0;
vtkFloatingPointType specularCoefficient = 0;
vtkFloatingPointType specularPower = 0;
myMP = mitk::Material::New(rgb, rgb, rgb, colorCoefficient,
specularCoefficient, specularPower, opacity);
vtkFloatingPointType lineWidth = 1;
myMP->SetLineWidth(lineWidth);
mitk::Material::RepresentationType representation = mitk::Material::Wireframe;
myMP->SetRepresentation(representation);mitk::Material::InterpolationType interpolation = mitk::Material::Flat;
myMP->SetInterpolation(interpolation);
myMP->SetSpecularColor(color);
std::string name = "Hans Wurst";
myMP->SetName(name);
mitk::Material::Color color2;
color2.Set(0, 0, 0);
vtkFloatingPointType opacity2 = 1.0f;
vtkFloatingPointType rgb2 = 1;
vtkFloatingPointType colorCoefficient2 = 0;
vtkFloatingPointType specularCoefficient2 = 0;
vtkFloatingPointType specularPower2 = 0;
mitk::Material::Pointer myMP2 = mitk::Material::New(rgb2, rgb2, rgb2, colorCoefficient2,
specularCoefficient2, specularPower2, opacity2);
vtkFloatingPointType lineWidth2 = 1;
myMP2->SetLineWidth(lineWidth2);
mitk::Material::RepresentationType representation2 = mitk::Material::Wireframe;
myMP2->SetRepresentation(representation2);
mitk::Material::InterpolationType interpolation2 = mitk::Material::Flat;
myMP2->SetInterpolation(interpolation2);
myMP2->SetSpecularColor(color2);
std::string name2 = "Hans Wurst";
myMP2->SetName(name2);
MITK_TEST_CONDITION(!(*myMP == *myMP2), "testing equality Operator")
}
}
void testAssignable()
{
mitk::Material::Pointer materialProp = mitk::Material::New();
MITK_TEST_CONDITION(myMP->Assignable(*materialProp),"testing Assignable with Material" )
}
void testOperatorAssign()
{
mitk::Material::Pointer myMP2 = mitk::Material::New();
*myMP2 = *myMP;
MITK_TEST_CONDITION(*myMP == *myMP2, "Testing Assignment Operator")
}
};
int
mitkMaterialTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("Material")
MaterialTest materialTest;
materialTest.testConstructor();
materialTest.testConstructorWithColorOpacity();
materialTest.testConstructorWithRedGreenBlueOpacity();
materialTest.testConstructorRedGreenBlueColorCoefficientSpecularCoefficientSpecularPowerOpacity();
materialTest.testConstructorColorColorCoefficientSpecularCoefficientSpecularPowerOpacity();
materialTest.testConstructorPropertyRedGreenBlueOpacityAndName();
materialTest.testAssignable();
materialTest.testOperatorAssign();
materialTest.testSetColor();
materialTest.testSetColorCoefficient();
materialTest.testSetSpecularColor();
materialTest.testSetSpecularCoefficient();
materialTest.testSetSpecularPower();
materialTest.testSetOpacity();
materialTest.testSetInterpolation();
materialTest.testSetRepresentation();
materialTest.testSetLineWidth();
materialTest.testInitialize();
materialTest.testOperatorequality();
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
// write your own tests here and use the macros from mitkTestingMacros.h !!!
// do not write to std::cout and do not return from this function yourself!
// always end with this!
MITK_TEST_END ()
}
diff --git a/Core/Code/Testing/mitkMessageTest.cpp b/Core/Code/Testing/mitkMessageTest.cpp
index 4ba950fe22..a488bc8200 100644
--- a/Core/Code/Testing/mitkMessageTest.cpp
+++ b/Core/Code/Testing/mitkMessageTest.cpp
@@ -1,416 +1,415 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 1.12 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkMessage.h"
#include "mitkTestingMacros.h"
#include <iostream>
namespace mitk
{
class mitkMessageTestTestClass
{
public:
// dummy class to send around
class Package
{
public:
Package(int content = 43)
:m_Content(content)
{
}
void Clear()
{
m_Content = 0;
}
bool operator==(const Package& other)
{
return m_Content == other.m_Content;
}
private:
int m_Content;
};
class MessageSenderClass
{
public:
// message without any parameters, pure notification
Message<> WaveHand;
// message without any parameters, pure notification
Message<> ShowFinger;
// message with one parameter of type std::string
Message1<const std::string&> Say;
// message with one parameter of type double
Message1<double> WalkMeters;
// message with one parameter of class type Package
Message1<const Package&> GivePackage;
// message with two parameters of type int and float
Message2<int, float> ShoutAgeAndFootSize;
void DoShowFinger()
{
ShowFinger.Send();
// ShowFinger() does the same
}
void DoWaveHand()
{
WaveHand();
// WaveHand.Send() does the same
}
void DoSay(const std::string& words)
{
Say(words);
}
void DoWalk(double meters)
{
WalkMeters(meters);
}
void DoGivePackage(const Package& package)
{
GivePackage.Send(package);
}
void DoShoutAgeAndFootSize(int age, float size)
{
ShoutAgeAndFootSize(age, size);
}
};
// Receiver class remembers events received.
// Will tell about received events when asked.
class MessageReceiverClass
{
public:
MessageReceiverClass()
{
Amnesia();
}
void OnWaveHand()
{
m_HandWaved = true;
}
bool HandWaved()
{
return m_HandWaved;
}
void OnSay(const std::string& words)
{
m_WordsSaid = words;
}
const std::string WordsSaid()
{
return m_WordsSaid;
}
void OnWalk(double meters)
{
m_MetersWalked = meters;
}
double MetersWalked()
{
return m_MetersWalked;
}
void OnGivePackage(const Package& p)
{
m_PackageReceived = p;
}
Package PackageReceived()
{
return m_PackageReceived;
}
void OnShoutAgeAndFootSize(int age, float footSize)
{
m_Age = age;
m_FootSize = footSize;
}
int Age()
{
return m_Age;
}
float FootSize()
{
return m_FootSize;
}
void Amnesia()
{
m_HandWaved = false;
m_WordsSaid.clear();
m_MetersWalked = 0.0;
m_PackageReceived.Clear();
m_Age = 0;
m_FootSize = 0.0;
}
void RegisterObservers(MessageSenderClass& sender)
{
sender.WaveHand += MessageDelegate<MessageReceiverClass>( this, &MessageReceiverClass::OnWaveHand );
sender.ShowFinger += MessageDelegate<MessageReceiverClass>( this, &MessageReceiverClass::OnWaveHand ); // we cannot see clearly, misinterpret this
sender.Say += MessageDelegate1<MessageReceiverClass, const std::string&>( this, &MessageReceiverClass::OnSay );
sender.WalkMeters += MessageDelegate1<MessageReceiverClass, double>( this, &MessageReceiverClass::OnWalk );
sender.GivePackage += MessageDelegate1<MessageReceiverClass, const Package&>( this, &MessageReceiverClass::OnGivePackage );
sender.ShoutAgeAndFootSize += MessageDelegate2<MessageReceiverClass, int, float>( this, &MessageReceiverClass::OnShoutAgeAndFootSize );
}
private:
bool m_HandWaved;
std::string m_WordsSaid;
double m_MetersWalked;
Package m_PackageReceived;
int m_Age;
float m_FootSize;
};
/* MessageMacro Test classes */
class Law
{
private:
std::string m_Description;
public:
Law(const std::string law) : m_Description(law)
{ }
std::string GetDescription() const
{
return m_Description;
}
};
// The NewtonMachine will issue specific events
class NewtonMachine
{
mitkNewMessageMacro(AnalysisStarted);
mitkNewMessage1Macro(AnalysisStopped, bool);
mitkNewMessage1Macro(LawDiscovered, const Law&);
//mitkNewMessageWithReturnMacro(PatentFiled, bool);
public:
void StartAnalysis()
{
// send the "started" signal
m_AnalysisStartedMessage();
// we found a new law of nature by creating one :-)
Law massLaw("Unit tests are mandatory!");
m_LawDiscoveredMessage(massLaw);
}
void StopAnalysis()
{
// send the "stop" message with true, indicating
// that an error occurred
m_AnalysisStoppedMessage(true);
}
bool PatentLaw()
{
//bool patentAccepted = m_PatentFiledMessage();
//return patentAccepted;
//m_PatentFiledMessage();
return false;
}
};
class Observer
{
private:
NewtonMachine* m_Machine;
public:
Observer(NewtonMachine* machine) :
m_Machine(machine), m_MachineStarted(false), m_MachineStopped(false),
m_Error(false), m_Law("NONE")
{
// Add "observers", i.e. function pointers to the machine
m_Machine->AddAnalysisStartedListener(
::mitk::MessageDelegate<Observer>(this, &Observer::MachineStarted));
m_Machine->AddAnalysisStoppedListener(
::mitk::MessageDelegate1<Observer, bool>(this, &Observer::MachineStopped));
m_Machine->AddLawDiscoveredListener(
::mitk::MessageDelegate1<Observer, const Law&>(this, &Observer::LawDiscovered));
//m_Machine->AddPatentFiledListener(
// ::mitk::MessageDelegate<Observer>(this, &Observer::ReviewPatent));
}
~Observer()
{
// Always remove your observers when finished
m_Machine->RemoveAnalysisStartedListener(
::mitk::MessageDelegate<Observer>(this, &Observer::MachineStarted));
m_Machine->RemoveAnalysisStoppedListener(
::mitk::MessageDelegate1<Observer, bool>(this, &Observer::MachineStopped));
m_Machine->RemoveLawDiscoveredListener(
::mitk::MessageDelegate1<Observer, const Law&>(this, &Observer::LawDiscovered));
//m_Machine->RemoveLawDiscoveredListener(
// ::mitk::MessageDelegate<Observer>(this, &Observer::ReviewPatent));
}
void MachineStarted()
{
m_MachineStarted = true;
}
void MachineStopped(bool error)
{
m_MachineStopped = true;
m_Error = error;
}
void LawDiscovered(const Law& law)
{
m_Law = law;
}
bool ReviewPatent()
{
m_PatentReviewed = true;
return false; // laws of nature are not patentable.
}
bool m_MachineStarted;
bool m_MachineStopped;
bool m_Error;
Law m_Law;
bool m_PatentReviewed;
};
}; // end test class
} // end namespace
int mitkMessageTest(int /* argc */, char* /*argv*/[])
{
MITK_TEST_BEGIN("Message")
mitk::mitkMessageTestTestClass::MessageSenderClass sender;
mitk::mitkMessageTestTestClass::MessageReceiverClass receiver;
MITK_TEST_CONDITION_REQUIRED(true, "Testing instantiation");
receiver.RegisterObservers(sender);
MITK_TEST_CONDITION_REQUIRED(true, "Testing registration to messages");
MITK_TEST_CONDITION_REQUIRED(
(sender.DoWaveHand(), // This is called "comma operator". Don't ask, read!
receiver.HandWaved()),
"Message without parameters");
receiver.Amnesia();
MITK_TEST_CONDITION_REQUIRED(
(sender.DoShowFinger(),
receiver.HandWaved()),
"Message without parameters");
receiver.Amnesia();
MITK_TEST_CONDITION_REQUIRED(
(sender.DoSay("Blooodworsch"),
receiver.WordsSaid() == "Blooodworsch"),
"Message with std::string parameter");
receiver.Amnesia();
MITK_TEST_CONDITION_REQUIRED(
(sender.DoWalk(2.67),
(receiver.MetersWalked() - 2.67) < 0.0001 ),
"Message with double parameter");
receiver.Amnesia();
mitk::mitkMessageTestTestClass::Package package(8);
MITK_TEST_CONDITION_REQUIRED(
(sender.DoGivePackage(package),
receiver.PackageReceived() == package),
"Message with class parameter");
receiver.Amnesia();
MITK_TEST_CONDITION_REQUIRED(
(sender.DoShoutAgeAndFootSize(46, 30.5),
(receiver.Age() == 46 && (receiver.FootSize() - 30.5 < 0.0001))),
"Message with int AND float parameter");
receiver.Amnesia();
mitk::mitkMessageTestTestClass::NewtonMachine newtonMachine;
mitk::mitkMessageTestTestClass::Observer observer1(&newtonMachine);
mitk::mitkMessageTestTestClass::Observer observer2(&newtonMachine);
// This will send two events to registered observers
newtonMachine.StartAnalysis();
MITK_TEST_CONDITION(observer1.m_MachineStarted == true, "Message from Message Macro send to receiver 1");
MITK_TEST_CONDITION(observer2.m_MachineStarted == true, "Message from Message Macro send to receiver 2");
MITK_TEST_CONDITION(observer1.m_Law.GetDescription() == std::string("Unit tests are mandatory!"),
"Message1 from Message Macro send to receiver 1");
MITK_TEST_CONDITION(observer2.m_Law.GetDescription() == std::string("Unit tests are mandatory!"),
"Message1 from Message Macro send to receiver 2");
// This will send one event to registered observers
newtonMachine.StopAnalysis();
MITK_TEST_CONDITION(observer1.m_MachineStopped == true, "Message1 from Message Macro send to receiver 1");
MITK_TEST_CONDITION(observer1.m_Error == true, "Message1 parameter from Message Macro send to receiver 1");
MITK_TEST_CONDITION(observer2.m_MachineStopped == true, "Message1 from Message Macro send to receiver 2");
MITK_TEST_CONDITION(observer2.m_Error == true, "Message1 parameter from Message Macro send to receiver 2");
/* Message with return type tests are work in progess... */
//bool patentSuccessful = newtonMachine.PatentLaw(); // what with return types from multiple observers?
//MITK_TEST_CONDITION((observer1.m_PatentReviewed == true) && (patentSuccessful == false),
// "Message with return type from Message Macro send to receiver 1");
//
//MITK_TEST_CONDITION((observer2.m_PatentReviewed == true) && (patentSuccessful == false),
// "Message with return type from Message Macro send to receiver 2");
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkNodeDependentPointSetInteractorTest.cpp b/Core/Code/Testing/mitkNodeDependentPointSetInteractorTest.cpp
index edc9284ff4..b2ef2e079c 100644
--- a/Core/Code/Testing/mitkNodeDependentPointSetInteractorTest.cpp
+++ b/Core/Code/Testing/mitkNodeDependentPointSetInteractorTest.cpp
@@ -1,204 +1,203 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-05-03 12:55:29 +0200 (Mo, 03 Mai 2010) $
-Version: $Revision: 22655 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodeDepententPointSetInteractor.h"
#include "mitkPointSet.h"
#include "mitkPositionEvent.h"
#include "mitkVtkPropRenderer.h"
#include "mitkStateEvent.h"
#include "mitkInteractionConst.h"
#include "mitkGlobalInteraction.h"
#include "mitkPointOperation.h"
#include "mitkTestingMacros.h"
#include "mitkStandaloneDataStorage.h"
#include "mitkDataNodeFactory.h"
#include "mitkStandardFileLocations.h"
#include "mitkNodePredicateDataType.h"
void SendPositionEvent(mitk::BaseRenderer* sender, int type, int button, int buttonState, int key, const mitk::Point2D& displPosition, const mitk::Point3D& worldPosition)
{
mitk::Event *posEvent = new mitk::PositionEvent(sender, type, button, buttonState, key, displPosition, worldPosition);
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(posEvent);
delete posEvent;
}
//test related to tutorial Step5.cpp
int mitkNodeDependentPointSetInteractorTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("NodeDependentPointSetInteractor");
// Global interaction must(!) be initialized if used
mitk::GlobalInteraction::GetInstance()->Initialize("global");
// Create a DataStorage
mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New();
MITK_TEST_CONDITION_REQUIRED(ds.IsNotNull(),"Instantiating DataStorage");
//read two images and store to datastorage
//these two images are used as node the interactors depend on. If the visibility property of one node if false, the
//associated interactor may not change the data
mitk::DataNode::Pointer node1, node2;
mitk::DataNodeFactory::Pointer nodeReader = mitk::DataNodeFactory::New();
MITK_TEST_CONDITION_REQUIRED(argc >= 3, "Test if a files to load has been specified");
try
{
//file 1
const std::string filename1 = argv[1];
nodeReader->SetFileName(filename1);
nodeReader->Update();
node1 = nodeReader->GetOutput();
ds->Add(node1);
//file 2
const std::string filename2 = argv[2];
nodeReader->SetFileName(filename2);
nodeReader->Update();
node2 = nodeReader->GetOutput();
ds->Add(node2);
}
catch(...) {
MITK_TEST_FAILED_MSG(<< "Could not read file for testing");
return EXIT_FAILURE;
}
//check for the two images
mitk::NodePredicateDataType::Pointer predicate(mitk::NodePredicateDataType::New("Image"));
mitk::DataStorage::SetOfObjects::ConstPointer allImagesInDS = ds->GetSubset(predicate);
MITK_TEST_CONDITION_REQUIRED(allImagesInDS->Size()==2,"load images to data storage");
// Create PointSet and a node for it
mitk::PointSet::Pointer pointSet1 = mitk::PointSet::New();
mitk::DataNode::Pointer pointSetNode1 = mitk::DataNode::New();
pointSetNode1->AddProperty( "unselectedcolor", mitk::ColorProperty::New(0.0f, 1.0f, 0.0f));
pointSetNode1->SetData(pointSet1);
mitk::NodeDepententPointSetInteractor::Pointer interactor1 = mitk::NodeDepententPointSetInteractor::New("pointsetinteractor", pointSetNode1, node1);
MITK_TEST_CONDITION_REQUIRED(interactor1.IsNotNull(),"Instanciating NodeDependentPointSetInteractor");
// Add the node to the tree
ds->Add(pointSetNode1);
mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor1);
mitk::PointSet::Pointer pointSet2 = mitk::PointSet::New();
mitk::DataNode::Pointer pointSetNode2 = mitk::DataNode::New();
pointSetNode2->AddProperty( "unselectedcolor", mitk::ColorProperty::New(0.0f, 0.0f, 1.0f));
pointSetNode2->SetData(pointSet2);
mitk::NodeDepententPointSetInteractor::Pointer interactor2 = mitk::NodeDepententPointSetInteractor::New("pointsetinteractor", pointSetNode2, node2);
MITK_TEST_CONDITION_REQUIRED(interactor2.IsNotNull(),"Instanciating NodeDependentPointSetInteractor");
// Add the node to the tree
ds->Add(pointSetNode2);
mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor2);
//check for the two pointsets
mitk::NodePredicateDataType::Pointer predicatePS(mitk::NodePredicateDataType::New("PointSet"));
mitk::DataStorage::SetOfObjects::ConstPointer allImagesInDSPS = ds->GetSubset(predicatePS);
MITK_TEST_CONDITION_REQUIRED(allImagesInDSPS->Size()==2,"create associated pointsets to data storage");
//create two RenderWindows
mitk::RenderingManager::Pointer myRenderingManager = mitk::RenderingManager::New();
vtkRenderWindow* vtkRenWin1 = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer br1 = mitk::VtkPropRenderer::New("testingBR", vtkRenWin1, myRenderingManager);
mitk::BaseRenderer::AddInstance(vtkRenWin1,br1);
myRenderingManager->AddRenderWindow(vtkRenWin1);
mitk::BaseRenderer::Pointer renderer1 = mitk::BaseRenderer::GetInstance(vtkRenWin1);
vtkRenderWindow* vtkRenWin2 = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer br2 = mitk::VtkPropRenderer::New("testingBR", vtkRenWin2, myRenderingManager);
mitk::BaseRenderer::AddInstance(vtkRenWin2,br2);
myRenderingManager->AddRenderWindow(vtkRenWin2);
mitk::BaseRenderer::Pointer renderer2 = mitk::BaseRenderer::GetInstance(vtkRenWin2);
//set properties for renderWindow 1 and 2
//1:
node1->SetBoolProperty("visible", true, renderer1);
node2->SetBoolProperty("visible", false, renderer1);
//2:
node1->SetBoolProperty("visible", false, renderer2);
node2->SetBoolProperty("visible", true, renderer2);
//***************************************************
//now start to test if only an event send from renderwindow 1 can interact with interactor 1 and vice versa
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==0,"Checking empty pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==0,"Checking empty pointset 2.");
//sending an event to interactor1
mitk::Point3D pos3D;
mitk::Point2D pos2D;
pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
pos2D[0]= 100; pos2D[0]= 200;
//add to pointset 1
SendPositionEvent(renderer1, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==1,"1 Checking addition of point to pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==0,"2 Checking empty pointset 2");
//add to pointset 2
SendPositionEvent(renderer2, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==1,"3 Checking untouched state of pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==1,"4 Checking addition of point to pointset 2");
//add to pointset 2
SendPositionEvent(renderer2, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==1,"5 Checking untouched state of pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==2,"6 Checking addition of point to pointset 2");
//add to pointset 2
SendPositionEvent(renderer2, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==1,"7 Checking untouched state of pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==3,"8 Checking addition of point to pointset 2");
//add to pointset 1
SendPositionEvent(renderer1, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==2,"9 Checking addition of point to pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==3,"10 Checking untouched state of pointset 2");
//trying to delete points
mitk::Event* delEvent1 = new mitk::Event(renderer1, mitk::Type_KeyPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_Delete);
mitk::Event* delEvent2 = new mitk::Event(renderer2, mitk::Type_KeyPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_Delete);
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent2);
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==2,"11 Checking untouched state of pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==2,"12 Checking detected point in pointset 2");
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent1);
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==1,"11 Checking deleted point in pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==2,"12 Checking untouched state of pointset 2");
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent2);
MITK_TEST_CONDITION_REQUIRED(pointSet1->GetPointSet()->GetNumberOfPoints()==1,"13 Checking untouched state of pointset 1");
MITK_TEST_CONDITION_REQUIRED(pointSet2->GetPointSet()->GetNumberOfPoints()==1,"14 Checking detected point in pointset 2");
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor1);
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor2);
delete delEvent1;
delete delEvent2;
myRenderingManager->RemoveRenderWindow(vtkRenWin1);
myRenderingManager->RemoveRenderWindow(vtkRenWin2);
vtkRenWin1->Delete();
vtkRenWin2->Delete();
//destroy RenderingManager
myRenderingManager = NULL;
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkNodePredicateSourceTest.cpp b/Core/Code/Testing/mitkNodePredicateSourceTest.cpp
index 24e6edbec8..92130cfbac 100644
--- a/Core/Code/Testing/mitkNodePredicateSourceTest.cpp
+++ b/Core/Code/Testing/mitkNodePredicateSourceTest.cpp
@@ -1,52 +1,51 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkNodePredicateSource.h"
#include "mitkTestingMacros.h"
#include "mitkStandaloneDataStorage.h"
int mitkNodePredicateSourceTest(int /* argc */, char* /*argv*/[])
{
MITK_TEST_BEGIN("Testing nodePredicateSource")
// Create a DataStorage
mitk::DataStorage::Pointer myDataStorage(mitk::StandaloneDataStorage::New().GetPointer());
mitk::DataNode::Pointer godfather, grandMother, mother, daughter;
godfather = mitk::DataNode::New();
grandMother = mitk::DataNode::New();
mother = mitk::DataNode::New();
daughter = mitk::DataNode::New();
myDataStorage->Add(godfather);
myDataStorage->Add(grandMother);
myDataStorage->Add(mother, grandMother);
myDataStorage->Add(daughter, mother);
mitk::NodePredicateSource::Pointer testPredicate = mitk::NodePredicateSource::New(grandMother, false, myDataStorage);
;
MITK_TEST_CONDITION_REQUIRED(true, "Testing instantiation");
MITK_TEST_CONDITION_REQUIRED(testPredicate->CheckNode(mother), "Node is derivative");
MITK_TEST_CONDITION_REQUIRED(!testPredicate->CheckNode(godfather), "Node is not derivative");
MITK_TEST_CONDITION_REQUIRED(!testPredicate->CheckNode(daughter), "Node is derivative but only direct derivatives are wanted");
testPredicate = NULL;
testPredicate = mitk::NodePredicateSource::New(grandMother, true, myDataStorage);
MITK_TEST_CONDITION_REQUIRED(testPredicate->CheckNode(daughter), "Node is not direct derivative and all derivatives are wanted ");
MITK_TEST_CONDITION_REQUIRED(!testPredicate->CheckNode(grandMother), "Self is not a derivative!");
MITK_TEST_END();
}
\ No newline at end of file
diff --git a/Core/Code/Testing/mitkPixelTypeTest.cpp b/Core/Code/Testing/mitkPixelTypeTest.cpp
index 7744583501..fee4c650f0 100644
--- a/Core/Code/Testing/mitkPixelTypeTest.cpp
+++ b/Core/Code/Testing/mitkPixelTypeTest.cpp
@@ -1,90 +1,89 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-10-07 16:14:59 +0200 (Mi, 07 Okt 2009) $
-Version: $Revision: 19343 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include "mitkPixelType.h"
#include <itkImage.h>
#include <mitkLogMacros.h>
//## Documentation
//## main testing method
int mitkPixelTypeTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("PixelTypeTest");
MITK_INFO << "ptype = mitk::MakePixelType<int, int, 5>();";
MITK_INFO << "itkPtype = mitk::MakePixelType<ItkImageType>();\n with itk::Image<itk::FixedArray< int, 5>, 3> ItkImageType";
mitk::PixelType ptype = mitk::MakePixelType<int, int, 5>();
typedef itk::Image<itk::FixedArray< int, 5>, 3> ItkImageType;
mitk::PixelType itkPtype = mitk::MakePixelType<ItkImageType>();
MITK_TEST_CONDITION_REQUIRED( ptype.GetTypeId() == typeid(int), "GetTypeId()");
// MITK_TEST_CONDITION( ptype.GetPixelTypeId() == typeid(ItkImageType), "GetPixelTypeId()");
MITK_INFO << ptype.GetPixelTypeId().name();
MITK_INFO << typeid(ItkImageType).name();
MITK_TEST_CONDITION_REQUIRED( ptype.GetBpe() == 8*sizeof(int)*5, "[ptype] GetBpe()");
MITK_TEST_CONDITION_REQUIRED( ptype.GetNumberOfComponents() == 5, "[ptype]GetNumberOfComponents()");
MITK_TEST_CONDITION_REQUIRED( ptype.GetBitsPerComponent() == 8*sizeof(int), "[ptype]GetBitsPerComponent()");
MITK_TEST_CONDITION_REQUIRED( itkPtype.GetBpe() == 8*sizeof(int)*5, "[itkPType] GetBpe()");
MITK_TEST_CONDITION_REQUIRED( itkPtype.GetNumberOfComponents() == 5, "[itkPType] GetNumberOfComponents()");
MITK_TEST_CONDITION_REQUIRED( itkPtype.GetBitsPerComponent() == 8*sizeof(int), "[itkPType] GetBitsPerComponent()");
// MITK_TEST_CONDITION_REQUIRED( itkPtype == ptype, "[itkPtype = ptype]");
//MITK_TEST_CONDITION( ptype.GetItkTypeAsString().compare("unknown") == 0, "GetItkTypeAsString()");
{
{
mitk::PixelType ptype2( ptype);
MITK_TEST_CONDITION_REQUIRED( ptype2.GetTypeId() == typeid(int), "ptype2( ptype)- GetTypeId()");
MITK_TEST_CONDITION( ptype2.GetPixelTypeId() == ptype.GetPixelTypeId(), "ptype2( ptype)-GetPixelTypeId(");
MITK_TEST_CONDITION_REQUIRED( ptype2.GetBpe() == 8*sizeof(int)*5, "ptype2( ptype)-GetBpe()");
MITK_TEST_CONDITION_REQUIRED( ptype2.GetNumberOfComponents() == 5, "ptype2( ptype)-GetNumberOfComponents()");
MITK_TEST_CONDITION_REQUIRED( ptype2.GetBitsPerComponent() == 8*sizeof(int), "ptype2( ptype)-GetBitsPerComponent()");
// MITK_TEST_CONDITION_REQUIRED( ptype.GetItkTypeAsString().compare("unknown") == 0, "ptype2( ptype)-GetItkTypeAsString()");
}
{
mitk::PixelType ptype2 = ptype;
MITK_TEST_CONDITION_REQUIRED( ptype2.GetTypeId() == typeid(int), "ptype2 = ptype- GetTypeId()");
MITK_TEST_CONDITION( ptype2.GetPixelTypeId() == ptype.GetPixelTypeId(), "ptype2 = ptype- GetPixelTypeId(");
MITK_TEST_CONDITION_REQUIRED( ptype2.GetBpe() == 8*sizeof(int)*5, "ptype2 = ptype- GetBpe()");
MITK_TEST_CONDITION_REQUIRED( ptype2.GetNumberOfComponents() == 5, "ptype2 = ptype- GetNumberOfComponents()");
MITK_TEST_CONDITION_REQUIRED( ptype2.GetBitsPerComponent() == 8*sizeof(int), "ptype2 = ptype- GetBitsPerComponent()");
// MITK_TEST_CONDITION_REQUIRED( ptype.GetItkTypeAsString().compare("unknown") == 0, "ptype2 = ptype- GetItkTypeAsString()");
}
{
mitk::PixelType ptype2 = ptype;
MITK_TEST_CONDITION_REQUIRED( ptype == ptype2, "operator ==");
//MITK_TEST_CONDITION_REQUIRED( ptype == typeid(int), "operator ==");
//mitk::PixelType ptype3 = mitk::MakePixelType<char, char ,5>;
//MITK_TEST_CONDITION_REQUIRED( ptype != ptype3, "operator !=");
//MITK_TEST_CONDITION_REQUIRED( *ptype3 != typeid(int), "operator !=");
}
}
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkPlaneGeometryTest.cpp b/Core/Code/Testing/mitkPlaneGeometryTest.cpp
index 821e08f059..0a4f40b956 100644
--- a/Core/Code/Testing/mitkPlaneGeometryTest.cpp
+++ b/Core/Code/Testing/mitkPlaneGeometryTest.cpp
@@ -1,1009 +1,1008 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPlaneGeometry.h"
#include "mitkRotationOperation.h"
#include "mitkInteractionConst.h"
#include "mitkLine.h"
#include "mitkTestingMacros.h"
#include <vnl/vnl_quaternion.h>
#include <vnl/vnl_quaternion.txx>
#include <fstream>
int mappingTests2D(const mitk::PlaneGeometry* planegeometry, const mitk::ScalarType& width, const mitk::ScalarType& height, const mitk::ScalarType& widthInMM, const mitk::ScalarType& heightInMM, const mitk::Point3D& origin, const mitk::Vector3D& right, const mitk::Vector3D& bottom)
{
std::cout << "Testing mapping Map(pt2d_mm(x=widthInMM/2.3,y=heightInMM/2.5), pt3d_mm) and compare with expected: ";
mitk::Point2D pt2d_mm;
mitk::Point3D pt3d_mm, expected_pt3d_mm;
pt2d_mm[0] = widthInMM/2.3; pt2d_mm[1] = heightInMM/2.5;
expected_pt3d_mm = origin+right*(pt2d_mm[0]/right.GetNorm())+bottom*(pt2d_mm[1]/bottom.GetNorm());
planegeometry->Map(pt2d_mm, pt3d_mm);
if(mitk::Equal(pt3d_mm, expected_pt3d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected: ";
mitk::Point2D testpt2d_mm;
planegeometry->Map(pt3d_mm, testpt2d_mm);
if(mitk::Equal(pt2d_mm, testpt2d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ";
mitk::Point2D pt2d_units;
pt2d_units[0] = width/2.0; pt2d_units[1] = height/2.0;
pt2d_mm[0] = widthInMM/2.0; pt2d_mm[1] = heightInMM/2.0;
planegeometry->IndexToWorld(pt2d_units, testpt2d_mm);
if(mitk::Equal(pt2d_mm, testpt2d_mm) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing WorldToIndex(pt2d_mm, pt2d_units) and compare with expected: ";
mitk::Point2D testpt2d_units;
planegeometry->WorldToIndex(pt2d_mm, testpt2d_units);
if(mitk::Equal(pt2d_units, testpt2d_units) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
int TestCase1210()
{
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
mitk::Point3D origin;
mitk::Vector3D right, down, spacing;
mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
mitk::FillVector3D(right,
1.015625, 1.015625, 1.1999969482421875
);
mitk::FillVector3D(down,
1.4012984643248170709237295832899161312802619418765e-45, 0, 0
);
mitk::FillVector3D(spacing,
0, 1.4713633875410579244699160624544119378442750389703e-43, 9.2806360452222355258639080851310540729807238879469e-32
);
std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
planegeometry->InitializeStandardPlane(right, down, &spacing);
/*
std::cout << "Testing width, height and thickness (in units): ";
if((mitk::Equal(planegeometry->GetExtent(0),width)==false) ||
(mitk::Equal(planegeometry->GetExtent(1),height)==false) ||
(mitk::Equal(planegeometry->GetExtent(2),1)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm): ";
if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
*/
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
/**
* @brief This method tests method IntersectionPoint
*
* See also bug #7151. (ref 2 this test: iggy)
* This test was written due to incorrect calculation of the intersection point
* between a given line and plane. This only occured when the pointdistance of
* the line was less than 1.
* Test Behavour:
* ==============
* we have a given line and a given plane.
* we let the line intersect the plane.
* when testing several positions on the line the resulting intersection point must be the same
* we test a position where the distance between the correspoinding points is < 0 and another position where the distance is > 0.
*
*/
int TestIntersectionPoint()
{
//init plane with its parameter
mitk::PlaneGeometry::Pointer myPlaneGeometry = mitk::PlaneGeometry::New();
mitk::Point3D origin;
origin[0] = 0.0;
origin[1] = 2.0;
origin[2] = 0.0;
mitk::Vector3D normal;
normal[0] = 0.0;
normal[1] = 1.0;
normal[2] = 0.0;
myPlaneGeometry->InitializePlane(origin,normal);
//generate points and line for intersection testing
//point distance of given line > 1
mitk::Point3D pointP1;
pointP1[0] = 2.0;
pointP1[1] = 1.0;
pointP1[2] = 0.0;
mitk::Point3D pointP2;
pointP2[0] = 2.0;
pointP2[1] = 4.0;
pointP2[2] = 0.0;
mitk::Vector3D lineDirection;
lineDirection[0] = pointP2[0] - pointP1[0];
lineDirection[1] = pointP2[1] - pointP1[1];
lineDirection[2] = pointP2[2] - pointP1[2];
mitk::Line3D xingline( pointP1, lineDirection );
mitk::Point3D calcXingPoint;
myPlaneGeometry->IntersectionPoint(xingline, calcXingPoint);
//point distance of given line < 1
mitk::Point3D pointP3;
pointP3[0] = 2.0;
pointP3[1] = 2.2;
pointP3[2] = 0.0;
mitk::Point3D pointP4;
pointP4[0] = 2.0;
pointP4[1] = 1.7;
pointP4[2] = 0.0;
mitk::Vector3D lineDirection2;
lineDirection2[0] = pointP4[0] - pointP3[0];
lineDirection2[1] = pointP4[1] - pointP3[1];
lineDirection2[2] = pointP4[2] - pointP3[2];
mitk::Line3D xingline2( pointP3, lineDirection2 );
mitk::Point3D calcXingPoint2;
myPlaneGeometry->IntersectionPoint( xingline2, calcXingPoint2 );
//intersection points must be the same
if (calcXingPoint == calcXingPoint2) {
return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
}
}
/**
* @brief This method tests method ProjectPointOntoPlane.
*
* See also bug #3409.
*/
int TestProjectPointOntoPlane()
{
mitk::PlaneGeometry::Pointer myPlaneGeometry = mitk::PlaneGeometry::New();
//create normal
mitk::Vector3D normal;
normal[0] = 0.0;
normal[1] = 0.0;
normal[2] = 1.0;
//create origin
mitk::Point3D origin;
origin[0] = -27.582859;
origin[1] = 50;
origin[2] = 200.27742;
//initialize plane geometry
myPlaneGeometry->InitializePlane(origin,normal);
//output to descripe the test
std::cout << "Testing PlaneGeometry according to bug #3409" << std::endl;
std::cout << "Our normal is: " << normal << std::endl;
std::cout << "So ALL projected points should have exactly the same z-value!" << std::endl;
//create a number of points
mitk::Point3D myPoints[5];
myPoints[0][0] = -27.582859;
myPoints[0][1] = 50.00;
myPoints[0][2] = 200.27742;
myPoints[1][0] = -26.58662;
myPoints[1][1] = 50.00;
myPoints[1][2] = 200.19026;
myPoints[2][0] = -26.58662;
myPoints[2][1] = 50.00;
myPoints[2][2] = 200.33124;
myPoints[3][0] = 104.58662;
myPoints[3][1] = 452.12313;
myPoints[3][2] = 866.41236;
myPoints[4][0] = -207.58662;
myPoints[4][1] = 312.00;
myPoints[4][2] = -300.12346;
//project points onto plane
mitk::Point3D myProjectedPoints[5];
for ( unsigned int i = 0; i < 5; ++i )
{
myProjectedPoints[i] = myPlaneGeometry->ProjectPointOntoPlane( myPoints[i] );
}
//compare z-values with z-value of plane (should be equal)
bool allPointsOnPlane = true;
for ( unsigned int i = 0; i < 5; ++i )
{
if ( fabs(myProjectedPoints[i][2] - origin[2]) > mitk::sqrteps )
{
allPointsOnPlane = false;
}
}
if (!allPointsOnPlane)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
else
{
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
}
int mitkPlaneGeometryTest(int /*argc*/, char* /*argv*/[])
{
int result;
/*
// the following can be used to reproduce a bug in ITK matrix inversion
// which was found while investigating bug #1210.
result = TestCase1210();
if(result!=EXIT_SUCCESS)
return result;
*/
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
mitk::Point3D origin;
mitk::Vector3D right, bottom, normal;
mitk::ScalarType width, height;
mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
width = 100; widthInMM = width;
height = 200; heightInMM = height;
thicknessInMM = 1.0;
mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
mitk::FillVector3D(right, widthInMM, 0, 0);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
mitk::FillVector3D(normal, 0, 0, thicknessInMM);
std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
planegeometry->InitializeStandardPlane(right.Get_vnl_vector(), bottom.Get_vnl_vector());
std::cout << "Testing width, height and thickness (in units): ";
if((mitk::Equal(planegeometry->GetExtent(0),width)==false) ||
(mitk::Equal(planegeometry->GetExtent(1),height)==false) ||
(mitk::Equal(planegeometry->GetExtent(2),1)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm): ";
if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector(): ";
if((mitk::Equal(planegeometry->GetAxisVector(0), right)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing = {1.0, 1.0, 1.5}): "<<std::endl;
mitk::Vector3D spacing;
thicknessInMM = 1.5;
normal.Normalize(); normal *= thicknessInMM;
mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM);
planegeometry->InitializeStandardPlane(right.Get_vnl_vector(), bottom.Get_vnl_vector(), &spacing);
std::cout << "Testing width, height and thickness (in units): ";
if((mitk::Equal(planegeometry->GetExtent(0),width)==false) ||
(mitk::Equal(planegeometry->GetExtent(1),height)==false) ||
(mitk::Equal(planegeometry->GetExtent(2),1)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm): ";
if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector(): ";
if((mitk::Equal(planegeometry->GetAxisVector(0), right)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing SetExtentInMM(2, ...), querying by GetExtentInMM(2): ";
thicknessInMM = 3.5;
normal.Normalize(); normal *= thicknessInMM;
planegeometry->SetExtentInMM(2, thicknessInMM);
if(mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing SetExtentInMM(2, ...), querying by GetAxisVector(2) and comparing to normal: ";
if(mitk::Equal(planegeometry->GetAxisVector(2), normal)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing SetOrigin: ";
planegeometry->SetOrigin(origin);
if(mitk::Equal(planegeometry->GetOrigin(), origin)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() after SetOrigin: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), right)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
if(result!=EXIT_SUCCESS)
return result;
std::cout << "Changing the IndexToWorldTransform to a rotated version by SetIndexToWorldTransform() (keep origin): "<<std::endl;
mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = planegeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
mitk::VnlVector axis(3);
mitk::FillVector3D(axis, 1.0, 1.0, 1.0); axis.normalize();
vnl_quaternion<mitk::ScalarType> rotation(axis, 0.223);
vnlmatrix = rotation.rotation_matrix_transpose()*vnlmatrix;
mitk::Matrix3D matrix;
matrix = vnlmatrix;
transform->SetMatrix(matrix);
transform->SetOffset(planegeometry->GetIndexToWorldTransform()->GetOffset());
right.Set_vnl_vector( rotation.rotation_matrix_transpose()*right.Get_vnl_vector() );
bottom.Set_vnl_vector(rotation.rotation_matrix_transpose()*bottom.Get_vnl_vector());
normal.Set_vnl_vector(rotation.rotation_matrix_transpose()*normal.Get_vnl_vector());
planegeometry->SetIndexToWorldTransform(transform);
//The origin changed,because m_Origin=m_IndexToWorldTransform->GetOffset()+GetAxisVector(2)*0.5
//and the AxisVector changes due to the rotation. In other words: the rotation was done around
//the corner of the box, not around the planes origin. Now change it to a rotation around
//the origin, simply by re-setting the origin to the original one:
planegeometry->SetOrigin(origin);
mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0);
std::cout << "Testing whether SetIndexToWorldTransform kept origin: ";
if(mitk::Equal(planegeometry->GetOrigin(), origin)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
MITK_TEST_OUTPUT( << "Testing consistancy of index and world coordinates. ");
mitk::Point2D point; point[0] = 4; point[1] = 3;
mitk::Point2D dummy;
planegeometry->WorldToIndex(point, dummy);
planegeometry->IndexToWorld(dummy, dummy);
MITK_TEST_CONDITION_REQUIRED(dummy == point, "");
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of rotated version: ";
if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM)==false) ||
(mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of rotated version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), right)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(),planegeometry->GetExtentInMM(0))==false) ||
(mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(),planegeometry->GetExtentInMM(1))==false) ||
(mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(),planegeometry->GetExtentInMM(2))==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
if(result!=EXIT_SUCCESS)
return result;
std::cout << "Testing SetSizeInUnits() of rotated version: "<<std::endl;
width *= 2;
height *= 3;
planegeometry->SetSizeInUnits(width, height);
std::cout << "Testing width, height and thickness (in units): ";
if((mitk::Equal(planegeometry->GetExtent(0),width)==false) ||
(mitk::Equal(planegeometry->GetExtent(1),height)==false) ||
(mitk::Equal(planegeometry->GetExtent(2),1)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of version with changed size in units: ";
if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM) || !mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM) || !mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of version with changed size in units: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), right)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(),planegeometry->GetExtentInMM(0))==false) ||
(mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(),planegeometry->GetExtentInMM(1))==false) ||
(mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(),planegeometry->GetExtentInMM(2))==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
if(result!=EXIT_SUCCESS)
return result;
std::cout << "Testing Clone(): ";
mitk::PlaneGeometry::Pointer clonedplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());
if((clonedplanegeometry.IsNull()) || (clonedplanegeometry->GetReferenceCount()!=1))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing origin of cloned version: ";
if(mitk::Equal(clonedplanegeometry->GetOrigin(), origin)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in units) of cloned version: ";
if((mitk::Equal(clonedplanegeometry->GetExtent(0),width)==false) ||
(mitk::Equal(clonedplanegeometry->GetExtent(1),height)==false) ||
(mitk::Equal(clonedplanegeometry->GetExtent(2),1)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of cloned version: ";
if(!mitk::Equal(clonedplanegeometry->GetExtentInMM(0), widthInMM) || !mitk::Equal(clonedplanegeometry->GetExtentInMM(1), heightInMM) || !mitk::Equal(clonedplanegeometry->GetExtentInMM(2), thicknessInMM))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of cloned version: ";
if((mitk::Equal(clonedplanegeometry->GetAxisVector(0), right)==false) || (mitk::Equal(clonedplanegeometry->GetAxisVector(1), bottom)==false) || (mitk::Equal(clonedplanegeometry->GetAxisVector(2), normal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(clonedplanegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
if(result!=EXIT_SUCCESS)
return result;
// Clone, move, rotate and test for 'IsParallel' and 'IsOnPlane'
std::cout << "Testing Clone(): ";
mitk::PlaneGeometry::Pointer clonedplanegeometry2 = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());
if((clonedplanegeometry2.IsNull()) || (clonedplanegeometry2->GetReferenceCount()!=1))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout << "Testing if cloned and original version are at the same place: ";
if(mitk::Equal(clonedplanegeometry2->IsOnPlane(planegeometry), true) ==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing if the origin is on the plane: ";
if(mitk::Equal(clonedplanegeometry2->IsOnPlane(origin), true)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
mitk::VnlVector newaxis(3);
mitk::FillVector3D(newaxis, 1.0, 1.0, 1.0); newaxis.normalize();
vnl_quaternion<mitk::ScalarType> rotation2(newaxis, 0.0);
mitk::Vector3D clonednormal = clonedplanegeometry2->GetNormal();
mitk::Point3D clonedorigin = clonedplanegeometry2->GetOrigin();
mitk::RotationOperation* planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 180.0 );
clonedplanegeometry2->ExecuteOperation( planerot );
std::cout << "Testing whether the flipped plane is still the original plane: ";
if( mitk::Equal( clonedplanegeometry2->IsOnPlane(planegeometry), true )==false )
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
clonedorigin += clonednormal;
clonedplanegeometry2->SetOrigin( clonedorigin );
std::cout << "Testing if the translated (cloned, flipped) plane is parallel to its origin plane: ";
if( mitk::Equal( clonedplanegeometry2->IsParallel(planegeometry), true )==false )
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
delete planerot;
planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 0.5 );
clonedplanegeometry2->ExecuteOperation( planerot );
std::cout << "Testing if a non-paralell plane gets recognized as not paralell [rotation +0.5 degree] : ";
if( mitk::Equal( clonedplanegeometry2->IsParallel(planegeometry), false )==false )
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
delete planerot;
planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), -1.0 );
clonedplanegeometry2->ExecuteOperation( planerot );
std::cout << "Testing if a non-paralell plane gets recognized as not paralell [rotation -0.5 degree] : ";
if( mitk::Equal( clonedplanegeometry2->IsParallel(planegeometry), false )==false )
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
delete planerot;
planerot = new mitk::RotationOperation( mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector( 0 ), 360.5 );
clonedplanegeometry2->ExecuteOperation( planerot );
std::cout << "Testing if a non-paralell plane gets recognized as not paralell [rotation 360 degree] : ";
if( mitk::Equal( clonedplanegeometry2->IsParallel(planegeometry), true )==false )
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Transversal, zPosition = 0, frontside=true): " <<std::endl;
planegeometry->InitializeStandardPlane(clonedplanegeometry);
std::cout << "Testing origin of transversally initialized version: ";
if(mitk::Equal(planegeometry->GetOrigin(), origin)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetCornerPoint(0) of transversally initialized version: ";
if(mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in units) of transversally initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ";
if(!mitk::Equal(planegeometry->GetExtent(0), width) || !mitk::Equal(planegeometry->GetExtent(1), height) || !mitk::Equal(planegeometry->GetExtent(2), 1))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of transversally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM) || !mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM) || !mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of transversally initialized version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), right)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), bottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), normal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
if(result!=EXIT_SUCCESS)
return result;
mitk::Vector3D newright, newbottom, newnormal;
mitk::ScalarType newthicknessInMM;
std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Frontal, zPosition = 0, frontside=true): " <<std::endl;
planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Frontal);
newright = right;
newbottom = normal; newbottom.Normalize(); newbottom *= thicknessInMM;
newthicknessInMM = heightInMM/height*1.0/*extent in normal direction is 1*/;
newnormal = -bottom; newnormal.Normalize(); newnormal *= newthicknessInMM;
std::cout << "Testing GetCornerPoint(0) of frontally initialized version: ";
if(mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
//ok, corner was fine, so we can dare to believe the origin is ok.
origin = planegeometry->GetOrigin();
std::cout << "Testing width, height and thickness (in units) of frontally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtent(0), width) || !mitk::Equal(planegeometry->GetExtent(1), 1) || !mitk::Equal(planegeometry->GetExtent(2), 1))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of frontally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM) || !mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM) || !mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of frontally initialized version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), newright)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), newbottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), newnormal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, width, 1, widthInMM, thicknessInMM, origin, newright, newbottom);
if(result!=EXIT_SUCCESS)
return result;
std::cout << "Changing plane to in-plane unit spacing using SetSizeInUnits: " <<std::endl;
planegeometry->SetSizeInUnits(planegeometry->GetExtentInMM(0), planegeometry->GetExtentInMM(1));
std::cout << "Testing origin of unit spaced, frontally initialized version: ";
if(mitk::Equal(planegeometry->GetOrigin(), origin)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtent(0), widthInMM) || !mitk::Equal(planegeometry->GetExtent(1), thicknessInMM) || !mitk::Equal(planegeometry->GetExtent(2), 1))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM) || !mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM) || !mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of unit spaced, frontally initialized version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), newright)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), newbottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), newnormal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom);
if(result!=EXIT_SUCCESS)
return result;
std::cout << "Changing plane to unit spacing also in normal direction using SetExtentInMM(2, 1.0): " <<std::endl;
planegeometry->SetExtentInMM(2, 1.0);
newnormal.Normalize();
std::cout << "Testing origin of unit spaced, frontally initialized version: ";
if(mitk::Equal(planegeometry->GetOrigin(), origin)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtent(0), widthInMM) || !mitk::Equal(planegeometry->GetExtent(1), thicknessInMM) || !mitk::Equal(planegeometry->GetExtent(2), 1))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM) || !mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM) || !mitk::Equal(planegeometry->GetExtentInMM(2), 1.0))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of unit spaced, frontally initialized version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), newright)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), newbottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), newnormal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom);
if(result!=EXIT_SUCCESS)
return result;
std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Sagittal, zPosition = 0, frontside=true): " <<std::endl;
planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Sagittal);
newright = bottom;
newthicknessInMM = widthInMM/width*1.0/*extent in normal direction is 1*/;
newnormal = right; newnormal.Normalize(); newnormal *= newthicknessInMM;
std::cout << "Testing GetCornerPoint(0) of sagitally initialized version: ";
if(mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
//ok, corner was fine, so we can dare to believe the origin is ok.
origin = planegeometry->GetOrigin();
std::cout << "Testing width, height and thickness (in units) of sagitally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtent(0), height) || !mitk::Equal(planegeometry->GetExtent(1), 1) || !mitk::Equal(planegeometry->GetExtent(2), 1))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of sagitally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtentInMM(0), heightInMM) || !mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM) || !mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of sagitally initialized version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), newright)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), newbottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), newnormal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, height, 1, heightInMM, thicknessInMM, origin, newright, newbottom);
if(result!=EXIT_SUCCESS)
return result;
//set origin back to the one of the transversal slice:
origin = clonedplanegeometry->GetOrigin();
std::cout << "Testing backside initialization: InitializeStandardPlane(clonedplanegeometry, planeorientation = Transversal, zPosition = 0, frontside=false, rotated=true): " <<std::endl;
planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Transversal, 0, false, true);
mitk::Point3D backsideorigin;
backsideorigin=origin+clonedplanegeometry->GetAxisVector(1);//+clonedplanegeometry->GetAxisVector(2);
std::cout << "Testing origin of backsidedly, transversally initialized version: ";
if(mitk::Equal(planegeometry->GetOrigin(), backsideorigin)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetCornerPoint(0) of sagitally initialized version: ";
mitk::Point3D backsidecornerpoint0;
backsidecornerpoint0 = cornerpoint0+clonedplanegeometry->GetAxisVector(1);//+clonedplanegeometry->GetAxisVector(2);
if(mitk::Equal(planegeometry->GetCornerPoint(0), backsidecornerpoint0)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in units) of backsidedly, transversally initialized version (should be same as in mm due to unit spacing, except for thickness, which is always 1): ";
if(!mitk::Equal(planegeometry->GetExtent(0), width) || !mitk::Equal(planegeometry->GetExtent(1), height) || !mitk::Equal(planegeometry->GetExtent(2), 1))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm) of backsidedly, transversally initialized version: ";
if(!mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM) || !mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM) || !mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector() of backsidedly, transversally initialized version: ";
if((mitk::Equal(planegeometry->GetAxisVector(0), right)==false) || (mitk::Equal(planegeometry->GetAxisVector(1), -bottom)==false) || (mitk::Equal(planegeometry->GetAxisVector(2), -normal)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
result = mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, backsideorigin, right, -bottom);
if(result!=EXIT_SUCCESS)
return result;
// test method mitk::PlaneGeometry::ProjectPointOntoPlane()
// (see also bug #3409)
result = TestProjectPointOntoPlane();
if(result!=EXIT_SUCCESS)
return result;
// testing mitk::PlaneGeometry::IntersectionPoint()
std::cout << std::endl;
std::cout << "Testing IntersectionPoint using given plane and given line: ";
result = TestIntersectionPoint();
if (result != EXIT_SUCCESS) {
std::cout << "[FAILED]" << std::endl;
return result;
}
std::cout<<"[PASSED]"<<std::endl<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkPointSetFileIOTest.cpp b/Core/Code/Testing/mitkPointSetFileIOTest.cpp
index f4233c44a2..f9e24b44e8 100644
--- a/Core/Code/Testing/mitkPointSetFileIOTest.cpp
+++ b/Core/Code/Testing/mitkPointSetFileIOTest.cpp
@@ -1,163 +1,162 @@
-/*=========================================================================
-
- Program: Medical Imaging & Interaction Toolkit
- Language: C++
- Date: $Date$
- Version: $Revision$
-
- Copyright (c) German Cancer Research Center, Division of Medical and
- Biological Informatics. All rights reserved.
- See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
-
- =========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkPointSet.h"
#include "mitkPointSetWriter.h"
#include "mitkPointSetReader.h"
#include "mitkTestingMacros.h"
#include <vector>
#include <itksys/SystemTools.hxx>
#include <time.h>
//unsigned int numberOfTestPointSets = 1;
unsigned int numberOfTimeSeries = 5;
// create one test PointSet
class mitkPointSetFileIOTestClass
{
public:
std::vector<mitk::PointSet::Pointer> m_SavedPointSet;
mitkPointSetFileIOTestClass()
{
}
mitk::PointSet::Pointer CreateTestPointSet()
{
mitk::PointSet::Pointer pointSet = mitk::PointSet::New();
for (unsigned int t = 0; t < numberOfTimeSeries; t++)
{
unsigned int position(0);
mitk::Point3D point;
mitk::FillVector3D(point, (rand()%1000) /1000.0 , (rand()%1000) /1000.0, (rand()%1000)/1000.0);
pointSet->SetPoint(position, point, t);
mitk::FillVector3D(point, (rand()%1000) /1000.0 , (rand()%1000) /1000.0, (rand()%1000)/1000.0);
++position;
pointSet->SetPoint(position, point, t);
mitk::FillVector3D(point, (rand()%1000) /1000.0 , (rand()%1000) /1000.0, (rand()%1000)/1000.0);
++position;
pointSet->SetPoint(position, point, t);
}
m_SavedPointSet.push_back(pointSet);
return pointSet;
}
void PointSetCompare(mitk::PointSet::Pointer pointSet2,
mitk::PointSet::Pointer pointSet1, bool& /*identical*/)
{
MITK_TEST_CONDITION(pointSet1->GetSize() == pointSet2->GetSize(), "Testing if PointSet size is correct" );
for (unsigned int t = 0; t < numberOfTimeSeries; t++)
{
for (unsigned int i = 0; i < (unsigned int) pointSet1->GetSize(t); ++i)
{
mitk::Point3D p1 = pointSet1->GetPoint(i);
mitk::Point3D p2 = pointSet2->GetPoint(i);
//test
std::cout << "r point: " << p2 << std::endl;
std::cout << "w point: " << p1 << std::endl;
//test end
MITK_TEST_CONDITION((p1[0] - p2[0]) <= 0.0001, "Testing if X coordinates of the Point are at the same Position" );
MITK_TEST_CONDITION((p1[1] - p2[1]) <= 0.0001, "Testing if Y coordinates of the Point are at the same Position" );
MITK_TEST_CONDITION((p1[2] - p2[2]) <= 0.0001, "Testing if Z coordinates of the Point are at the same Position" );
}
}
}
bool PointSetWrite(unsigned int numberOfPointSets)
{
try
{
m_SavedPointSet.clear();
mitk::PointSetWriter::Pointer pointSetWriter = mitk::PointSetWriter::New();
pointSetWriter->SetFileName("test_pointset_new.mps");
for (unsigned int i = 0; i < numberOfPointSets; i++)
{
pointSetWriter->SetInput(i, CreateTestPointSet());
}
pointSetWriter->Write();
}
catch (std::exception& /*e*/)
{
return false;
}
return true;
}
void PointSetLoadAndCompareTest(unsigned int numberOfPointSets)
{
try
{
mitk::PointSetReader::Pointer pointSetReader =
mitk::PointSetReader::New();
mitk::PointSet::Pointer pointSet;
pointSetReader->SetFileName("test_pointset_new.mps");
for (unsigned int i = 0; i < numberOfPointSets; i++)
{
pointSetReader->Update();
pointSet = pointSetReader->GetOutput(i);
MITK_TEST_CONDITION(pointSet.IsNotNull(), "Testing if the loaded Data are NULL" );
bool identical(true);
PointSetCompare(pointSet.GetPointer(), m_SavedPointSet.at(i).GetPointer(),
identical);
}
} catch (std::exception& /*e*/)
{
}
}
}; //mitkPointSetFileIOTestClass
int mitkPointSetFileIOTest(int, char*[])
{
MITK_TEST_BEGIN("PointSet");
unsigned int numberOfPointSets(5);
mitkPointSetFileIOTestClass* test = new mitkPointSetFileIOTestClass();
// write
MITK_TEST_CONDITION(test->PointSetWrite(numberOfPointSets), "Testing if the PointSetWriter writes Data" );
// load - compare
test->PointSetLoadAndCompareTest(numberOfPointSets);
//Delete correctly
delete test;
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkPointSetInteractorTest.cpp b/Core/Code/Testing/mitkPointSetInteractorTest.cpp
index 7395184ad1..3daaed58fe 100644
--- a/Core/Code/Testing/mitkPointSetInteractorTest.cpp
+++ b/Core/Code/Testing/mitkPointSetInteractorTest.cpp
@@ -1,590 +1,589 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-05-03 12:55:29 +0200 (Mo, 03 Mai 2010) $
-Version: $Revision: 22655 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetInteractor.h"
#include "mitkPointSet.h"
#include "mitkPositionEvent.h"
#include "mitkVtkPropRenderer.h"
#include "mitkStateEvent.h"
#include "mitkInteractionConst.h"
#include "mitkGlobalInteraction.h"
#include "mitkPointOperation.h"
#include "mitkTestingMacros.h"
#include <iostream>
const char* POINTSETINTERACTORNAME = "pointsetinteractor";
const char* ONLYMOVEPOINTSETINTERACTORNAME = "onlymovepointsetinteractor";
const char* SEEDPOINTSETINTERACTORNAME = "seedpointsetinteractor";
const char* SINGLEPOINTWITHOUTSHIFTCLICKNAME = "singlepointinteractorwithoutshiftclick";
/**
*@brief method to send specified events to EventMapper
**/
class mitkPointSetInteractorTestClass {
public:
void TestPointSetInteractor(const char* name, mitk::DataNode* node, mitk::BaseRenderer* sender, int numberOfPointsAllowed)
{
mitk::PointSetInteractor::Pointer interactor = mitk::PointSetInteractor::New(name, node, numberOfPointsAllowed);
MITK_TEST_CONDITION_REQUIRED(interactor.IsNotNull(),"Testing to initialize PointSetInteractor")
std::cout<<"The pattern of the interactor is called: "<<interactor->GetType()<<std::endl;
MITK_TEST_CONDITION_REQUIRED(interactor->GetType() == name,"testing pattern name of interactor");
//should not be null
MITK_TEST_CONDITION_REQUIRED(node != NULL, "error in test! Node == NULL");
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
MITK_TEST_CONDITION_REQUIRED(pointSet.IsNotNull(), "error in test! PointSet not set");
//sending an event now shouln't lead to an addition of a point because interactor is not yet connected to globalinteraction
mitk::Point3D pos3D;
mitk::Point2D pos2D;
pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
pos2D[0]= 100; pos2D[0]= 200;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking unconnected interactor.");
//activate interaction
mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor);
//now one point should be added going from state 1 over state 3 and 40 to state 2 (space left)
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking connected interactor by adding a point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing right addition of point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point is selected.");
//delesecting point; going from state 2 over state 10 to state 2
pos3D.Fill(-100.0);
pos2D.Fill(200.0);
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) == false,"Testing deselection of a point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetNumberOfSelected() == 0,"No selected points.");
//trying to delete a deselected point so going from state 2 over 30 to 1
mitk::Event* delEvent = new mitk::Event(sender, mitk::Type_KeyPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_Delete);
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking that no unselected point can be deleted.");
//not deleting delEvent, because if will be used later on
//picking point
pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
pos2D[0]= 100; pos2D[0]= 200;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point is picked.");
//deleting selected point
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking if the selected point could be delected.");
//adding two points and checking selection
pos3D[0]= 11.0; pos3D[1]= 22.0; pos3D[2]= 33.0;
pos2D[0]= 11; pos2D[0]= 22;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking adding point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point1 is selected.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing addition of point.");
pos3D[0]= 111.0; pos3D[1]= 222.0; pos3D[2]= 333.0;
pos2D[0]= 111; pos2D[0]= 222;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==2,"Checking adding second point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ==false,"Testing if point1 is deselected.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(1) == pos3D,"Testing addition of point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(1) ,"Testing if point2 is selected.");
//selecting the first point and deleting it
pos3D[0]= 11.0; pos3D[1]= 22.0; pos3D[2]= 33.0;
pos2D[0]= 11; pos2D[0]= 22;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point1 is picked.");
//sending delete-event
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking if the picked point1 could be delected.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(1) ,"Testing if point2 is now selected.");
//sending delete-event again
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking if point2 could be delected.");
//adding more than three points and see if only three can be added
pos3D[0]= 1.0; pos3D[1]= 2.0; pos3D[2]= 3.0;
pos2D[0]= 1; pos2D[0]= 2;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 11.0; pos3D[1]= 22.0; pos3D[2]= 33.0;
pos2D[0]= 11; pos2D[0]= 22;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 111.0; pos3D[1]= 222.0; pos3D[2]= 333.0;
pos2D[0]= 111; pos2D[0]= 222;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 1111.0; pos3D[1]= 2222.0; pos3D[2]= 3333.0;
pos2D[0]= 12; pos2D[0]= 21;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
if (numberOfPointsAllowed>=0) //not number of points set to unlimited
{
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==(unsigned long)numberOfPointsAllowed,"Checking if only the amount of defined points could be added.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(2) ,"Testing if the last point added is selected.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(2) != pos3D,"Testing that the last addition didn't work.");
}
//testing whether a point can be added to an already filled point set after deleting an unselected point
if (numberOfPointsAllowed>=0) //not number of points set to unlimited
{
//delesecting point; going from state 2 over state 10 to state 2
pos3D.Fill(-100.0);
pos2D.Fill(200.0);
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) == false,"Testing deselection of a point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetNumberOfSelected() == 0,"No selected points.");
//trying to delete a deselected point so going from state 2 over 30 to 1
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==(unsigned long)numberOfPointsAllowed,"Checking that no unselected point can be deleted.");
//trying to add point to already filled point set
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==(unsigned long)numberOfPointsAllowed,"Checking that no point can be added after hitting DEL on no selection.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(2) ,"Testing if the last point added is selected.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(2) != pos3D,"Testing that the last addition didn't work.");
}
//selecting the first point and moving it to 0,0,0
pos3D[0]= 1.0; pos3D[1]= 2.0; pos3D[2]= 3.0;
pos2D[0]= 1; pos2D[0]= 2;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point1 is selected.");
//sending the same event to hold the point for movement
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
//slowly move to 0,0,0
pos3D[0]= 0.5; pos3D[1]= 1.0; pos3D[2]= 1.5;
pos2D[0]= 0; pos2D[0]= 1;
this->SendPositionEvent(sender, mitk::Type_MouseMove, mitk::BS_NoButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 0.0; pos3D[1]= 0.0; pos3D[2]= 0.0;
pos2D[0]= 0; pos2D[0]= 0;
this->SendPositionEvent(sender, mitk::Type_MouseMove, mitk::BS_NoButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
//release event
this->SendPositionEvent(sender, mitk::Type_MouseButtonRelease, mitk::BS_LeftButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing movement of point.");
if (numberOfPointsAllowed>=0) //not number of points set to unlimited
{
//deleting all three points now
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==2,"Checking if point3 could be delected.");
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking if point2 could be delected.");
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking if point1 could be delected.");
}
else
{
//deleting all four points now
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==3,"Checking if point4 could be delected.");
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==2,"Checking if point3 could be delected.");
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking if point2 could be delected.");
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking if point1 could be delected.");
}
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor);
delete delEvent;
}
void TestOnlyMovePointSetInteractor(const char* name, mitk::DataNode* node, mitk::BaseRenderer* sender, int numberOfPointsAllowed)
{
mitk::PointSetInteractor::Pointer interactor = mitk::PointSetInteractor::New(name, node, numberOfPointsAllowed);
MITK_TEST_CONDITION_REQUIRED(interactor.IsNotNull(),"Testing to initialize PointSetInteractor")
std::cout<<"The pattern of the interactor is called: "<<interactor->GetType()<<std::endl;
MITK_TEST_CONDITION_REQUIRED(interactor->GetType() == name,"testing pattern name of interactor");
MITK_TEST_CONDITION_REQUIRED(node != NULL, "error in test! Node == NULL");
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
MITK_TEST_CONDITION_REQUIRED(pointSet.IsNotNull(), "error in test! PointSet not set");
//sending an event now shouln't lead to an addition of a point because interactor is not connected to globalinteraction
mitk::Point3D pos3D;
mitk::Point2D pos2D;
pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
pos2D[0]= 10; pos2D[0]= 20;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking unconnected interactor.");
//activate interaction
mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor);
//sending event shouldn't lead to an addition of a point, because statemachine cannot handle this!
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Check to add a point.");
//manually adding two points to a new pointset and setting it to node
mitk::PointSet::Pointer newPointSet = mitk::PointSet::New();
//pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
//pos2D[0]= 10; pos2D[0]= 20;
int timestep = 0;
int index = 0;
mitk::PointOperation* doOp = new mitk::PointOperation( mitk::OpINSERT, timestep, pos3D, index);
newPointSet->ExecuteOperation(doOp);
//undo is enabled on default, so no need to delete doOp
pos3D[0]= 100.0; pos3D[1]= 200.0; pos3D[2]= 300.0;
pos2D[0]= 100; pos2D[0]= 200;
index = 1;
mitk::PointOperation* secondDoOp = new mitk::PointOperation( mitk::OpINSERT, timestep, pos3D, index);
newPointSet->ExecuteOperation(secondDoOp);
//setting it to node
node->SetData(newPointSet);
pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
MITK_TEST_CONDITION_REQUIRED(pointSet.IsNotNull(), "error in test! new PointSet not set");
//checking if data has two points now
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints() == 2,"Testing new data.");
//all points should be deselected but standard addition of a point is selected by default so all are selected. To be solved later
//MITK_TEST_CONDITION_REQUIRED(pointSet->GetNumberOfSelected() == 2,"No selected points.");
//trying to delete a selected point
mitk::Event* delEvent = new mitk::Event(sender, mitk::Type_KeyPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_Delete);
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==2,"Checking that no point can be deleted.");
delete delEvent;
//delesecting point
pos3D.Fill(-100.0);
pos2D.Fill(200.0);
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(1) == false,"Testing deselection of a point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetNumberOfSelected() == 0,"No selected points.");
//picking point
pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
pos2D[0]= 10; pos2D[0]= 20;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point is picked.");
//sending the same event to hold the point for movement
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
//slowly move to 0,0,0
pos3D[0]= 0.5; pos3D[1]= 1.0; pos3D[2]= 1.5;
pos2D[0]= 0; pos2D[0]= 1;
this->SendPositionEvent(sender, mitk::Type_MouseMove, mitk::BS_NoButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 0.0; pos3D[1]= 0.0; pos3D[2]= 0.0;
pos2D[0]= 0; pos2D[0]= 0;
this->SendPositionEvent(sender, mitk::Type_MouseMove, mitk::BS_NoButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
//release event
this->SendPositionEvent(sender, mitk::Type_MouseButtonRelease, mitk::BS_LeftButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing movement of point.");
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor);
}
void TestSeedPointSetInteractor(const char* name, mitk::DataNode* node, mitk::BaseRenderer* sender)
{
mitk::PointSetInteractor::Pointer interactor = mitk::PointSetInteractor::New(name, node);
MITK_TEST_CONDITION_REQUIRED(interactor.IsNotNull(),"Testing to initialize PointSetInteractor")
std::cout<<"The pattern of the interactor is called: "<<interactor->GetType()<<std::endl;
MITK_TEST_CONDITION_REQUIRED(interactor->GetType() == name,"testing pattern name of interactor");
//should not be null
MITK_TEST_CONDITION_REQUIRED(node != NULL, "error in test! Node == NULL");
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
MITK_TEST_CONDITION_REQUIRED(pointSet.IsNotNull(), "error in test! PointSet not set");
//sending an event now shouln't lead to an addition of a point because interactor is not yet connected to globalinteraction
mitk::Point3D pos3D;
mitk::Point2D pos2D;
pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
pos2D[0]= 10; pos2D[0]= 20;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking unconnected interactor.");
//activate interaction
mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor);
//now one point should be added going from state 1 over state 2 to state 10
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking connected interactor by adding a point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing right addition of point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point is selected.");
//delesecting point; going from state 10 over state 12 to state 10
pos3D.Fill(-100.0);
pos2D.Fill(200.0);
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) == false,"Testing deselection of a point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetNumberOfSelected() == 0,"No selected points.");
//trying to delete a deselected point so going from state 10 over 15 to 10
mitk::Event* delEvent = new mitk::Event(sender, mitk::Type_KeyPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_Delete);
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking that no unselected point can be deleted.");
//not deleting delEvent, because if will be used later on
//picking point
pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
pos2D[0]= 10; pos2D[0]= 20;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing picking point.");
//deleting selected point
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking if the selected point could be delected.");
//adding two points and checking that only the last one remains in point set
pos3D[0]= 11.0; pos3D[1]= 22.0; pos3D[2]= 33.0;
pos2D[0]= 11; pos2D[0]= 22;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking adding point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point1 is selected.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing addition of point.");
pos3D[0]= 111.0; pos3D[1]= 222.0; pos3D[2]= 333.0;
pos2D[0]= 111; pos2D[0]= 222;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking that only one point remains in pointset.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing addition of point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ==true,"Testing if point is selected.");
//sending delete-event
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking if the point could be delected.");
//sending delete-event again
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking Sending Delete again.");
//adding three points and see if only the third remains
pos3D[0]= 1.0; pos3D[1]= 2.0; pos3D[2]= 3.0;
pos2D[0]= 1; pos2D[0]= 2;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 11.0; pos3D[1]= 22.0; pos3D[2]= 33.0;
pos2D[0]= 11; pos2D[0]= 22;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 111.0; pos3D[1]= 222.0; pos3D[2]= 333.0;
pos2D[0]= 111; pos2D[0]= 222;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_ShiftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking if only one point could be added.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing if the last point was inserted.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if the last point added is selected.");
//sending the picking event to hold the point for movement
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
//slowly move to 0,0,0
pos3D[0]= 0.5; pos3D[1]= 1.0; pos3D[2]= 1.5;
pos2D[0]= 0; pos2D[0]= 1;
this->SendPositionEvent(sender, mitk::Type_MouseMove, mitk::BS_NoButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 0.0; pos3D[1]= 0.0; pos3D[2]= 0.0;
pos2D[0]= 0; pos2D[0]= 0;
this->SendPositionEvent(sender, mitk::Type_MouseMove, mitk::BS_NoButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
//release event
this->SendPositionEvent(sender, mitk::Type_MouseButtonRelease, mitk::BS_LeftButton, mitk::BS_LeftButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing movement of point.");
//not deleting the points and end of test
//removing interactor from GlobalInteraction
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor);
delete delEvent;
}
void TestSinglePointSetInteractorWithoutShiftClick(const char* name, mitk::DataNode* node, mitk::BaseRenderer* sender)
{
mitk::PointSetInteractor::Pointer interactor = mitk::PointSetInteractor::New(name, node);
MITK_TEST_CONDITION_REQUIRED(interactor.IsNotNull(),"Testing to initialize PointSetInteractor")
std::cout<<"The pattern of the interactor is called: "<<interactor->GetType()<<std::endl;
MITK_TEST_CONDITION_REQUIRED(interactor->GetType() == name,"testing pattern name of interactor");
//should not be null
MITK_TEST_CONDITION_REQUIRED(node != NULL, "error in test! Node == NULL");
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
MITK_TEST_CONDITION_REQUIRED(pointSet.IsNotNull(), "error in test! PointSet not set");
//sending an event now shouln't lead to an addition of a point because interactor is not yet connected to globalinteraction
mitk::Point3D pos3D;
mitk::Point2D pos2D;
pos3D[0]= 10.0; pos3D[1]= 20.0; pos3D[2]= 30.0;
pos2D[0]= 10; pos2D[0]= 20;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking unconnected interactor.");
//activate interaction
mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor);
//now one point should be added going from state 1 to state 2
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking connected interactor by adding a point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing right addition of point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point is selected.");
//trying to delete point
mitk::Event* delEvent = new mitk::Event(sender, mitk::Type_KeyPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_Delete);
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking deleting point.");
//adding two points and checking that only the last one remains in point set
pos3D[0]= 11.0; pos3D[1]= 22.0; pos3D[2]= 33.0;
pos2D[0]= 11; pos2D[0]= 22;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking adding point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if point1 is selected.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing addition of point.");
pos3D[0]= 111.0; pos3D[1]= 222.0; pos3D[2]= 333.0;
pos2D[0]= 111; pos2D[0]= 222;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking that only one point remains in pointset.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing addition of point.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ==true,"Testing if point is selected.");
//sending delete-event
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking if the point could be delected.");
//sending delete-event again
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(delEvent);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking Sending Delete again.");
//adding three points and see if only the third remains
pos3D[0]= 1.0; pos3D[1]= 2.0; pos3D[2]= 3.0;
pos2D[0]= 1; pos2D[0]= 2;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 11.0; pos3D[1]= 22.0; pos3D[2]= 33.0;
pos2D[0]= 11; pos2D[0]= 22;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
pos3D[0]= 111.0; pos3D[1]= 222.0; pos3D[2]= 333.0;
pos2D[0]= 111; pos2D[0]= 222;
this->SendPositionEvent(sender, mitk::Type_MouseButtonPress, mitk::BS_LeftButton, mitk::BS_NoButton, mitk::Key_none, pos2D, pos3D);
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==1,"Checking if only one point could be added.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPoint(0) == pos3D,"Testing if the last point was inserted.");
MITK_TEST_CONDITION_REQUIRED(pointSet->GetSelectInfo(0) ,"Testing if the last point added is selected.");
//removing interactor from GlobalInteraction
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor);
delete delEvent;
}
private:
void SendPositionEvent(mitk::BaseRenderer* sender, int type, int button, int buttonState, int key, const mitk::Point2D& displPosition, const mitk::Point3D& worldPosition)
{
mitk::Event *posEvent = new mitk::PositionEvent(sender, type, button, buttonState, key, displPosition, worldPosition);
mitk::GlobalInteraction::GetInstance()->GetEventMapper()->MapEvent(posEvent);
delete posEvent;
}
}; //mitkPointSetInteractorTestClass
int mitkPointSetInteractorTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("PointSetInteractor")
// Global interaction must(!) be initialized if used
mitk::GlobalInteraction::GetInstance()->Initialize("global");
//create the corresponding data
mitk::PointSet::Pointer pointSet = mitk::PointSet::New();
mitk::DataNode::Pointer node = mitk::DataNode::New();
//we need a baserenderer (VtkPropRenderer) to be able to let PointSetInteractor::CanHandleEvent() proccess
//and for this we need a RenderWindow and a RenderingManager
mitk::RenderingManager::Pointer myRenderingManager = mitk::RenderingManager::New();
myRenderingManager->SetGlobalInteraction(mitk::GlobalInteraction::GetInstance());
vtkRenderWindow* vtkRenWin = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer sender = mitk::VtkPropRenderer::New("testingBR", vtkRenWin, myRenderingManager);
vtkRenWin->Delete();
//hook everything up into a dataNode. (node doesn't here have to be in DataStorage)
node->SetData(pointSet);
//pointset should be empty
MITK_TEST_CONDITION_REQUIRED(pointSet->GetPointSet()->GetNumberOfPoints()==0,"Checking if pointset is empty.");
//instance of testclass
mitkPointSetInteractorTestClass* test = new mitkPointSetInteractorTestClass();
//test setup regular pointsetinteractor
MITK_TEST_OUTPUT(<<"--------Testing "<<POINTSETINTERACTORNAME<<" with max 3 points--------");
test->TestPointSetInteractor(POINTSETINTERACTORNAME, node, sender, 3);
pointSet = mitk::PointSet::New();
node = mitk::DataNode::New();
node->SetData(pointSet);
//test setup with unlimited numbers of points supported
MITK_TEST_OUTPUT(<<"--------Testing "<<POINTSETINTERACTORNAME<<" with unlimited points --------");
test->TestPointSetInteractor(POINTSETINTERACTORNAME, node, sender, -1);
pointSet = mitk::PointSet::New();
node = mitk::DataNode::New();
node->SetData(pointSet);
//test setup only move pointsetinteractor
MITK_TEST_OUTPUT(<<"--------Testing "<<ONLYMOVEPOINTSETINTERACTORNAME<<" with unlimited points --------");
test->TestOnlyMovePointSetInteractor(ONLYMOVEPOINTSETINTERACTORNAME, node, sender, -1);
pointSet = mitk::PointSet::New();
node = mitk::DataNode::New();
node->SetData(pointSet);
MITK_TEST_OUTPUT(<<"--------Testing "<<SEEDPOINTSETINTERACTORNAME<<" with one point --------");
test->TestSeedPointSetInteractor(SEEDPOINTSETINTERACTORNAME, node, sender);
pointSet = mitk::PointSet::New();
node = mitk::DataNode::New();
node->SetData(pointSet);
MITK_TEST_OUTPUT(<<"--------Testing "<<SINGLEPOINTWITHOUTSHIFTCLICKNAME<<" with one point --------");
test->TestSinglePointSetInteractorWithoutShiftClick(SINGLEPOINTWITHOUTSHIFTCLICKNAME, node, sender);
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkPointSetLocaleTest.cpp b/Core/Code/Testing/mitkPointSetLocaleTest.cpp
index ebb61b8f8e..e4bcc999a8 100644
--- a/Core/Code/Testing/mitkPointSetLocaleTest.cpp
+++ b/Core/Code/Testing/mitkPointSetLocaleTest.cpp
@@ -1,178 +1,177 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSetReader.h"
#include "mitkPointSetWriter.h"
#include "mitkStandardFileLocations.h"
#include "mitkTestingMacros.h"
#include <list>
#include <fstream>
#include <iostream>
#include <string>
bool ChangeLocale(const std::string& locale)
{
try
{
MITK_TEST_OUTPUT(<< "\n** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'");
setlocale(LC_ALL, locale.c_str());
std::locale l( locale.c_str() );
std::cin.imbue(l);
std::cout.imbue(l);
return true;
}
catch(...)
{
MITK_TEST_OUTPUT(<< "Could not activate locale" << locale << "\n");
return false;
}
}
void ReaderLocaleTest(mitk::Point3D & refPoint, std::string filename)
{
MITK_TEST_OUTPUT(<< "---- Reader Test ---- ");
mitk::PointSetReader::Pointer reader = mitk::PointSetReader::New();
reader -> SetFileName(filename.c_str());
reader -> Update();
mitk::PointSet::Pointer pointSet = reader -> GetOutput();
mitk::Point3D point;
if (pointSet->GetPointIfExists(0, &point))
{
MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[0] - point[0]) < 0.00001, "read x correct");
MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[1] - point[1]) < 0.00001, "read y correct");
MITK_TEST_CONDITION_REQUIRED(fabs(refPoint[2] - point[2]) < 0.00001, "read z correct");
}else
{
MITK_TEST_FAILED_MSG(<< "File "<< filename << " can not be read - test will not applied." );
return;
}
}
void WriterLocaleTest(mitk::Point3D & refPoint, std::string filename)
{
MITK_TEST_OUTPUT(<< "---- Writer Test---- ");
//create pointset
mitk::PointSet::Pointer refPointSet = mitk::PointSet::New();
refPointSet->InsertPoint(0,refPoint);
//SetPoint(0, refPoint);
std::string testFileName = "testPointSet.mps";
// write point set
mitk::PointSetWriter::Pointer writer = mitk::PointSetWriter::New();
writer -> SetFileName(testFileName.c_str());
writer -> SetInput(refPointSet);
writer -> Write();
//compare two .mps files
std::ifstream refStream (filename.c_str());
std::ifstream stream (testFileName.c_str());
MITK_TEST_CONDITION_REQUIRED(refStream,"Read reference point set");
MITK_TEST_CONDITION_REQUIRED(stream,"Read point set");
std::string streamLine;
std::string refStreamLine;
bool differ = false;
if (stream.is_open() && refStream.is_open())
{
std::string streamLine;
std::string refStreamLine;
while(!stream.eof() && ! refStream.eof())
{
getline(stream, streamLine);
getline(refStream, refStreamLine);
if(streamLine.compare(refStreamLine) != 0)
{
differ = true;
break;
}
}
stream.close();
refStream.close();
}
MITK_TEST_CONDITION_REQUIRED(!differ, "Write point set correct");
}
int mitkPointSetLocaleTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("PointSetLocaleTest");
if (argc<2) {MITK_TEST_FAILED_MSG(<<"Error: test file name is needed as second argument.");}
std::string filename = argv[1];
MITK_INFO << filename;
//create reference point set
mitk::PointSet::Pointer refPointSet = mitk::PointSet::New();
mitk::Point3D refPoint;
refPoint[0] = 32.2946;
refPoint[1] = -17.7359;
refPoint[2] = 29.6502;
refPointSet->SetPoint(0, refPoint);
//create locale list
std::ofstream stream;
std::locale previousLocale(stream.getloc());
typedef std::list<std::string> StringList;
StringList alllocales;
alllocales.push_back("de_DE");
alllocales.push_back("de_DE.utf8");
alllocales.push_back("de_DE.UTF-8");
alllocales.push_back("de_DE@euro");
alllocales.push_back("German_Germany");
// QuickFix for MAC OS X
// See for more the Bug #3894 comments
#if defined (__APPLE__) || defined(MACOSX)
alllocales.push_back("C");
#endif
unsigned int numberOfTestedGermanLocales(0);
for (StringList::iterator iter = alllocales.begin();
iter != alllocales.end();
++iter)
{
if ( ChangeLocale(*iter) )
{
++numberOfTestedGermanLocales;
WriterLocaleTest(refPoint,filename);
ReaderLocaleTest(refPoint,filename);
}
}
if(numberOfTestedGermanLocales == 0)
{
MITK_TEST_OUTPUT(<< "Warning: No German locale was found on the system.");
}
//MITK_TEST_CONDITION_REQUIRED( numberOfTestedGermanLocales > 0, "Verify that at least one German locale has been tested.");
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkPointSetReaderTest.cpp b/Core/Code/Testing/mitkPointSetReaderTest.cpp
index 191f019231..0601eb3a32 100644
--- a/Core/Code/Testing/mitkPointSetReaderTest.cpp
+++ b/Core/Code/Testing/mitkPointSetReaderTest.cpp
@@ -1,66 +1,65 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSet.h"
#include "mitkPointSetReader.h"
#include "mitkTestingMacros.h"
/**
* Test for the class "mitkPointSetReader".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test data set for the tests (see CMakeLists.txt).
*/
int mitkPointSetReaderTest(int argc , char* argv[])
{
// always start with this!
MITK_TEST_BEGIN("PointSetReader")
MITK_TEST_CONDITION_REQUIRED(argc == 2,"Testing invocation")
// let's create an object of our class
mitk::PointSetReader::Pointer myPointSetReader = mitk::PointSetReader::New();
MITK_TEST_CONDITION_REQUIRED(myPointSetReader.IsNotNull(),"Testing instantiation")
// testing set / get name with invalid data
std::string testName = "test1";
myPointSetReader->SetFileName( testName );
MITK_TEST_CONDITION_REQUIRED( myPointSetReader->GetFileName()== testName, "Testing set / get file name methods!");
// testing file reading with invalid data
MITK_TEST_CONDITION_REQUIRED( !myPointSetReader->CanReadFile(testName,"",""), "Testing CanReadFile() method with invalid input file name!");
myPointSetReader->Update();
MITK_TEST_CONDITION_REQUIRED( !myPointSetReader->GetSuccess(), "Testing GetSuccess() with invalid input file name!");
// testing file reading with invalid data
myPointSetReader->SetFileName(argv[1]);
MITK_TEST_CONDITION_REQUIRED( myPointSetReader->CanReadFile(argv[1], "", ""), "Testing CanReadFile() method with valid input file name!");
myPointSetReader->Modified();
myPointSetReader->Update();
MITK_TEST_CONDITION_REQUIRED( myPointSetReader->GetSuccess(), "Testing GetSuccess() with valid input file name!");
// evaluate if the read point set is correct
mitk::PointSet::Pointer resultPS = myPointSetReader->GetOutput();
MITK_TEST_CONDITION_REQUIRED( resultPS.IsNotNull(), "Testing output generation!");
MITK_TEST_CONDITION_REQUIRED( resultPS->GetTimeSteps() == 14, "Testing output time step generation!"); // CAVE: Only valid with the specified test data!
MITK_TEST_CONDITION_REQUIRED( resultPS->GetPointSet(resultPS->GetTimeSteps()-1)->GetNumberOfPoints() == 0, "Testing output time step generation with empty time step!"); // CAVE: Only valid with the specified test data!
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkPointSetTest.cpp b/Core/Code/Testing/mitkPointSetTest.cpp
index 7e8a6cec4f..474c05a250 100644
--- a/Core/Code/Testing/mitkPointSetTest.cpp
+++ b/Core/Code/Testing/mitkPointSetTest.cpp
@@ -1,621 +1,620 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include <mitkPointSet.h>
#include <mitkVector.h>
#include <mitkPointOperation.h>
#include <mitkInteractionConst.h>
#include <fstream>
class mitkPointSetTestClass { public:
static void TestGetITKPointSet(mitk::PointSet *pointSet)
{
//try to get the itkPointSet
mitk::PointSet::DataType::Pointer itkdata = NULL;
itkdata = pointSet->GetPointSet();
MITK_TEST_CONDITION( itkdata.IsNotNull(), "try to get the itkPointSet from a newly created PointSet" )
}
static void TestGetSizeIsZero(mitk::PointSet *pointSet)
{
//fresh PointSet has to be empty!
MITK_TEST_CONDITION( pointSet->GetSize() == 0, "check if the PointSet size is 0 " )
}
static void TestIsEmpty(mitk::PointSet *pointSet)
{
MITK_TEST_CONDITION(pointSet->IsEmptyTimeStep(0), "check if the PointSet is empty" )
}
static void TestCreateOperationAndAddPoint(mitk::PointSet *pointSet)
{
int id = 0;
mitk::Point3D point;
point.Fill(1);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpINSERT, point, id);
pointSet->ExecuteOperation(doOp);
MITK_TEST_CONDITION( pointSet->GetSize()==1 && pointSet->IndexExists(id), "check if added points exists" )
delete doOp;
mitk::Point3D tempPoint;
tempPoint.Fill(0);
tempPoint = pointSet->GetPoint(id);
MITK_TEST_CONDITION( point == tempPoint, "check if added point contains real value" )
}
static void TestAddSecondPoint(mitk::PointSet *pointSet)
{
//add a point directly
int id=0;
mitk::Point3D point;
mitk::FillVector3D(point, 1.0, 2.0, 3.0);
++id;
pointSet->GetPointSet()->GetPoints()->InsertElement(id, point);
MITK_TEST_CONDITION( pointSet->GetSize()==2 ||pointSet->IndexExists(id), "check if added points exists" )
mitk::Point3D tempPoint;
tempPoint.Fill(0);
tempPoint = pointSet->GetPoint(id);
MITK_TEST_CONDITION( point == tempPoint, "check if added point contains real value" )
}
static void TestIsNotEmpty(mitk::PointSet *pointSet)
{
//PointSet can not be empty!
MITK_TEST_CONDITION( !pointSet->IsEmptyTimeStep(0), "check if the PointSet is not empty " )
/*
std::cout << "check if the PointSet is not empty ";
if (pointSet->IsEmpty(0))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestSwapPointPositionUpwards(mitk::PointSet *pointSet)
{
//Check SwapPointPosition upwards
mitk::Point3D point;
mitk::Point3D tempPoint;
point = pointSet->GetPoint(1);
pointSet->SwapPointPosition(1, true);
tempPoint = pointSet->GetPoint(0);
MITK_TEST_CONDITION( point == tempPoint, "check SwapPointPosition upwards" )
/*
if(point != tempPoint)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestSwapPointPositionUpwardsNotPossible(mitk::PointSet *pointSet)
{
//Check SwapPointPosition upwards not possible
MITK_TEST_CONDITION( pointSet->SwapPointPosition(0, true)==false, "check SwapPointPosition upwards not possible" )
/*
if(pointSet->SwapPointPosition(0, true))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestSwapPointPositionDownwards(mitk::PointSet *pointSet)
{
//Check SwapPointPosition downwards
mitk::Point3D point;
mitk::Point3D tempPoint;
point = pointSet->GetPoint(0);
pointSet->SwapPointPosition(0, false);
tempPoint = pointSet->GetPoint(1);
MITK_TEST_CONDITION( point == tempPoint, "check SwapPointPosition down" )
/*
if(point != tempPoint)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestSwapPointPositionDownwardsNotPossible(mitk::PointSet * /*pointSet*/)
{
mitk::PointSet::Pointer pointSet2 = mitk::PointSet::New();
int id = 0;
mitk::Point3D point;
point.Fill(1);
pointSet2->SetPoint(id, point);
//Check SwapPointPosition downwards not possible
MITK_TEST_CONDITION(!pointSet2->SwapPointPosition(id, false), "check SwapPointPosition downwards not possible" )
/*
if(pointSet->SwapPointPosition(1, false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestPointOperationOpMove(mitk::PointSet *pointSet)
{
//check opMOVE ExecuteOperation
int id=1;
mitk::Point3D point1;
mitk::Point3D tempPoint;
point1.Fill(2);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVE, point1, id);
pointSet->ExecuteOperation(doOp);
tempPoint = pointSet->GetPoint(id);
MITK_TEST_CONDITION(tempPoint == point1 , "check PointOperation OpMove " )
delete doOp;
/*
if (tempPoint != point1)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
delete doOp;
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestPointOperationOpRemove(mitk::PointSet *pointSet)
{
//check OpREMOVE ExecuteOperation
int id=0;
mitk::Point3D point;
mitk::Point3D tempPoint;
point = pointSet->GetPoint(id);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpREMOVE, point, id);
pointSet->ExecuteOperation(doOp);
tempPoint = pointSet->GetPoint(id);
MITK_TEST_CONDITION(!pointSet->IndexExists(id) , "check PointOperation OpREMOVE " )
delete doOp;
/*
if(pointSet->IndexExists(id))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
delete doOp;
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestPointOperationOpSelectPoint(mitk::PointSet *pointSet)
{
mitk::Point3D point4;
//check OpSELECTPOINT ExecuteOperation
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpSELECTPOINT, point4,4);
pointSet->ExecuteOperation(doOp);
MITK_TEST_CONDITION(pointSet->GetSelectInfo(4) , "check PointOperation OpSELECTPOINT " )
delete doOp;
/*
if (!pointSet->GetSelectInfo(4))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
delete doOp;
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestGetNumberOfSelected(mitk::PointSet *pointSet)
{
// check GetNumeberOfSelected
MITK_TEST_CONDITION(pointSet->GetNumberOfSelected() == 1 , "check GetNumeberOfSelected " )
/*
if(pointSet->GetNumberOfSelected() != 1)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestSearchSelectedPoint(mitk::PointSet *pointSet)
{
// check SearchSelectedPoint
MITK_TEST_CONDITION(pointSet->SearchSelectedPoint() == 4 , "check SearchSelectedPoint " )
/*
if( pointSet->SearchSelectedPoint() != 4)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestOpDeselectPoint(mitk::PointSet *pointSet)
{
//check OpDESELECTPOINT ExecuteOperation
mitk::Point3D point4;
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpDESELECTPOINT, point4,4);
pointSet->ExecuteOperation(doOp);
MITK_TEST_CONDITION(!pointSet->GetSelectInfo(4) , "check PointOperation OpDESELECTPOINT " )
MITK_TEST_CONDITION(pointSet->GetNumberOfSelected() == 0 , "check GetNumeberOfSelected " )
delete doOp;
/*
if (pointSet->GetSelectInfo(4))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
delete doOp;
std::cout<<"[PASSED]"<<std::endl;
if(pointSet->GetNumberOfSelected() != 0)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestOpMovePointUp(mitk::PointSet *pointSet)
{
//check OpMOVEPOINTUP ExecuteOperation
int id = 4;
mitk::Point3D point4;
mitk::Point3D point;
mitk::Point3D tempPoint;
point = pointSet->GetPoint(id);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTUP, point4, id);
pointSet->ExecuteOperation(doOp);
tempPoint = pointSet->GetPoint(id-1);
MITK_TEST_CONDITION(tempPoint == point , "check PointOperation OpMOVEPOINTUP " )
delete doOp;
/*
if (tempPoint != point)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
delete doOp;
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestOpMovePointDown(mitk::PointSet *pointSet)
{
//check OpMOVEPOINTDown ExecuteOperation
int id = 2;
mitk::Point3D point;
mitk::Point3D point2;
mitk::Point3D tempPoint;
point = pointSet->GetPoint(id);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTDOWN, point2, id);
pointSet->ExecuteOperation(doOp);
tempPoint = pointSet->GetPoint(id+1);
MITK_TEST_CONDITION(tempPoint == point , "check PointOperation OpMOVEPOINTDOWN " )
delete doOp;
/*
if (tempPoint != point)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestSetSelectInfo(mitk::PointSet *pointSet)
{
//check SetSelectInfo
pointSet->SetSelectInfo(2, true);
MITK_TEST_CONDITION(pointSet->GetSelectInfo(2) , "check SetSelectInfo" )
/*
if (!pointSet->GetSelectInfo(2))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
delete doOp;
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestInsertPointWithPointSpecification(mitk::PointSet *pointSet)
{
//check InsertPoint with PointSpecification
mitk::Point3D point5;
mitk::Point3D tempPoint;
point5.Fill(7);
pointSet->SetPoint(5, point5, mitk::PTEDGE );
tempPoint = pointSet->GetPoint(5);
MITK_TEST_CONDITION(tempPoint == point5, "check InsertPoint with PointSpecification" )
/*
if (tempPoint != point5)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestGetPointIfExists(mitk::PointSet *pointSet)
{
//check GetPointIfExists
mitk::Point3D point5;
mitk::Point3D tempPoint;
point5.Fill(7);
mitk::PointSet::PointType tmpPoint;
pointSet->GetPointIfExists(5, &tmpPoint);
MITK_TEST_CONDITION(tmpPoint == point5, "check GetPointIfExists: " )
/*
if (tmpPoint != point5)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestCreateHoleInThePointIDs(mitk::PointSet *pointSet)
{
// create a hole in the point IDs
mitk::Point3D point;
mitk::PointSet::PointType p10, p11, p12;
p10.Fill(10.0);
p11.Fill(11.0);
p12.Fill(12.0);
pointSet->InsertPoint(10, p10);
pointSet->InsertPoint(11, p11);
pointSet->InsertPoint(12, p12);
MITK_TEST_CONDITION((pointSet->IndexExists(10) == true) || (pointSet->IndexExists(11) == true) || (pointSet->IndexExists(12) == true), "add points with id 10, 11, 12: " )
//check OpREMOVE ExecuteOperation
int id = 11;
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpREMOVE, point, id);
pointSet->ExecuteOperation(doOp);
MITK_TEST_CONDITION(!pointSet->IndexExists(id), "remove point id 11: ")
/*
if(pointSet->IndexExists(id))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
delete doOp;
std::cout<<"[PASSED]"<<std::endl;
*/
//mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTUP, p12, 12);
//pointSet->ExecuteOperation(doOp);
delete doOp;
//check OpMOVEPOINTUP ExecuteOperation
doOp = new mitk::PointOperation(mitk::OpMOVEPOINTUP, p12, 12);
pointSet->ExecuteOperation(doOp);
delete doOp;
mitk::PointSet::PointType newP10 = pointSet->GetPoint(10);
mitk::PointSet::PointType newP12 = pointSet->GetPoint(12);
MITK_TEST_CONDITION(((newP10 == p12) && (newP12 == p10)) == true, "check PointOperation OpMOVEPOINTUP for point id 12:" )
//check OpMOVEPOINTDOWN ExecuteOperation
doOp = new mitk::PointOperation(mitk::OpMOVEPOINTDOWN, p10, 10);
pointSet->ExecuteOperation(doOp);
delete doOp;
newP10 = pointSet->GetPoint(10);
newP12 = pointSet->GetPoint(12);
MITK_TEST_CONDITION(((newP10 == p10) && (newP12 == p12)) == true, "check PointOperation OpMOVEPOINTDOWN for point id 10: ")
}
static void TestOpMovePointUpOnFirstPoint(mitk::PointSet *pointSet)
{
//check OpMOVEPOINTUP on first point ExecuteOperation
mitk::PointSet::PointType p1 = pointSet->GetPoint(1);
mitk::PointSet::PointType p2 = pointSet->GetPoint(2);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTUP, p1, 1);
pointSet->ExecuteOperation(doOp);
delete doOp;
mitk::PointSet::PointType newP1 = pointSet->GetPoint(1);
mitk::PointSet::PointType newP2 = pointSet->GetPoint(2);
MITK_TEST_CONDITION(((newP1 == p1) && (newP2 == p2)) == true, "check PointOperation OpMOVEPOINTUP for point id 1: ")
/*
if (((newP1 == p1) && (newP2 == p2)) == false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
*/
}
static void TestPointContainerPointDataContainer(mitk::PointSet* ps)
{
mitk::PointSet::PointsContainer* pc = ps->GetPointSet()->GetPoints();
mitk::PointSet::PointDataContainer* pd = ps->GetPointSet()->GetPointData();
MITK_TEST_CONDITION_REQUIRED(pc->Size() == pd->Size(), "PointContainer and PointDataContainer have same size");
mitk::PointSet::PointsContainer::ConstIterator pIt = pc->Begin();
mitk::PointSet::PointDataContainer::ConstIterator dIt = pd->Begin();
bool failed = false;
for (; pIt != pc->End(); ++pIt, ++dIt)
if (pIt->Index() != dIt->Index())
{
failed = true;
break;
}
MITK_TEST_CONDITION(failed == false, "Indices in PointContainer and PointDataContainer are equal");
}
};
int mitkPointSetTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("PointSet")
//Create PointSet
mitk::PointSet::Pointer pointSet = mitk::PointSet::New();
MITK_TEST_CONDITION_REQUIRED(pointSet.IsNotNull(),"Testing instantiation")
mitkPointSetTestClass::TestGetITKPointSet(pointSet);
mitkPointSetTestClass::TestGetSizeIsZero(pointSet);
mitkPointSetTestClass::TestIsEmpty(pointSet);
mitkPointSetTestClass::TestCreateOperationAndAddPoint(pointSet);
mitk::Point3D point2, point3, point4;
point2.Fill(3);
point3.Fill(4);
point4.Fill(5);
pointSet->InsertPoint(2,point2);
pointSet->InsertPoint(3,point3);
pointSet->InsertPoint(4,point4);
mitkPointSetTestClass::TestAddSecondPoint(pointSet);
mitkPointSetTestClass::TestIsNotEmpty(pointSet);
mitkPointSetTestClass::TestSwapPointPositionUpwards(pointSet);
mitkPointSetTestClass::TestSwapPointPositionUpwardsNotPossible(pointSet);
mitkPointSetTestClass::TestSwapPointPositionDownwards(pointSet);
mitkPointSetTestClass::TestSwapPointPositionDownwardsNotPossible(pointSet);
mitkPointSetTestClass::TestPointOperationOpMove(pointSet);
mitkPointSetTestClass::TestPointOperationOpRemove(pointSet);
mitkPointSetTestClass::TestPointOperationOpSelectPoint(pointSet);
mitkPointSetTestClass::TestGetNumberOfSelected(pointSet);
mitkPointSetTestClass::TestSearchSelectedPoint(pointSet);
mitkPointSetTestClass::TestOpDeselectPoint(pointSet);
mitkPointSetTestClass::TestOpMovePointUp(pointSet);
mitkPointSetTestClass::TestOpMovePointDown(pointSet);
mitkPointSetTestClass::TestSetSelectInfo(pointSet);
mitkPointSetTestClass::TestInsertPointWithPointSpecification(pointSet);
mitkPointSetTestClass::TestGetPointIfExists(pointSet);
mitkPointSetTestClass::TestCreateHoleInThePointIDs(pointSet);
mitkPointSetTestClass::TestOpMovePointUpOnFirstPoint(pointSet);
MITK_TEST_OUTPUT(<< "Test InsertPoint(), SetPoint() and SwapPointPosition()");
mitk::PointSet::PointType point;
mitk::FillVector3D(point, 2.2, 3.3, -4.4);
/* call everything that might modify PointContainer and PointDataContainer */
pointSet->InsertPoint(17, point);
pointSet->SetPoint(4, point);
pointSet->SetPoint(7, point);
pointSet->SetPoint(2, point);
pointSet->SwapPointPosition(7, true);
pointSet->SwapPointPosition(3, true);
pointSet->SwapPointPosition(2, false);
mitkPointSetTestClass::TestPointContainerPointDataContainer(pointSet);
MITK_TEST_OUTPUT(<< "Test OpREMOVE");
mitk::PointOperation op1(mitk::OpREMOVE, mitk::Point3D(), 2); // existing index
pointSet->ExecuteOperation(&op1);
mitk::PointOperation op1b(mitk::OpREMOVE, mitk::Point3D(), 112); // non existing index
pointSet->ExecuteOperation(&op1b);
mitkPointSetTestClass::TestPointContainerPointDataContainer(pointSet);
MITK_TEST_OUTPUT(<< "Test OpMove");
mitk::PointOperation op2(mitk::OpMOVE, mitk::Point3D(), 4); // existing index
pointSet->ExecuteOperation(&op2);
mitk::PointOperation op3(mitk::OpMOVE, mitk::Point3D(), 34); // non existing index
pointSet->ExecuteOperation(&op3);
mitkPointSetTestClass::TestPointContainerPointDataContainer(pointSet);
MITK_TEST_OUTPUT(<< "Test OpINSERT");
mitk::PointOperation op4(mitk::OpINSERT, mitk::Point3D(), 38); // non existing index
pointSet->ExecuteOperation(&op4);
mitk::PointOperation op5(mitk::OpINSERT, mitk::Point3D(), 17); // existing index
pointSet->ExecuteOperation(&op5);
mitkPointSetTestClass::TestPointContainerPointDataContainer(pointSet);
mitk::PointSet::Pointer clonePS = pointSet->Clone();
mitkPointSetTestClass::TestIsNotEmpty(clonePS);
MITK_TEST_CONDITION_REQUIRED(clonePS->GetPointSetSeriesSize() == pointSet->GetPointSetSeriesSize(), "Testing cloned point set's size!");
MITK_TEST_CONDITION_REQUIRED(clonePS.GetPointer() != pointSet.GetPointer(), "Testing that the clone is not the source PS!");
MITK_TEST_CONDITION_REQUIRED(clonePS->GetGeometry()->GetCenter() == pointSet->GetGeometry()->GetCenter() , "Testing if the geometry is cloned correctly!");
MITK_TEST_CONDITION_REQUIRED(clonePS->GetPropertyList()->GetMap()->size() == pointSet->GetPropertyList()->GetMap()->size() , "Testing if the property list is cloned correctly!");
// Also testing, that clone is independent from original
mitk::Point3D p, p2;
p.Fill(42);
p2.Fill(84);
clonePS->InsertPoint(0,p);
pointSet->InsertPoint(0,p2);
p = clonePS->GetPoint(0);
p2 = pointSet->GetPoint(0);
MITK_TEST_CONDITION_REQUIRED(p != p2, "Testing that the clone is independent from source!");
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkPointSetWriterTest.cpp b/Core/Code/Testing/mitkPointSetWriterTest.cpp
index c96ce8dff5..abfcf2d273 100644
--- a/Core/Code/Testing/mitkPointSetWriterTest.cpp
+++ b/Core/Code/Testing/mitkPointSetWriterTest.cpp
@@ -1,115 +1,114 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPointSet.h"
#include "mitkPointSetWriter.h"
#include "mitkTestingMacros.h"
#include <iostream>
#include <time.h>
/**
* Test for the class "mitkPointSetFileWriter".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkPointSetWriterTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("PointSetWriter")
// let's create an object of our class
mitk::PointSetWriter::Pointer myPointSetWriter = mitk::PointSetWriter::New();
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
MITK_TEST_CONDITION_REQUIRED(myPointSetWriter.IsNotNull(),"Testing instantiation")
// write your own tests here and use the macros from mitkTestingMacros.h !!!
// do not write to std::cout and do not return from this function yourself!
// create pointSet
srand(time(NULL));
mitk::PointSet::Pointer pointSet = mitk::PointSet::New();
int numberOfPoints = rand()%100;
for (int i=0; i<=numberOfPoints+1;i++)
{
mitk::Point3D point;
point[0] = rand()%1000;
point[1] = rand()%1000;
point[2] = rand()%1000;
pointSet->SetPoint(i,point);
}
MITK_TEST_CONDITION_REQUIRED(pointSet.IsNotNull(),"PointSet creation")
try{
// test for exception handling
MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject)
myPointSetWriter->SetInput(pointSet);
myPointSetWriter->SetFileName("/usr/bin");
myPointSetWriter->Update();
MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject)
}
catch(...) {
//this means that a wrong exception (i.e. no itk:Exception) has been thrown
std::cout << "Wrong exception (i.e. no itk:Exception) caught during write [FAILED]" << std::endl;
return EXIT_FAILURE;
}
/*
MITK_TEST_OUTPUT( << "Check if filename can be set correctly: ");
myPointSetWriter->SetFileName("filename");
const char * filename = myPointSetWriter->GetFileName();
MITK_TEST_CONDITION_REQUIRED(std::string("filename") == "filename", "Filename set correctly?");
MITK_TEST_OUTPUT( << "Check if prefix can be set correctly: ");
myPointSetWriter->SetFilePrefix("pre");
const char * prefix = myPointSetWriter->GetFilePrefix();
MITK_TEST_CONDITION_REQUIRED(std::string("pre") == prefix, "Prefix set correctly?");
MITK_TEST_OUTPUT( << "Check if pattern can be set correctly: ");
myPointSetWriter->SetFilePattern("pattern");
const char * pattern = myPointSetWriter->GetFilePattern();
MITK_TEST_CONDITION_REQUIRED(std::string("pattern") == prefix, "Pattern set correctly?");
*/
MITK_TEST_OUTPUT( << "Check if input can be set correctly: ");
myPointSetWriter->SetInput(pointSet);
mitk::PointSet::Pointer pointSet2 = mitk::PointSet::New();
pointSet2 = myPointSetWriter->GetInput();
MITK_TEST_CONDITION_REQUIRED( pointSet->GetSize() == pointSet2->GetSize(), "Pointsets have unequal size" );
for(int i=0; i<pointSet->GetSize(); i++)
{
mitk::Point3D p1 = pointSet->GetPoint(i);
mitk::Point3D p2 = pointSet2->GetPoint(i);
MITK_TEST_CONDITION_REQUIRED( p1[0] == p2[0] && p1[0] == p2[0] && p1[0] == p2[0], "Pointsets aren't equal" );
}
std::vector< std::string > extensions = myPointSetWriter->GetPossibleFileExtensions();
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkPropertyListTest.cpp b/Core/Code/Testing/mitkPropertyListTest.cpp
index 1ee7ea3e4f..47c9a227cd 100644
--- a/Core/Code/Testing/mitkPropertyListTest.cpp
+++ b/Core/Code/Testing/mitkPropertyListTest.cpp
@@ -1,242 +1,241 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkPropertyList.h"
#include "mitkProperties.h"
#include "mitkLookupTables.h"
#include "mitkStringProperty.h"
#include <iostream>
int mitkPropertyListTest(int /*argc*/, char* /*argv*/[])
{
mitk::PropertyList::Pointer propList;
std::cout << "Testing mitk::PropertyList::New(): ";
propList = mitk::PropertyList::New();
if (propList.IsNull()) {
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
else {
std::cout << "[PASSED]" << std::endl;
}
mitk::BoolProperty::Pointer boolProp = mitk::BoolProperty::New(false);
mitk::BoolProperty::Pointer boolProp2 = mitk::BoolProperty::New(false);
std::cout << "Testing BoolProperty ==: ";
if (! (*boolProp2 == *boolProp) ) {
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
unsigned long tBefore,tAfter;
std::cout << "Testing SetProperty() with new key value: ";
tBefore = propList->GetMTime();
propList->SetProperty("test",boolProp);
tAfter = propList->GetMTime();
if (! ( tAfter > tBefore) ) {
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing SetProperty() with changed property value: ";
tBefore = propList->GetMTime();
propList->SetProperty("test",mitk::BoolProperty::New(true));
tAfter = propList->GetMTime();
if (! (tAfter > tBefore) ) {
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing SetProperty() with unchanged property value: ";
tBefore = propList->GetMTime();
propList->SetProperty("test",mitk::BoolProperty::New(true));
tAfter = propList->GetMTime();
if ( tBefore != tAfter ) {
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing MTime correctness when changing property value: ";
boolProp = mitk::BoolProperty::New(true);
propList->ReplaceProperty("test",boolProp);
tBefore = propList->GetMTime();
boolProp->SetValue(true);
tAfter = propList->GetMTime();
boolProp->SetValue(false);
unsigned long tAfterAll = propList->GetMTime();
if (tBefore != tAfter || tAfterAll <= tAfter) {
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing MTime correctness when calling SetProperty twice: ";
boolProp = mitk::BoolProperty::New(true);
propList->SetProperty("test",boolProp);
tBefore = propList->GetMTime();
propList->SetProperty("test",boolProp);
tAfter = propList->GetMTime();
if (tBefore != tAfter) {
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing if existing properties survive SetProperty: ";
propList->SetProperty("test",boolProp);
mitk::BaseProperty* bpBefore = propList->GetProperty("test");
propList->SetProperty("test",boolProp2);
mitk::BaseProperty* bpAfter = propList->GetProperty("test");
if (bpBefore != bpAfter || bpAfter == NULL) {
std::cout << std::endl;
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
std::cout << "Testing if existing properties survive ReplaceProperty: ";
propList->SetProperty("test",boolProp);
bpBefore = propList->GetProperty("test");
propList->ReplaceProperty("test",boolProp2);
bpAfter = propList->GetProperty("test");
if (bpBefore == bpAfter || bpAfter == NULL) {
std::cout << std::endl;
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[PASSED]" << std::endl;
//std::cout << "Testing output of PropertyList to file: ";
//if ( TestXMLWriter() )
// std::cout << "[PASSED]" << std::endl;
//else
// return EXIT_FAILURE;
std::cout << "Testing GetPropertyValue(bool): ";
mitk::BoolProperty::Pointer gpvTest = mitk::BoolProperty::New(true);
propList->SetProperty("gpvBool", gpvTest);
bool b = false;
bool getPropertyValueReturnValue = propList->GetPropertyValue<bool>("gpvBool", b);
if ((getPropertyValueReturnValue == true) && (b == gpvTest->GetValue()))
std::cout << "[PASSED]" << std::endl;
else
{
std::cout << "Oh, not goot:"
"\nWe called propList->GetPropertyValue<bool>('gpvBool', b) and it returned " << getPropertyValueReturnValue <<
"\nThen we compared b [" << b << "] and gpvTest->GetValue() [" << gpvTest->GetValue() << "]" << std::endl;
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "Testing GetPropertyValue(float): ";
mitk::FloatProperty::Pointer gpvTest2 = mitk::FloatProperty::New(3.1337);
propList->SetProperty("gpvfloat", gpvTest2);
float v = -1.23;
if ((propList->GetPropertyValue<float>("gpvfloat", v) == true) && (v == gpvTest2->GetValue()))
std::cout << "[PASSED]" << std::endl;
else
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
std::cout << "Testing GetPropertyValue(BoolLookupTable): ";
mitk::BoolLookupTable blt;
blt.SetTableValue(17, true);
propList->SetProperty("blutprop", mitk::BoolLookupTableProperty::New(blt));
try
{
mitk::BoolLookupTable blut;
if ((propList->GetPropertyValue<mitk::BoolLookupTable>("blutprop", blut) == true) && (blut.GetTableValue(17) == true))
std::cout << "[PASSED]" << std::endl;
else
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
}
catch(...)
{
std::cout << "Exception thrown! [FAILED]" << std::endl;
return EXIT_FAILURE;
}
{
std::cout << "Testing GetBoolProperty(): ";
mitk::BoolProperty::Pointer prop = mitk::BoolProperty::New(true);
propList->ReplaceProperty("test", prop);
bool v = false;
if ((propList->GetBoolProperty("test", v) == true) && (v == prop->GetValue()))
std::cout << "[PASSED]" << std::endl;
else
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
}
{
std::cout << "Testing GetIntProperty(): ";
mitk::IntProperty::Pointer prop = mitk::IntProperty::New(31337);
propList->ReplaceProperty("test", prop);
int v = 1;
if ((propList->GetIntProperty("test", v) == true) && (v == prop->GetValue()))
std::cout << "[PASSED]" << std::endl;
else
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
}
{
std::cout << "Testing GetFloatProperty(): ";
mitk::FloatProperty::Pointer prop = mitk::FloatProperty::New(31.337);
propList->ReplaceProperty("test", prop);
float v = 1.2;
if ((propList->GetFloatProperty("test", v) == true) && (v == prop->GetValue()))
std::cout << "[PASSED]" << std::endl;
else
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
}
{
std::cout << "Testing GetStringProperty(): ";
mitk::StringProperty::Pointer prop = mitk::StringProperty::New("MITK");
propList->ReplaceProperty("test", prop);
std::string v = "";
if ((propList->GetStringProperty("test", v) == true) && (v == prop->GetValue()))
std::cout << "[PASSED]" << std::endl;
else
{
std::cout << "[FAILED]" << std::endl;
return EXIT_FAILURE;
}
}
std::cout << "[TEST DONE]" << std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkPropertyTest.cpp b/Core/Code/Testing/mitkPropertyTest.cpp
index 38567a5b2f..c40b5ab898 100644
--- a/Core/Code/Testing/mitkPropertyTest.cpp
+++ b/Core/Code/Testing/mitkPropertyTest.cpp
@@ -1,376 +1,375 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include <mitkProperties.h>
#include <mitkStringProperty.h>
#include <mitkLookupTables.h>
#include <mitkAnnotationProperty.h>
#include <mitkClippingProperty.h>
#include <mitkColorProperty.h>
#include <mitkLevelWindowProperty.h>
#include <mitkSmartPointerProperty.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkWeakPointerProperty.h>
#include <mitkLookupTableProperty.h>
#include <itkCommand.h>
struct PropertyModifiedListener
{
typedef itk::SimpleMemberCommand<PropertyModifiedListener> CmdType;
PropertyModifiedListener() : m_Modified(false), m_Cmd(CmdType::New())
{
m_Cmd->SetCallbackFunction(this, &PropertyModifiedListener::Modified);
}
void Modified()
{
m_Modified = true;
}
bool Pop()
{
bool b = m_Modified;
m_Modified = false;
return b;
}
bool m_Modified;
CmdType::Pointer m_Cmd;
};
template<class T>
void TestPropInequality(T prop, T prop2)
{
mitk::BaseProperty::Pointer baseProp2(prop2.GetPointer());
MITK_TEST_CONDITION_REQUIRED(!(*prop == *prop2), "Test inequality 1");
MITK_TEST_CONDITION_REQUIRED(!(*prop == *baseProp2), "Test polymorphic inequality 1");
MITK_TEST_CONDITION_REQUIRED(!(*baseProp2 == *prop), "Test polymorphic inequality 2");
}
template<class T>
void TestPropAssignment(T prop, T prop2, const std::string& strProp)
{
PropertyModifiedListener l;
unsigned long tag = prop->AddObserver(itk::ModifiedEvent(), l.m_Cmd.GetPointer());
mitk::BaseProperty::Pointer baseProp2(prop2.GetPointer());
*prop = *baseProp2;
MITK_TEST_CONDITION_REQUIRED(l.Pop(), "Test modified event");
std::string msg = std::string("Test assignment [") + prop->GetValueAsString() + " == " + strProp + "]";
MITK_TEST_CONDITION_REQUIRED(prop->GetValueAsString() == strProp, msg);
MITK_TEST_CONDITION_REQUIRED(*prop == *prop2, "Test equality");
MITK_TEST_CONDITION_REQUIRED(*prop == *baseProp2, "Test equality");
MITK_TEST_CONDITION_REQUIRED(*baseProp2 == *prop, "Test polymorphic equality");
prop->RemoveObserver(tag);
}
template<class T>
void TestPropPolymorphicAssignment(T prop, T prop2, const std::string& strProp)
{
mitk::BaseProperty::Pointer baseProp(prop.GetPointer());
PropertyModifiedListener l;
unsigned long tag = baseProp->AddObserver(itk::ModifiedEvent(), l.m_Cmd.GetPointer());
*baseProp = *prop2;
MITK_TEST_CONDITION_REQUIRED(l.Pop(), "Test modified event");
std::string msg = std::string("Test polymorphic assignment [") + baseProp->GetValueAsString() + " == " + strProp + "]";
MITK_TEST_CONDITION_REQUIRED(baseProp->GetValueAsString() == strProp, msg);
MITK_TEST_CONDITION_REQUIRED(*prop == *prop2, "Test equality");
MITK_TEST_CONDITION_REQUIRED(*prop2 == *baseProp, "Test equality");
MITK_TEST_CONDITION_REQUIRED(*baseProp == *prop2, "Test polymorphic equality");
baseProp->RemoveObserver(tag);
}
template<class T>
void TestProperty(const typename T::ValueType& v1, const typename T::ValueType& v2,
const std::string& strV1, const std::string& strV2)
{
PropertyModifiedListener l;
typename T::Pointer prop = T::New(v1);
MITK_TEST_OUTPUT(<< "**** Test [" << prop->GetNameOfClass() << "] ****");
MITK_TEST_CONDITION_REQUIRED(prop->GetValue() == v1, "Test constructor");
std::string msg = std::string("Test GetValueAsString() [") + prop->GetValueAsString() + " == " + strV1 + "]";
MITK_TEST_CONDITION_REQUIRED(prop->GetValueAsString() == strV1, msg);
typename T::Pointer prop2 = T::New();
prop2->AddObserver(itk::ModifiedEvent(), l.m_Cmd.GetPointer());
MITK_TEST_CONDITION_REQUIRED(!l.m_Modified, "Test modified");
prop2->SetValue(v2);
MITK_TEST_CONDITION_REQUIRED(l.Pop(), "Test modified");
MITK_TEST_CONDITION_REQUIRED(prop2->GetValue() == v2, "Test SetValue()");
prop2->SetValue(v2);
MITK_TEST_CONDITION_REQUIRED(!l.Pop(), "Test for no modification");
TestPropInequality(prop, prop2);
TestPropAssignment(prop, prop2, strV2);
prop->SetValue(v1);
TestPropPolymorphicAssignment(prop2, prop, strV1);
}
void TestGenericProperties()
{
TestProperty<mitk::BoolProperty>(false, true, "0", "1");
TestProperty<mitk::IntProperty>(3, 5, "3", "5");
TestProperty<mitk::FloatProperty>(0.3f, -23.5f, "0.3", "-23.5");
TestProperty<mitk::DoubleProperty>(64.1f, 2.34f, "64.1", "2.34");
{
mitk::Vector3D p1; p1[0] = 2.0; p1[1] = 3.0; p1[2] = 4.0;
mitk::Vector3D p2; p2[0] =-1.0; p2[1] = 2.0; p2[2] = 3.0;
TestProperty<mitk::Vector3DProperty>(p1, p2, "[2, 3, 4]", "[-1, 2, 3]");
}
{
mitk::Point3D p1; p1[0] = 2.0; p1[1] = 3.0; p1[2] = 4.0;
mitk::Point3D p2; p2[0] =-1.0; p2[1] = 2.0; p2[2] = 3.0;
TestProperty<mitk::Point3dProperty>( p1, p2, "[2, 3, 4]", "[-1, 2, 3]");
}
{
mitk::Point4D p1; p1[0] = 2.0; p1[1] = 3.0; p1[2] = 4.0; p1[3] =-2.0;
mitk::Point4D p2; p2[0] =-1.0; p2[1] = 2.0; p2[2] = 3.0; p2[3] = 5.0;
TestProperty<mitk::Point4dProperty>(p1, p2, "[2, 3, 4, -2]", "[-1, 2, 3, 5]");
}
{
mitk::Point3I p1; p1[0] = 2; p1[1] = 3; p1[2] = 4;
mitk::Point3I p2; p2[0] = 8; p2[1] = 7; p2[2] = 6;
TestProperty<mitk::Point3iProperty>(p1, p2, "[2, 3, 4]", "[8, 7, 6]");
}
{
mitk::FloatLookupTable lut1;
lut1.SetTableValue(1, 0.3f);
lut1.SetTableValue(4, 323.7f);
mitk::FloatLookupTable lut2;
lut2.SetTableValue(6, -0.3f);
lut2.SetTableValue(2, 25.7f);
TestProperty<mitk::FloatLookupTableProperty>(lut1, lut2, "[1 -> 0.3, 4 -> 323.7]", "[2 -> 25.7, 6 -> -0.3]");
}
{
mitk::BoolLookupTable lut1;
lut1.SetTableValue(3, false);
lut1.SetTableValue(5, true);
mitk::BoolLookupTable lut2;
lut2.SetTableValue(1, false);
lut2.SetTableValue(2, false);
TestProperty<mitk::BoolLookupTableProperty>(lut1, lut2, "[3 -> 0, 5 -> 1]", "[1 -> 0, 2 -> 0]");
}
{
mitk::IntLookupTable lut1;
lut1.SetTableValue(5, -12);
lut1.SetTableValue(7, 3);
mitk::IntLookupTable lut2;
lut2.SetTableValue(4, -6);
lut2.SetTableValue(8, -45);
TestProperty<mitk::IntLookupTableProperty>(lut1, lut2, "[5 -> -12, 7 -> 3]", "[4 -> -6, 8 -> -45]");
}
{
mitk::StringLookupTable lut1;
lut1.SetTableValue(0, "a");
lut1.SetTableValue(2, "b");
mitk::StringLookupTable lut2;
lut2.SetTableValue(0, "a");
lut2.SetTableValue(2, "c");
TestProperty<mitk::StringLookupTableProperty>(lut1, lut2, "[0 -> a, 2 -> b]", "[0 -> a, 2 -> c]");
}
}
void TestAnnotationProperty()
{
PropertyModifiedListener l;
std::string label1("Label1");
mitk::Point3D point1; point1[0] = 3; point1[1] = 5; point1[2] = -4;
std::string str1 = "Label1[3, 5, -4]";
std::string label2("Label2");
mitk::Point3D point2; point2[0] = -2; point2[1] = 8; point2[2] = -4;
std::string str2 = "Label2[-2, 8, -4]";
mitk::AnnotationProperty::Pointer prop = mitk::AnnotationProperty::New(label1, point1);
MITK_TEST_OUTPUT(<< "**** Test [" << prop->GetNameOfClass() << "] ****");
MITK_TEST_CONDITION_REQUIRED(prop->GetLabel() == label1 && prop->GetPosition() == point1, "Test constructor");
std::string msg = std::string("Test GetValueAsString() [") + prop->GetValueAsString() + " == " + str1 + "]";
MITK_TEST_CONDITION_REQUIRED(prop->GetValueAsString() == str1, msg);
mitk::AnnotationProperty::Pointer prop2 = mitk::AnnotationProperty::New();
prop2->AddObserver(itk::ModifiedEvent(), l.m_Cmd.GetPointer());
MITK_TEST_CONDITION_REQUIRED(!l.m_Modified, "Test not modified");
prop2->SetLabel(label2);
MITK_TEST_CONDITION_REQUIRED(l.Pop(), "Test modified");
prop2->SetPosition(point2);
MITK_TEST_CONDITION_REQUIRED(l.Pop(), "Test modified");
MITK_TEST_CONDITION_REQUIRED(prop2->GetLabel() == label2 && prop2->GetPosition() == point2, "Test Setter");
prop2->SetLabel(label2);
MITK_TEST_CONDITION_REQUIRED(!l.Pop(), "Test for no modification");
prop2->SetPosition(point2);
MITK_TEST_CONDITION_REQUIRED(!l.Pop(), "Test for no modification");
TestPropInequality(prop, prop2);
TestPropAssignment(prop, prop2, str2);
prop->SetLabel(label1);
prop->SetPosition(point1);
TestPropPolymorphicAssignment(prop2, prop, str1);
}
void TestClippingProperty()
{
PropertyModifiedListener l;
bool enabled1 = true;
mitk::Point3D point1; point1[0] = 3; point1[1] = 5; point1[2] = -4;
mitk::Vector3D vec1; vec1[0] = 0; vec1[1] = 2; vec1[2] = -1;
std::string str1 = "1[3, 5, -4][0, 2, -1]";
bool enabled2 = false;
mitk::Point3D point2; point2[0] = -2; point2[1] = 8; point2[2] = -4;
mitk::Vector3D vec2; vec2[0] = 0; vec2[1] = 2; vec2[2] = 4;
std::string str2 = "0[-2, 8, -4][0, 2, 4]";
mitk::ClippingProperty::Pointer prop = mitk::ClippingProperty::New(point1, vec1);
MITK_TEST_OUTPUT(<< "**** Test [" << prop->GetNameOfClass() << "] ****");
MITK_TEST_CONDITION_REQUIRED(prop->GetClippingEnabled() == enabled1 && prop->GetOrigin() == point1 && prop->GetNormal() == vec1, "Test constructor");
std::string msg = std::string("Test GetValueAsString() [") + prop->GetValueAsString() + " == " + str1 + "]";
MITK_TEST_CONDITION_REQUIRED(prop->GetValueAsString() == str1, msg);
mitk::ClippingProperty::Pointer prop2 = mitk::ClippingProperty::New();
prop2->AddObserver(itk::ModifiedEvent(), l.m_Cmd.GetPointer());
MITK_TEST_CONDITION_REQUIRED(!l.m_Modified, "Test not modified");
prop2->SetClippingEnabled(enabled2);
MITK_TEST_CONDITION_REQUIRED(!l.Pop(), "Test not modified");
prop2->SetOrigin(point2);
MITK_TEST_CONDITION_REQUIRED(l.Pop(), "Test modified");
prop2->SetNormal(vec2);
MITK_TEST_CONDITION_REQUIRED(l.Pop(), "Test modified");
MITK_TEST_CONDITION_REQUIRED(prop2->GetClippingEnabled() == enabled2 && prop2->GetOrigin() == point2 && prop2->GetNormal() == vec2, "Test Setter");
prop2->SetClippingEnabled(enabled2);
MITK_TEST_CONDITION_REQUIRED(!l.Pop(), "Test for no modification");
prop2->SetOrigin(point2);
MITK_TEST_CONDITION_REQUIRED(!l.Pop(), "Test for no modification");
prop2->SetNormal(vec2);
MITK_TEST_CONDITION_REQUIRED(!l.Pop(), "Test for no modification");
TestPropInequality(prop, prop2);
TestPropAssignment(prop, prop2, str2);
prop->SetClippingEnabled(enabled1);
prop->SetOrigin(point1);
prop->SetNormal(vec1);
TestPropPolymorphicAssignment(prop2, prop, str1);
}
int mitkPropertyTest(int /* argc */, char* /*argv*/[])
{
MITK_TEST_BEGIN("Testing MITK Properties")
TestGenericProperties();
TestAnnotationProperty();
TestClippingProperty();
mitk::Color c1; c1[0] = 0.2; c1[1] = 0.6; c1[2] = 0.8;
mitk::Color c2; c2[0] = 0.2; c2[1] = 0.4; c2[2] = 0.1;
TestProperty<mitk::ColorProperty>(c1, c2, "0.2 0.6 0.8", "0.2 0.4 0.1");
mitk::LevelWindow lw1(50, 100);
mitk::LevelWindow lw2(120, 30);
TestProperty<mitk::LevelWindowProperty>(lw1, lw2, "L:50 W:100", "L:120 W:30");
{
itk::Object::Pointer sp1 = itk::Object::New();
itk::Object::Pointer sp2 = itk::Object::New();
// to generate the UIDs, we set the smartpointers
mitk::SmartPointerProperty::Pointer spp1 = mitk::SmartPointerProperty::New(sp1.GetPointer());
mitk::SmartPointerProperty::Pointer spp2 = mitk::SmartPointerProperty::New(sp2.GetPointer());
TestProperty<mitk::SmartPointerProperty>(sp1, sp2, spp1->GetReferenceUIDFor(sp1), spp2->GetReferenceUIDFor(sp2));
}
TestProperty<mitk::StringProperty>("1", "2", "1", "2");
{
mitk::TransferFunction::Pointer tf1 = mitk::TransferFunction::New();
mitk::TransferFunction::Pointer tf2 = mitk::TransferFunction::New();
tf2->AddScalarOpacityPoint(0.4, 0.8);
std::stringstream ss;
ss << tf1;
std::string strTF1 = ss.str();
ss.str("");
ss << tf2;
std::string strTF2 = ss.str();
TestProperty<mitk::TransferFunctionProperty>(tf1, tf2, strTF1, strTF2);
}
{
itk::Object::Pointer sp1 = itk::Object::New();
itk::Object::Pointer sp2 = itk::Object::New();
mitk::WeakPointerProperty::ValueType wp1 = sp1.GetPointer();
mitk::WeakPointerProperty::ValueType wp2 = sp2.GetPointer();
std::stringstream ss;
ss << sp1.GetPointer();
std::string str1 = ss.str();
ss.str("");
ss << sp2.GetPointer();
std::string str2 = ss.str();
TestProperty<mitk::WeakPointerProperty>(wp1, wp2, str1, str2);
}
{
mitk::LookupTable::Pointer lut1 = mitk::LookupTable::New();
lut1->GetVtkLookupTable()->SetTableValue(0, 0.2, 0.3, 0.4);
mitk::LookupTable::Pointer lut2 = mitk::LookupTable::New();
lut2->GetVtkLookupTable()->SetTableValue(0, 0.2, 0.4, 0.4);
std::stringstream ss;
ss << lut1;
std::string strLUT1 = ss.str();
ss.str("");
ss << lut2;
std::string strLUT2 = ss.str();
TestProperty<mitk::LookupTableProperty>(lut1, lut2, strLUT1, strLUT2);
}
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkRawImageFileReaderTest.cpp b/Core/Code/Testing/mitkRawImageFileReaderTest.cpp
index ce6fcd594c..15dced0fe9 100644
--- a/Core/Code/Testing/mitkRawImageFileReaderTest.cpp
+++ b/Core/Code/Testing/mitkRawImageFileReaderTest.cpp
@@ -1,31 +1,30 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRawImageFileReader.h"
int mitkRawImageFileReaderTest(int /*argc*/, char* /*argv*/[])
{
// instantiation
mitk::RawImageFileReader::Pointer reader = mitk::RawImageFileReader::New();
// freeing
reader = NULL;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkRegistrationBaseTest.cpp b/Core/Code/Testing/mitkRegistrationBaseTest.cpp
index 47cd81df7e..6478c091b8 100644
--- a/Core/Code/Testing/mitkRegistrationBaseTest.cpp
+++ b/Core/Code/Testing/mitkRegistrationBaseTest.cpp
@@ -1,49 +1,48 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 15228 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkRegistrationBase.h"
int mitkRegistrationBaseTest(int /*argc*/, char* /*argv*/[])
{
//Create Image out of nowhere
mitk::Image::Pointer image;
mitk::PixelType pt(typeid(int));
unsigned int dim[]={100,100,20};
std::cout << "Creating image: ";
image = mitk::Image::New();
//image->DebugOn();
image->Initialize(mitk::PixelType(typeid(int)), 3, dim);
int *p = (int*)image->GetData();
int size = dim[0]*dim[1]*dim[2];
int i;
for(i=0; i<size; ++i, ++p)
*p=i;
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Constructor: ";
mitk::RegistrationBase::Pointer registrationBase = mitk::RegistrationBase::New();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Set Reference Image: ";
registrationBase->SetReferenceImage(image);
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
\ No newline at end of file
diff --git a/Core/Code/Testing/mitkRenderingManagerTest.cpp b/Core/Code/Testing/mitkRenderingManagerTest.cpp
index 25bb53a45d..faf9ec7794 100644
--- a/Core/Code/Testing/mitkRenderingManagerTest.cpp
+++ b/Core/Code/Testing/mitkRenderingManagerTest.cpp
@@ -1,222 +1,221 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRenderingManager.h"
#include "mitkProperties.h"
#include "mitkGlobalInteraction.h"
#include "mitkVtkPropRenderer.h"
#include "mitkStandaloneDataStorage.h"
#include "vtkRenderWindow.h"
#include "mitkTestingMacros.h"
#include <vtkCubeSource.h>
#include "mitkSurface.h"
//Propertylist Test
/**
* Simple example for a test for the class "RenderingManager".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
class mitkRenderingManagerTestClass
{
public:
static void TestPropertyList(mitk::RenderingManager::Pointer renderingManager)
{
mitk::PropertyList::Pointer propertyList = renderingManager->GetPropertyList();
MITK_TEST_CONDITION(renderingManager->GetPropertyList().IsNotNull(), "Testing if the constructor set the propertylist" )
//check if the default properties are set
renderingManager->SetProperty("booltest", mitk::BoolProperty::New(true));
mitk::BoolProperty* prop = dynamic_cast<mitk::BoolProperty*>( renderingManager->GetProperty("booltest") );
MITK_TEST_CONDITION(prop->GetValue(), "Testing if getting the bool property" )
MITK_TEST_CONDITION(propertyList == renderingManager->GetPropertyList(), "Testing if the propertylist has changed during the last tests" )
}
static void TestSurfaceLoading( mitk::RenderingManager::Pointer renderingManager )
{
// create and render two dimensional surface
vtkCubeSource* plane = vtkCubeSource::New();
double planeBounds[] = { -1.0, 1.0, -1.0, 1.0, 0.0, 0.0 };
double cubeBounds[] = { -0.5, 0.5, -0.5, 0.5, -0.5, 0.5 };
plane->SetBounds( planeBounds );
plane->SetCenter( 0.0, 0.0, 0.0 );
vtkPolyData* polys = plane->GetOutput();
mitk::Surface::Pointer mitkPlane = mitk::Surface::New();
mitkPlane->SetVtkPolyData( polys );
plane->Delete();
mitk::DataNode::Pointer planeNode = mitk::DataNode::New();
planeNode->SetData( mitkPlane );
renderingManager->GetDataStorage()->Add( planeNode );
mitk::Geometry3D::Pointer planeGeometry = mitk::Geometry3D::New();
planeGeometry->SetFloatBounds( planeBounds );
MITK_TEST_CONDITION( renderingManager->InitializeViews( planeGeometry ), "Testing if two dimensional Geometry3Ds can be displayed" )
//clear rendering
renderingManager->GetDataStorage()->Remove( planeNode );
renderingManager->InitializeViews();
// create and render three dimensional surface
vtkCubeSource* cube = vtkCubeSource::New();
cube->SetBounds( cubeBounds );
cube->SetCenter( 0.0, 0.0, 0.0 );
vtkPolyData* polyCube = cube->GetOutput();
mitk::Surface::Pointer mitkCube = mitk::Surface::New();
mitkCube->SetVtkPolyData( polyCube );
cube->Delete();
mitk::DataNode::Pointer cubeNode = mitk::DataNode::New();
cubeNode->SetData( mitkCube );
renderingManager->GetDataStorage()->Add( cubeNode );
mitk::Geometry3D::Pointer cubeGeometry = mitk::Geometry3D::New();
cubeGeometry->SetFloatBounds( cubeBounds );
MITK_TEST_CONDITION( renderingManager->InitializeViews( cubeGeometry ), "Testing if three dimensional Geometry3Ds can be displayed" )
//clear rendering
renderingManager->GetDataStorage()->Remove( cubeNode );
renderingManager->InitializeViews();
}
static void TestAddRemoveRenderWindow()
{
mitk::RenderingManager::Pointer myRenderingManager = mitk::RenderingManager::New();
//mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New();
//myRenderingManager->SetDataStorage(ds);
{
vtkRenderWindow* vtkRenWin = vtkRenderWindow::New();
MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetAllRegisteredRenderWindows().size() == 0, "Render window list must be empty")
// Add Render Window
myRenderingManager->AddRenderWindow(vtkRenWin);
MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetAllRegisteredRenderWindows().size() == 1, "Render window list must contain one item")
// Remove Render Window
myRenderingManager->RemoveRenderWindow(vtkRenWin);
MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetAllRegisteredRenderWindows().size() == 0, "Render window list must be empty")
// Test if the Render Window was removed properly. This should not do anything
MITK_TEST_OUTPUT(<< "Call RequestUpdate on removed render window")
myRenderingManager->RequestUpdate(vtkRenWin);
MITK_TEST_OUTPUT(<< "Call ForceImmediateUpdate on removed render window")
myRenderingManager->ForceImmediateUpdate(vtkRenWin);
MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetAllRegisteredRenderWindows().size() == 0, "Render window list must be empty")
// Delete vtk variable correctly
vtkRenWin->Delete();
}
// Check that the previous calls to RequestUpdate and ForceImmediateUpdate
// did not modify the internal vtkRenderWindow list. This should not crash.
MITK_TEST_OUTPUT(<< "Call RequestUpdateAll after deleting render window")
myRenderingManager->RequestUpdateAll();
MITK_TEST_OUTPUT(<< "Call ForceImmediateUpdateAll after deleting render window")
myRenderingManager->ForceImmediateUpdateAll();
}
}; //mitkDataNodeTestClass
int mitkRenderingManagerTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("RenderingManager")
mitkRenderingManagerTestClass::TestAddRemoveRenderWindow();
mitk::RenderingManager::Pointer globalRenderingManager = mitk::RenderingManager::GetInstance();
MITK_TEST_CONDITION_REQUIRED(globalRenderingManager.IsNotNull(),"Testing instantiation of global static instance")
mitk::RenderingManager::Pointer myRenderingManager = mitk::RenderingManager::New();
MITK_TEST_CONDITION_REQUIRED(myRenderingManager.IsNotNull(),"Testing instantiation of second 'local' instance")
MITK_TEST_CONDITION_REQUIRED(myRenderingManager != globalRenderingManager ,"Testing whether global instance equals new local instance (must not be!)")
mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New();
mitk::StandaloneDataStorage::Pointer ds2 = mitk::StandaloneDataStorage::New();
mitk::GlobalInteraction::Pointer gi = mitk::GlobalInteraction::New();
gi->Initialize("global");
myRenderingManager->SetDataStorage(ds);
myRenderingManager->SetGlobalInteraction(gi);
vtkRenderWindow* vtkRenWin = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer br = mitk::VtkPropRenderer::New("testingBR", vtkRenWin, myRenderingManager);
mitk::BaseRenderer::AddInstance(vtkRenWin,br);
myRenderingManager->AddRenderWindow(vtkRenWin);
MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetDataStorage() == ds, "Testing the setter and getter for internal DataStorage")
MITK_TEST_CONDITION_REQUIRED(myRenderingManager->GetGlobalInteraction() ==gi, "Testing the setter and getter for internal GlobalInteraction")
MITK_TEST_CONDITION_REQUIRED(br->GetDataStorage() == ds,"Testing if internal DataStorage has been set correctly for registered BaseRenderer")
myRenderingManager->SetDataStorage(ds2);
MITK_TEST_CONDITION_REQUIRED(br->GetDataStorage() == ds2,"Testing if change of internal DataStorage has been forwarded correctly to registered BaseRenderer")
mitkRenderingManagerTestClass::TestPropertyList(myRenderingManager);
mitkRenderingManagerTestClass::TestSurfaceLoading( myRenderingManager );
// write your own tests here and use the macros from mitkTestingMacros.h !!!
// do not write to std::cout and do not return from this function yourself!
//Remove Render Window
myRenderingManager->RemoveRenderWindow(vtkRenWin);
//Delete vtk variable correctly
vtkRenWin->Delete();
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkRenderingTestHelper.cpp b/Core/Code/Testing/mitkRenderingTestHelper.cpp
index d41f993c81..98fce2fd8d 100644
--- a/Core/Code/Testing/mitkRenderingTestHelper.cpp
+++ b/Core/Code/Testing/mitkRenderingTestHelper.cpp
@@ -1,88 +1,87 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-03-31 17:34:48 +0200 (Wed, 31 Mar 2010) $
-Version: $Revision: 21985 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkRenderingTestHelper.h"
#include "mitkStandaloneDataStorage.h"
#include <vtkRenderWindow.h>
#include <vtkPNGWriter.h>
#include <vtkRenderLargeImage.h>
#include <mitkRenderWindow.h>
#include <mitkGlobalInteraction.h>
#include <vtkRenderWindowInteractor.h>
#include <mitkSliceNavigationController.h>
#include <mitkNodePredicateDataType.h>
#include <mitkLevelWindowProperty.h>
mitkRenderingTestHelper::mitkRenderingTestHelper(int width, int height, mitk::DataStorage *ds)
{
// Global interaction must(!) be initialized
mitk::GlobalInteraction::GetInstance()->Initialize("global");
m_RenderWindow = mitk::RenderWindow::New();
m_RenderWindow->GetRenderer()->SetDataStorage(ds);
m_RenderWindow->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard2D);
this->GetVtkRenderWindow()->SetSize( width, height );
mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Transversal);
mitk::TimeSlicedGeometry::Pointer geo = ds->ComputeBoundingGeometry3D(ds->GetAll());
//Level Window Property
// ds->GetNode(mitk::NodePredicateDataType::New("Image"))->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(254.0, 1.0) ) );
mitk::RenderingManager::GetInstance()->InitializeViews( geo );
mitk::RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow->GetVtkRenderWindow());
//use this to actually show the iamge in a renderwindow
// this->GetVtkRenderWindow()->Render();
// this->GetVtkRenderWindow()->GetInteractor()->Start();
}
mitkRenderingTestHelper::~mitkRenderingTestHelper()
{
}
vtkRenderer* mitkRenderingTestHelper::GetVtkRenderer()
{
return m_RenderWindow->GetRenderer()->GetVtkRenderer();
}
vtkRenderWindow* mitkRenderingTestHelper::GetVtkRenderWindow()
{
return m_RenderWindow->GetVtkRenderWindow();
}
//method to save a screenshot of the renderwindow (e.g. create a reference screenshot)
void mitkRenderingTestHelper::SaveAsPNG(std::string fileName)
{
vtkSmartPointer<vtkRenderer> renderer = this->GetVtkRenderer();
bool doubleBuffering( renderer->GetRenderWindow()->GetDoubleBuffer() );
renderer->GetRenderWindow()->DoubleBufferOff();
vtkSmartPointer<vtkRenderLargeImage> magnifier = vtkSmartPointer<vtkRenderLargeImage>::New();
magnifier->SetInput(renderer);
magnifier->SetMagnification(1.0);
vtkSmartPointer<vtkImageWriter> fileWriter = vtkSmartPointer<vtkPNGWriter>::New();
fileWriter->SetInput(magnifier->GetOutput());
fileWriter->SetFileName(fileName.c_str());
fileWriter->Write();
renderer->GetRenderWindow()->SetDoubleBuffer(doubleBuffering);
}
diff --git a/Core/Code/Testing/mitkRenderingTestHelper.h b/Core/Code/Testing/mitkRenderingTestHelper.h
index 8cd4156b93..f8790f561e 100644
--- a/Core/Code/Testing/mitkRenderingTestHelper.h
+++ b/Core/Code/Testing/mitkRenderingTestHelper.h
@@ -1,51 +1,50 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2010-03-31 17:34:48 +0200 (Wed, 31 Mar 2010) $
-Version: $Revision: 21985 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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 mitkRenderingTestHelper_h
#define mitkRenderingTestHelper_h
#include <string>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <mitkRenderWindow.h>
class vtkRenderWindow;
class vtkRenderer;
namespace mitk
{
class DataStorage;
}
class mitkRenderingTestHelper
{
public:
mitkRenderingTestHelper(int width, int height, mitk::DataStorage* ds);
~mitkRenderingTestHelper();
vtkRenderer* GetVtkRenderer();
vtkRenderWindow* GetVtkRenderWindow();
void SaveAsPNG(std::string fileName);
protected:
mitk::RenderWindow::Pointer m_RenderWindow;
};
#endif
diff --git a/Core/Code/Testing/mitkSTLFileReaderTest.cpp b/Core/Code/Testing/mitkSTLFileReaderTest.cpp
index 171e5e42ec..8bf7819ff8 100644
--- a/Core/Code/Testing/mitkSTLFileReaderTest.cpp
+++ b/Core/Code/Testing/mitkSTLFileReaderTest.cpp
@@ -1,79 +1,78 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-09-17 13:15:38 +0200 (Do, 17 Sep 2009) $
-Version: $Revision: 19014 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkSTLFileReader.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include "mitkSurface.h"
#include "mitkTestingMacros.h"
#include <vtkSTLReader.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <fstream>
int mitkSTLFileReaderTest(int argc, char* argv[])
{
// always start with this!
MITK_TEST_BEGIN("STLFileReader")
//Read STL-Image from file
mitk::STLFileReader::Pointer reader = mitk::STLFileReader::New();
if(argc==0)
{
std::cout<<"file not found - test not applied [PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
std::cout << "Testing CanReadFile(): ";
if (!reader->CanReadFile(argv[1], "", ""))
{
//std::cout<<"[FAILED]"<<std::endl;
//return EXIT_FAILURE;
MITK_TEST_OUTPUT(<< mitkTestName << ": "<< mitk::TestManager::GetInstance()->NumberOfPassedTests() << " tests [DONE PASSED] File is not STL!")
return EXIT_SUCCESS;
}
std::cout<<"[PASSED]"<<std::endl;
reader->SetFileName(argv[1]);
reader->Update();
MITK_TEST_CONDITION_REQUIRED((reader->GetOutput() != NULL),"Reader output not NULL")
mitk::Surface::Pointer surface = reader->GetOutput();
MITK_TEST_CONDITION_REQUIRED(surface->IsInitialized(),"IsInitialized()")
MITK_TEST_CONDITION_REQUIRED((surface->GetVtkPolyData()!=NULL),"mitk::Surface::SetVtkPolyData()")
MITK_TEST_CONDITION_REQUIRED((surface->GetGeometry()!=NULL),"Availability of geometry")
vtkSmartPointer<vtkSTLReader> myVtkSTLReader = vtkSmartPointer<vtkSTLReader>::New();
myVtkSTLReader->SetFileName( argv[1] );
myVtkSTLReader->Update();
vtkSmartPointer<vtkPolyData> myVtkPolyData = myVtkSTLReader->GetOutput();
// vtkPolyData from vtkSTLReader directly
int n = myVtkPolyData->GetNumberOfPoints();
// vtkPolyData from mitkSTLFileReader
int m = surface->GetVtkPolyData()->GetNumberOfPoints();
MITK_TEST_CONDITION_REQUIRED((n == m),"Number of Points in VtkPolyData")
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkSliceNavigationControllerTest.cpp b/Core/Code/Testing/mitkSliceNavigationControllerTest.cpp
index 441f8af53c..3371465cc7 100644
--- a/Core/Code/Testing/mitkSliceNavigationControllerTest.cpp
+++ b/Core/Code/Testing/mitkSliceNavigationControllerTest.cpp
@@ -1,417 +1,416 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSliceNavigationController.h"
#include "mitkPlaneGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkRotationOperation.h"
#include "mitkInteractionConst.h"
#include "mitkPlanePositionManager.h"
#include "mitkTestingMacros.h"
#include "mitkGetModuleContext.h"
#include <vnl/vnl_quaternion.h>
#include <vnl/vnl_quaternion.txx>
#include <fstream>
bool operator==(const mitk::Geometry3D & left, const mitk::Geometry3D & right)
{
mitk::BoundingBox::BoundsArrayType leftbounds, rightbounds;
leftbounds =left.GetBounds();
rightbounds=right.GetBounds();
unsigned int i;
for(i=0;i<6;++i)
if(mitk::Equal(leftbounds[i],rightbounds[i])==false) return false;
const mitk::Geometry3D::TransformType::MatrixType & leftmatrix = left.GetIndexToWorldTransform()->GetMatrix();
const mitk::Geometry3D::TransformType::MatrixType & rightmatrix = right.GetIndexToWorldTransform()->GetMatrix();
unsigned int j;
for(i=0;i<3;++i)
{
const mitk::Geometry3D::TransformType::MatrixType::ValueType* leftvector = leftmatrix[i];
const mitk::Geometry3D::TransformType::MatrixType::ValueType* rightvector = rightmatrix[i];
for(j=0;j<3;++j)
if(mitk::Equal(leftvector[i],rightvector[i])==false) return false;
}
const mitk::Geometry3D::TransformType::OffsetType & leftoffset = left.GetIndexToWorldTransform()->GetOffset();
const mitk::Geometry3D::TransformType::OffsetType & rightoffset = right.GetIndexToWorldTransform()->GetOffset();
for(i=0;i<3;++i)
if(mitk::Equal(leftoffset[i],rightoffset[i])==false) return false;
return true;
}
int compareGeometry(const mitk::Geometry3D & geometry,
const mitk::ScalarType& width, const mitk::ScalarType& height, const mitk::ScalarType& numSlices,
const mitk::ScalarType& widthInMM, const mitk::ScalarType& heightInMM, const mitk::ScalarType& thicknessInMM,
const mitk::Point3D& cornerpoint0, const mitk::Vector3D& right, const mitk::Vector3D& bottom, const mitk::Vector3D& normal)
{
std::cout << "Testing width, height and thickness (in units): ";
if((mitk::Equal(geometry.GetExtent(0),width)==false) ||
(mitk::Equal(geometry.GetExtent(1),height)==false) ||
(mitk::Equal(geometry.GetExtent(2),numSlices)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing width, height and thickness (in mm): ";
if((mitk::Equal(geometry.GetExtentInMM(0),widthInMM)==false) ||
(mitk::Equal(geometry.GetExtentInMM(1),heightInMM)==false) ||
(mitk::Equal(geometry.GetExtentInMM(2),thicknessInMM)==false)
)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing GetAxisVector(): ";
std::cout << "dir=0 ";
mitk::Vector3D dv;
dv=right; dv.Normalize(); dv*=widthInMM;
if((mitk::Equal(geometry.GetAxisVector(0), dv)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]";
std::cout << ", dir=1 ";
dv=bottom; dv.Normalize(); dv*=heightInMM;
if((mitk::Equal(geometry.GetAxisVector(1), dv)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]";
std::cout << ", dir=2 ";
dv=normal; dv.Normalize(); dv*=thicknessInMM;
if((mitk::Equal(geometry.GetAxisVector(2), dv)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing offset: ";
if((mitk::Equal(geometry.GetCornerPoint(0),cornerpoint0)==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
int testGeometry(const mitk::Geometry3D * geometry,
const mitk::ScalarType& width, const mitk::ScalarType& height, const mitk::ScalarType& numSlices,
const mitk::ScalarType& widthInMM, const mitk::ScalarType& heightInMM, const mitk::ScalarType& thicknessInMM,
const mitk::Point3D& cornerpoint0, const mitk::Vector3D& right, const mitk::Vector3D& bottom, const mitk::Vector3D& normal)
{
int result=EXIT_FAILURE;
std::cout << "Comparing GetCornerPoint(0) of Geometry3D with provided cornerpoint0: ";
if(mitk::Equal(geometry->GetCornerPoint(0), cornerpoint0)==false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating and initializing a SliceNavigationController with the Geometry3D: ";
mitk::SliceNavigationController::Pointer sliceCtrl = mitk::SliceNavigationController::New();
sliceCtrl->SetInputWorldGeometry(geometry);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing SetViewDirection(mitk::SliceNavigationController::Transversal): ";
sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Transversal);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing Update(): ";
sliceCtrl->Update();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing result of CreatedWorldGeometry(): ";
mitk::Point3D transversalcornerpoint0;
transversalcornerpoint0 = cornerpoint0+bottom+normal*(numSlices-1+0.5); //really -1?
result = compareGeometry(*sliceCtrl->GetCreatedWorldGeometry(), width, height, numSlices, widthInMM, heightInMM, thicknessInMM*numSlices, transversalcornerpoint0, right, bottom*(-1.0), normal*(-1.0));
if(result!=EXIT_SUCCESS)
{
std::cout<<"[FAILED]"<<std::endl;
return result;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing SetViewDirection(mitk::SliceNavigationController::Frontal): ";
sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Frontal);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing Update(): ";
sliceCtrl->Update();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing result of CreatedWorldGeometry(): ";
mitk::Point3D frontalcornerpoint0;
frontalcornerpoint0 = cornerpoint0+geometry->GetAxisVector(1)*(+0.5/geometry->GetExtent(1));
result = compareGeometry(*sliceCtrl->GetCreatedWorldGeometry(), width, numSlices, height, widthInMM, thicknessInMM*numSlices, heightInMM, frontalcornerpoint0, right, normal, bottom);
if(result!=EXIT_SUCCESS)
{
std::cout<<"[FAILED]"<<std::endl;
return result;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing SetViewDirection(mitk::SliceNavigationController::Sagittal): ";
sliceCtrl->SetViewDirection(mitk::SliceNavigationController::Sagittal);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing Update(): "<<std::endl;
sliceCtrl->Update();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing result of CreatedWorldGeometry(): ";
mitk::Point3D sagittalcornerpoint0;
sagittalcornerpoint0 = cornerpoint0+geometry->GetAxisVector(0)*(+0.5/geometry->GetExtent(0));
result = compareGeometry(*sliceCtrl->GetCreatedWorldGeometry(), height, numSlices, width, heightInMM, thicknessInMM*numSlices, widthInMM, sagittalcornerpoint0, bottom, normal, right);
if(result!=EXIT_SUCCESS)
{
std::cout<<"[FAILED]"<<std::endl;
return result;
}
std::cout<<"[PASSED]"<<std::endl;
return EXIT_SUCCESS;
}
int testRestorePlanePostionOperation ()
{
//Create PlaneGeometry
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
mitk::Point3D origin;
mitk::Vector3D right, bottom, normal;
mitk::ScalarType width, height;
mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
width = 100; widthInMM = width;
height = 200; heightInMM = height;
thicknessInMM = 1.5;
mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
mitk::FillVector3D(right, widthInMM, 0, 0);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
mitk::FillVector3D(normal, 0, 0, thicknessInMM);
mitk::Vector3D spacing;
normal.Normalize(); normal *= thicknessInMM;
mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM);
planegeometry->InitializeStandardPlane(right.Get_vnl_vector(), bottom.Get_vnl_vector(), &spacing);
planegeometry->SetOrigin(origin);
//Create SlicedGeometry3D out of planeGeometry
mitk::SlicedGeometry3D::Pointer slicedgeometry1 = mitk::SlicedGeometry3D::New();
unsigned int numSlices = 300;
slicedgeometry1->InitializeEvenlySpaced(planegeometry, thicknessInMM, numSlices, false);
//Create another slicedgeo which will be rotated
mitk::SlicedGeometry3D::Pointer slicedgeometry2 = mitk::SlicedGeometry3D::New();
slicedgeometry2->InitializeEvenlySpaced(planegeometry, thicknessInMM, numSlices, false);
//Create geo3D as reference
mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New();
geometry->SetBounds(slicedgeometry1->GetBounds());
geometry->SetIndexToWorldTransform(slicedgeometry1->GetIndexToWorldTransform());
//Initialize planes
for (int i=0; i < (int)numSlices; i++)
{
mitk::PlaneGeometry::Pointer geo2d = mitk::PlaneGeometry::New();
geo2d->Initialize();
geo2d->SetReferenceGeometry(geometry);
slicedgeometry1->SetGeometry2D(geo2d,i);
}
for (int i=0; i < (int)numSlices; i++)
{
mitk::PlaneGeometry::Pointer geo2d = mitk::PlaneGeometry::New();
geo2d->Initialize();
geo2d->SetReferenceGeometry(geometry);
slicedgeometry2->SetGeometry2D(geo2d,i);
}
slicedgeometry1->SetReferenceGeometry(geometry);
slicedgeometry2->SetReferenceGeometry(geometry);
//Create SNC
mitk::SliceNavigationController::Pointer sliceCtrl1 = mitk::SliceNavigationController::New();
sliceCtrl1->SetInputWorldGeometry(slicedgeometry1);
sliceCtrl1->Update();
mitk::SliceNavigationController::Pointer sliceCtrl2 = mitk::SliceNavigationController::New();
sliceCtrl2->SetInputWorldGeometry(slicedgeometry2);
sliceCtrl2->Update();
slicedgeometry1->SetSliceNavigationController(sliceCtrl1);
slicedgeometry2->SetSliceNavigationController(sliceCtrl2);
//Rotate slicedgeo2
double angle = 63.84;
mitk::Vector3D rotationVector; mitk::FillVector3D( rotationVector, 0.5, 0.95, 0.23 );
mitk::Point3D center = slicedgeometry2->GetCenter();
mitk::RotationOperation* op = new mitk::RotationOperation( mitk::OpROTATE, center, rotationVector, angle );
slicedgeometry2->ExecuteOperation(op);
sliceCtrl2->Update();
mitk::ServiceReference serviceRef = mitk::GetModuleContext()->GetServiceReference<mitk::PlanePositionManagerService>();
mitk::PlanePositionManagerService* service = dynamic_cast<mitk::PlanePositionManagerService*>(mitk::GetModuleContext()->GetService(serviceRef));
service->AddNewPlanePosition(slicedgeometry2->GetGeometry2D(0), 178);
sliceCtrl1->ExecuteOperation(service->GetPlanePosition(0));
sliceCtrl1->Update();
mitk::Geometry2D* planeRotated = slicedgeometry2->GetGeometry2D(178);
mitk::Geometry2D* planeRestored = dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetGeometry2D(178);
bool error = ( !mitk::MatrixEqualElementWise(planeRotated->GetIndexToWorldTransform()->GetMatrix(), planeRestored->GetIndexToWorldTransform()->GetMatrix()) ||
!mitk::Equal(planeRotated->GetOrigin(), planeRestored->GetOrigin()) ||
!mitk::Equal(planeRotated->GetSpacing(), planeRestored->GetSpacing()) ||
!mitk::Equal(slicedgeometry2->GetDirectionVector(), dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetDirectionVector()) ||
!mitk::Equal(slicedgeometry2->GetSlices(), dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetSlices()) ||
!mitk::MatrixEqualElementWise(slicedgeometry2->GetIndexToWorldTransform()->GetMatrix(), dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetIndexToWorldTransform()->GetMatrix())
);
if (error)
{
MITK_TEST_CONDITION(mitk::MatrixEqualElementWise(planeRotated->GetIndexToWorldTransform()->GetMatrix(), planeRestored->GetIndexToWorldTransform()->GetMatrix()),"Testing for IndexToWorld");
MITK_INFO<<"Rotated: \n"<<planeRotated->GetIndexToWorldTransform()->GetMatrix()<<" Restored: \n"<<planeRestored->GetIndexToWorldTransform()->GetMatrix();
MITK_TEST_CONDITION(mitk::Equal(planeRotated->GetOrigin(), planeRestored->GetOrigin()),"Testing for origin");
MITK_INFO<<"Rotated: \n"<<planeRotated->GetOrigin()<<" Restored: \n"<<planeRestored->GetOrigin();
MITK_TEST_CONDITION(mitk::Equal(planeRotated->GetSpacing(), planeRestored->GetSpacing()),"Testing for spacing");
MITK_INFO<<"Rotated: \n"<<planeRotated->GetSpacing()<<" Restored: \n"<<planeRestored->GetSpacing();
MITK_TEST_CONDITION(mitk::Equal(slicedgeometry2->GetDirectionVector(), dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetDirectionVector()),"Testing for directionvector");
MITK_INFO<<"Rotated: \n"<<slicedgeometry2->GetDirectionVector()<<" Restored: \n"<<dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetDirectionVector();
MITK_TEST_CONDITION(mitk::Equal(slicedgeometry2->GetSlices(), dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetSlices()),"Testing for numslices");
MITK_INFO<<"Rotated: \n"<<slicedgeometry2->GetSlices()<<" Restored: \n"<<dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetSlices();
MITK_TEST_CONDITION(mitk::MatrixEqualElementWise(slicedgeometry2->GetIndexToWorldTransform()->GetMatrix(), dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetIndexToWorldTransform()->GetMatrix()),"Testing for IndexToWorld");
MITK_INFO<<"Rotated: \n"<<slicedgeometry2->GetIndexToWorldTransform()->GetMatrix()<<" Restored: \n"<<dynamic_cast< const mitk::SlicedGeometry3D*>(sliceCtrl1->GetCurrentGeometry3D())->GetIndexToWorldTransform()->GetMatrix();
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int mitkSliceNavigationControllerTest(int /*argc*/, char* /*argv*/[])
{
int result=EXIT_FAILURE;
std::cout << "Creating and initializing a PlaneGeometry: ";
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
mitk::Point3D origin;
mitk::Vector3D right, bottom, normal;
mitk::ScalarType width, height;
mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
width = 100; widthInMM = width;
height = 200; heightInMM = height;
thicknessInMM = 1.5;
// mitk::FillVector3D(origin, 0, 0, thicknessInMM*0.5);
mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
mitk::FillVector3D(right, widthInMM, 0, 0);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
mitk::FillVector3D(normal, 0, 0, thicknessInMM);
mitk::Vector3D spacing;
normal.Normalize(); normal *= thicknessInMM;
mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM);
planegeometry->InitializeStandardPlane(right.Get_vnl_vector(), bottom.Get_vnl_vector(), &spacing);
planegeometry->SetOrigin(origin);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating and initializing a SlicedGeometry3D with the PlaneGeometry: ";
mitk::SlicedGeometry3D::Pointer slicedgeometry = mitk::SlicedGeometry3D::New();
unsigned int numSlices = 5;
slicedgeometry->InitializeEvenlySpaced(planegeometry, thicknessInMM, numSlices, false);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating a Geometry3D with the same extent as the SlicedGeometry3D: ";
mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New();
geometry->SetBounds(slicedgeometry->GetBounds());
geometry->SetIndexToWorldTransform(slicedgeometry->GetIndexToWorldTransform());
std::cout<<"[PASSED]"<<std::endl;
mitk::Point3D cornerpoint0;
cornerpoint0 = geometry->GetCornerPoint(0);
result=testGeometry(geometry, width, height, numSlices, widthInMM, heightInMM, thicknessInMM, cornerpoint0, right, bottom, normal);
if(result!=EXIT_SUCCESS)
return result;
mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New();
transform->SetMatrix(geometry->GetIndexToWorldTransform()->GetMatrix());
mitk::BoundingBox::Pointer boundingbox = geometry->CalculateBoundingBoxRelativeToTransform(transform);
geometry->SetBounds(boundingbox->GetBounds());
cornerpoint0 = geometry->GetCornerPoint(0);
result=testGeometry(geometry, width, height, numSlices, widthInMM, heightInMM, thicknessInMM, cornerpoint0, right, bottom, normal);
if(result!=EXIT_SUCCESS)
return result;
std::cout << "Changing the IndexToWorldTransform of the geometry to a rotated version by SetIndexToWorldTransform() (keep cornerpoint0): ";
transform = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = planegeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
mitk::VnlVector axis(3);
mitk::FillVector3D(axis, 1.0, 1.0, 1.0); axis.normalize();
vnl_quaternion<mitk::ScalarType> rotation(axis, 0.223);
vnlmatrix = rotation.rotation_matrix_transpose()*vnlmatrix;
mitk::Matrix3D matrix;
matrix = vnlmatrix;
transform->SetMatrix(matrix);
transform->SetOffset(cornerpoint0.GetVectorFromOrigin());
right.Set_vnl_vector( rotation.rotation_matrix_transpose()*right.Get_vnl_vector() );
bottom.Set_vnl_vector(rotation.rotation_matrix_transpose()*bottom.Get_vnl_vector());
normal.Set_vnl_vector(rotation.rotation_matrix_transpose()*normal.Get_vnl_vector());
geometry->SetIndexToWorldTransform(transform);
std::cout<<"[PASSED]"<<std::endl;
cornerpoint0 = geometry->GetCornerPoint(0);
result = testGeometry(geometry, width, height, numSlices, widthInMM, heightInMM, thicknessInMM, cornerpoint0, right, bottom, normal);
if(result!=EXIT_SUCCESS)
return result;
//Testing Execute RestorePlanePositionOperation
result = testRestorePlanePostionOperation();
if(result!=EXIT_SUCCESS)
return result;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkSlicedGeometry3DTest.cpp b/Core/Code/Testing/mitkSlicedGeometry3DTest.cpp
index d63dd2995d..89a3d72204 100644
--- a/Core/Code/Testing/mitkSlicedGeometry3DTest.cpp
+++ b/Core/Code/Testing/mitkSlicedGeometry3DTest.cpp
@@ -1,257 +1,256 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkPlaneGeometry.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include "mitkTestingMacros.h"
#include <vnl/vnl_quaternion.h>
#include <vnl/vnl_quaternion.txx>
#include <fstream>
void mitkSlicedGeometry3D_ChangeImageGeometryConsideringOriginOffset_Test()
{
//Tests for Offset
MITK_TEST_OUTPUT( << "====== NOW RUNNING: Tests for pixel-center-based offset concerns ========");
// create a SlicedGeometry3D
mitk::SlicedGeometry3D::Pointer slicedGeo3D=mitk::SlicedGeometry3D::New();
int num_slices = 5;
slicedGeo3D->InitializeSlicedGeometry(num_slices); // 5 slices
mitk::Point3D newOrigin;
newOrigin[0] = 91.3;
newOrigin[1] = -13.3;
newOrigin[2] = 0;
slicedGeo3D->SetOrigin(newOrigin);
mitk::Vector3D newSpacing;
newSpacing[0] = 1.0f;
newSpacing[1] = 0.9f;
newSpacing[2] = 0.3f;
slicedGeo3D->SetSpacing(newSpacing);
// create subslices as well
for (int i=0; i < num_slices; i++)
{
mitk::Geometry2D::Pointer geo2d = mitk::Geometry2D::New();
geo2d->Initialize();
slicedGeo3D->SetGeometry2D(geo2d,i);
}
// now run tests
MITK_TEST_OUTPUT( << "Testing whether slicedGeo3D->GetImageGeometry() is false by default");
MITK_TEST_CONDITION_REQUIRED( slicedGeo3D->GetImageGeometry()==false, "");
MITK_TEST_OUTPUT( << "Testing whether first and last geometry in the SlicedGeometry3D have GetImageGeometry()==false by default");
mitk::Geometry3D* subSliceGeo2D_first = slicedGeo3D->GetGeometry2D(0);
mitk::Geometry3D* subSliceGeo2D_last = slicedGeo3D->GetGeometry2D(num_slices-1);
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_first->GetImageGeometry()==false, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_last->GetImageGeometry()==false, "");
// Save some Origins and cornerpoints
mitk::Point3D OriginSlicedGeo( slicedGeo3D->GetOrigin() );
mitk::Point3D OriginFirstGeo( subSliceGeo2D_first->GetOrigin() );
mitk::Point3D OriginLastGeo( subSliceGeo2D_last->GetOrigin() );
mitk::Point3D CornerPoint0SlicedGeo(slicedGeo3D->GetCornerPoint(0));
mitk::Point3D CornerPoint1FirstGeo(subSliceGeo2D_first->GetCornerPoint(1));
mitk::Point3D CornerPoint2LastGeo(subSliceGeo2D_last->GetCornerPoint(2));
MITK_TEST_OUTPUT( << "Calling slicedGeo3D->ChangeImageGeometryConsideringOriginOffset(true)");
//std::cout << "vorher Origin: " << subSliceGeo2D_first->GetOrigin() << std::endl;
//std::cout << "vorher Corner: " << subSliceGeo2D_first->GetCornerPoint(0) << std::endl;
slicedGeo3D->ChangeImageGeometryConsideringOriginOffset(true);
//std::cout << "nachher Origin: " << subSliceGeo2D_first->GetOrigin() << std::endl;
//std::cout << "nachher Corner: " << subSliceGeo2D_first->GetCornerPoint(0) << std::endl;
MITK_TEST_OUTPUT( << "Testing whether slicedGeo3D->GetImageGeometry() is now true");
MITK_TEST_CONDITION_REQUIRED( slicedGeo3D->GetImageGeometry()==true, "");
MITK_TEST_OUTPUT( << "Testing whether first and last geometry in the SlicedGeometry3D have GetImageGeometry()==true now");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_first->GetImageGeometry()==true, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_last->GetImageGeometry()==true, "");
MITK_TEST_OUTPUT( << "Testing wether offset has been added to origins");
// Manually adding Offset.
OriginSlicedGeo[0] += (slicedGeo3D->GetSpacing()[0]) / 2;
OriginSlicedGeo[1] += (slicedGeo3D->GetSpacing()[1]) / 2;
OriginSlicedGeo[2] += (slicedGeo3D->GetSpacing()[2]) / 2;
OriginFirstGeo[0] += (subSliceGeo2D_first->GetSpacing()[0]) / 2;
OriginFirstGeo[1] += (subSliceGeo2D_first->GetSpacing()[1]) / 2;
OriginFirstGeo[2] += (subSliceGeo2D_first->GetSpacing()[2]) / 2;
OriginLastGeo[0] += (subSliceGeo2D_last->GetSpacing()[0]) / 2;
OriginLastGeo[1] += (subSliceGeo2D_last->GetSpacing()[1]) / 2;
OriginLastGeo[2] += (subSliceGeo2D_last->GetSpacing()[2]) / 2;
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_first->GetCornerPoint(1)==CornerPoint1FirstGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_last->GetCornerPoint(2)==CornerPoint2LastGeo, "");
MITK_TEST_CONDITION_REQUIRED( slicedGeo3D->GetCornerPoint(0)==CornerPoint0SlicedGeo, "");
MITK_TEST_CONDITION_REQUIRED( slicedGeo3D->GetOrigin()==OriginSlicedGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_first->GetOrigin()==OriginFirstGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_last->GetOrigin()==OriginLastGeo, "");
MITK_TEST_OUTPUT( << "Calling slicedGeo3D->ChangeImageGeometryConsideringOriginOffset(false)");
slicedGeo3D->ChangeImageGeometryConsideringOriginOffset(false);
MITK_TEST_OUTPUT( << "Testing whether slicedGeo3D->GetImageGeometry() is now false");
MITK_TEST_CONDITION_REQUIRED( slicedGeo3D->GetImageGeometry()==false, "");
MITK_TEST_OUTPUT( << "Testing whether first and last geometry in the SlicedGeometry3D have GetImageGeometry()==false now");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_first->GetImageGeometry()==false, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_last->GetImageGeometry()==false, "");
MITK_TEST_OUTPUT( << "Testing wether offset has been added to origins of geometry");
// Manually substracting Offset.
OriginSlicedGeo[0] -= (slicedGeo3D->GetSpacing()[0]) / 2;
OriginSlicedGeo[1] -= (slicedGeo3D->GetSpacing()[1]) / 2;
OriginSlicedGeo[2] -= (slicedGeo3D->GetSpacing()[2]) / 2;
OriginFirstGeo[0] -= (subSliceGeo2D_first->GetSpacing()[0]) / 2;
OriginFirstGeo[1] -= (subSliceGeo2D_first->GetSpacing()[1]) / 2;
OriginFirstGeo[2] -= (subSliceGeo2D_first->GetSpacing()[2]) / 2;
OriginLastGeo[0] -= (subSliceGeo2D_last->GetSpacing()[0]) / 2;
OriginLastGeo[1] -= (subSliceGeo2D_last->GetSpacing()[1]) / 2;
OriginLastGeo[2] -= (subSliceGeo2D_last->GetSpacing()[2]) / 2;
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_first->GetCornerPoint(1)==CornerPoint1FirstGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_last->GetCornerPoint(2)==CornerPoint2LastGeo, "");
MITK_TEST_CONDITION_REQUIRED( slicedGeo3D->GetCornerPoint(0)==CornerPoint0SlicedGeo, "");
MITK_TEST_CONDITION_REQUIRED( slicedGeo3D->GetOrigin()==OriginSlicedGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_first->GetOrigin()==OriginFirstGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo2D_last->GetOrigin()==OriginLastGeo, "");
MITK_TEST_OUTPUT( << "ALL SUCCESSFULLY!");
}
int mitkSlicedGeometry3DTest(int /*argc*/, char* /*argv*/[])
{
mitk::PlaneGeometry::Pointer planegeometry1 = mitk::PlaneGeometry::New();
mitk::Point3D origin;
mitk::Vector3D right, bottom, normal;
mitk::ScalarType width, height;
mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
width = 100; widthInMM = width;
height = 200; heightInMM = height;
thicknessInMM = 3.5;
mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
mitk::FillVector3D(right, widthInMM, 0, 0);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
mitk::FillVector3D(normal, 0, 0, thicknessInMM);
std::cout << "Initializing planegeometry1 by InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
planegeometry1->InitializeStandardPlane(right.Get_vnl_vector(), bottom.Get_vnl_vector());
std::cout << "Setting planegeometry2 to a cloned version of planegeometry1: "<<std::endl;
mitk::PlaneGeometry::Pointer planegeometry2;
planegeometry2 = dynamic_cast<mitk::PlaneGeometry*>(planegeometry1->Clone().GetPointer());;
std::cout << "Changing the IndexToWorldTransform of planegeometry2 to a rotated version by SetIndexToWorldTransform() (keep origin): "<<std::endl;
mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New();
mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
vnlmatrix = planegeometry2->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
mitk::VnlVector axis(3);
mitk::FillVector3D(axis, 1.0, 1.0, 1.0); axis.normalize();
vnl_quaternion<mitk::ScalarType> rotation(axis, 0.123);
vnlmatrix = rotation.rotation_matrix_transpose()*vnlmatrix;
mitk::Matrix3D matrix;
matrix = vnlmatrix;
transform->SetMatrix(matrix);
transform->SetOffset(planegeometry2->GetIndexToWorldTransform()->GetOffset());
right.Set_vnl_vector( rotation.rotation_matrix_transpose()*right.Get_vnl_vector() );
bottom.Set_vnl_vector(rotation.rotation_matrix_transpose()*bottom.Get_vnl_vector());
normal.Set_vnl_vector(rotation.rotation_matrix_transpose()*normal.Get_vnl_vector());
planegeometry2->SetIndexToWorldTransform(transform);
std::cout << "Setting planegeometry3 to the backside of planegeometry2: " <<std::endl;
mitk::PlaneGeometry::Pointer planegeometry3 = mitk::PlaneGeometry::New();
planegeometry3->InitializeStandardPlane(planegeometry2, mitk::PlaneGeometry::Transversal, 0, false);
std::cout << "Testing SlicedGeometry3D::InitializeEvenlySpaced(planegeometry3, zSpacing = 1, slices = 5, flipped = false): " <<std::endl;
mitk::SlicedGeometry3D::Pointer slicedWorldGeometry=mitk::SlicedGeometry3D::New();
unsigned int numSlices = 5;
slicedWorldGeometry->InitializeEvenlySpaced(planegeometry3, 1, numSlices, false);
std::cout << "Testing availability and type (PlaneGeometry) of first geometry in the SlicedGeometry3D: ";
mitk::PlaneGeometry* accessedplanegeometry3 = dynamic_cast<mitk::PlaneGeometry*>(slicedWorldGeometry->GetGeometry2D(0));
if(accessedplanegeometry3==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing whether the first geometry in the SlicedGeometry3D is identical to planegeometry3 by axis comparison and origin: "<<std::endl;
if((mitk::Equal(accessedplanegeometry3->GetAxisVector(0), planegeometry3->GetAxisVector(0))==false) ||
(mitk::Equal(accessedplanegeometry3->GetAxisVector(1), planegeometry3->GetAxisVector(1))==false) ||
(mitk::Equal(accessedplanegeometry3->GetAxisVector(2), planegeometry3->GetAxisVector(2))==false) ||
(mitk::Equal(accessedplanegeometry3->GetOrigin(), planegeometry3->GetOrigin())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing availability and type (PlaneGeometry) of the last geometry in the SlicedGeometry3D: ";
mitk::PlaneGeometry* accessedplanegeometry3last = dynamic_cast<mitk::PlaneGeometry*>(slicedWorldGeometry->GetGeometry2D(numSlices-1));
mitk::Point3D origin3last; origin3last = planegeometry3->GetOrigin()+slicedWorldGeometry->GetDirectionVector()*(numSlices-1);
if(accessedplanegeometry3last==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing whether the last geometry in the SlicedGeometry3D is identical to planegeometry3 by axis comparison: "<<std::endl;
if((mitk::Equal(accessedplanegeometry3last->GetAxisVector(0), planegeometry3->GetAxisVector(0))==false) ||
(mitk::Equal(accessedplanegeometry3last->GetAxisVector(1), planegeometry3->GetAxisVector(1))==false) ||
(mitk::Equal(accessedplanegeometry3last->GetAxisVector(2), planegeometry3->GetAxisVector(2))==false) ||
(mitk::Equal(accessedplanegeometry3last->GetOrigin(), origin3last)==false) ||
(mitk::Equal(accessedplanegeometry3last->GetIndexToWorldTransform()->GetOffset(), origin3last.GetVectorFromOrigin())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Again for first slice - Testing availability and type (PlaneGeometry) of first geometry in the SlicedGeometry3D: ";
accessedplanegeometry3 = dynamic_cast<mitk::PlaneGeometry*>(slicedWorldGeometry->GetGeometry2D(0));
if(accessedplanegeometry3==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Again for first slice - Testing whether the first geometry in the SlicedGeometry3D is identical to planegeometry3 by axis comparison and origin: "<<std::endl;
if((mitk::Equal(accessedplanegeometry3->GetAxisVector(0), planegeometry3->GetAxisVector(0))==false) ||
(mitk::Equal(accessedplanegeometry3->GetAxisVector(1), planegeometry3->GetAxisVector(1))==false) ||
(mitk::Equal(accessedplanegeometry3->GetAxisVector(2), planegeometry3->GetAxisVector(2))==false) ||
(mitk::Equal(accessedplanegeometry3->GetOrigin(), planegeometry3->GetOrigin())==false) ||
(mitk::Equal(accessedplanegeometry3->GetIndexToWorldTransform()->GetOffset(), planegeometry3->GetOrigin().GetVectorFromOrigin())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
mitkSlicedGeometry3D_ChangeImageGeometryConsideringOriginOffset_Test();
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkStateMachineFactoryTest.cpp b/Core/Code/Testing/mitkStateMachineFactoryTest.cpp
index 5cba2525ee..59028a1452 100644
--- a/Core/Code/Testing/mitkStateMachineFactoryTest.cpp
+++ b/Core/Code/Testing/mitkStateMachineFactoryTest.cpp
@@ -1,95 +1,94 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkStateMachineFactory.h>
#include <mitkState.h>
#include "mitkTestingMacros.h"
#include <mitkInteractionConst.h>
int mitkStateMachineFactoryTest(int argc, char* argv[])
{
MITK_TEST_BEGIN("StateMachineFactory")
//create statemachinefactory
mitk::StateMachineFactory* statemachineFactory = mitk::StateMachineFactory::New();
//load standard behavior
MITK_TEST_CONDITION_REQUIRED(statemachineFactory->LoadStandardBehavior(),"Testing LoadStandardBehavior(): ")
//get the first state of the statemachine "global" (mitkGlobalInteraction)
mitk::State::Pointer state = statemachineFactory->GetStartState("global");
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing GetStartState() of GlobalInteraction state machine pattern: ")
MITK_TEST_CONDITION_REQUIRED(argc>2, "Testing correct test invocation");
std::string xmlFileName1 = argv[1];
MITK_TEST_CONDITION_REQUIRED(!xmlFileName1.empty(),"Getting xml file 1: ")
MITK_TEST_CONDITION_REQUIRED(statemachineFactory->LoadBehavior(xmlFileName1),"Parsing xml file 1: ")
state = statemachineFactory->GetStartState("test1");
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing GetStartState() of test1 state machine pattern: ")
//global still accessible?
state = statemachineFactory->GetStartState("global");
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing if previous loaded state machine patterns are still accessible: ")
std::string xmlFileName2 = argv[2];
MITK_TEST_CONDITION_REQUIRED(!xmlFileName2.empty(),"Getting xml file 2: ")
MITK_TEST_CONDITION_REQUIRED(statemachineFactory->LoadBehavior(xmlFileName2),"Parsing xml file 2. Schould throw a fatal error due to already existing pattern name: ")
state = statemachineFactory->GetStartState("test4");
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing GetStartState() of test4 state machine pattern: ")
state = statemachineFactory->GetStartState("global");
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing if previous loaded state machine pattern (global) is still accessible: ")
state = statemachineFactory->GetStartState("test1");
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing if previous loaded state machine pattern (test1) is still accessible: ")
//manually create a state machine pattern and add it to factory
std::string patternName("manuallyCreatedStateMachine");
mitk::StateMachineFactory::StateMachineMapType* allStatesMap = new mitk::StateMachineFactory::StateMachineMapType();
mitk::State::Pointer state1 = mitk::State::New("firstState", 1);
mitk::Transition* transition1 = new mitk::Transition("goto2", 2, mitk::EIDNULLEVENT);
mitk::Action::Pointer action1 = mitk::Action::New(mitk::AcDONOTHING);
transition1->AddAction(action1);
state1->AddTransition(transition1);
allStatesMap->insert(mitk::StateMachineFactory::StateMachineMapType::value_type(state1->GetId(), state1));
mitk::State::Pointer state2 = mitk::State::New("secondState", 2);
transition1->SetNextState(state2);
mitk::Transition* transition2 = new mitk::Transition("goto1", 1, mitk::EIDNULLEVENT);
mitk::Action::Pointer action2 = mitk::Action::New(mitk::AcDONOTHING);
transition2->AddAction(action2);
transition2->SetNextState(state1);
state2->AddTransition(transition2);
allStatesMap->insert(mitk::StateMachineFactory::StateMachineMapType::value_type(state2->GetId(), state2));
//now add to factory
statemachineFactory->AddStateMachinePattern(patternName.c_str(), state1, allStatesMap);
//check if it is accessable
state = statemachineFactory->GetStartState("global");
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing if previous loaded state machine pattern (global) is still accessible: ")
state = statemachineFactory->GetStartState("test1");
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing if previous loaded state machine pattern (test1) is still accessible: ")
state = statemachineFactory->GetStartState(patternName.c_str());
MITK_TEST_CONDITION_REQUIRED(state.IsNotNull(),"Testing if manually created and added state machine pattern is accessible: ")
statemachineFactory->Delete();
//states, transitions and actions are freed in StateMachineFactory
// always end with this!
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkStateMachineTest.cpp b/Core/Code/Testing/mitkStateMachineTest.cpp
index 70dca1f2fc..d3e10ec537 100644
--- a/Core/Code/Testing/mitkStateMachineTest.cpp
+++ b/Core/Code/Testing/mitkStateMachineTest.cpp
@@ -1,95 +1,94 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-08-09 09:26:25 +0200 (Sa, 09 Aug 2008) $
-Version: $Revision: 14937 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkEvent.h>
#include <mitkInteractionConst.h>
#include <mitkStateEvent.h>
#include <mitkStateMachine.h>
#include <mitkTestingMacros.h>
#include <mitkGlobalInteraction.h>
/**
* Simple example for a test for the (non-existent) class "StateMachine".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty f25or the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkStateMachineTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("StateMachine")
std::string name("global");
//test Statemachine without given pattern name
std::cout<<"should throw fatal error:\n";
mitk::StateMachine::Pointer noMachine1 = mitk::StateMachine::New("");
std::cout<<"should throw fatal error:\n";
//test Statemachine without initialization of GlobalInteraction
mitk::StateMachine::Pointer noMachine2 = mitk::StateMachine::New(name.c_str());
std::cout<<"should throw fatal error:\n";
// test Statemachine with GlobalInteraction being initialized with no string
MITK_TEST_CONDITION_REQUIRED(mitk::GlobalInteraction::GetInstance()->Initialize("")==false,"Testing wrong initialization")
MITK_TEST_CONDITION_REQUIRED(mitk::GlobalInteraction::GetInstance()->Initialize("raraolala")==false,"Testing initialization with wrong pattern name")
std::cout<<"should throw fatal error:\n";
mitk::StateMachine::Pointer noMachine3 = mitk::StateMachine::New(name.c_str());
//now get serious
std::cout<<"no errors / warnings anymore!\n";
// now initialize GlobalInteraction
MITK_TEST_CONDITION_REQUIRED(mitk::GlobalInteraction::GetInstance()->Initialize(name.c_str())==true,"Testing wright initialization")
// let's create an object of our class
mitk::StateMachine::Pointer myStateMachine = mitk::StateMachine::New(name.c_str());
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
MITK_TEST_CONDITION_REQUIRED(myStateMachine.IsNotNull(),"Testing instantiation")
MITK_TEST_CONDITION_REQUIRED(myStateMachine->GetType() == name ,"Testing GetType")
//severe HandleEvent testing
//creating an event to go from state 1 to state 2; don't execute an action
mitk::Event *event = new mitk::Event(NULL, mitk::Type_None, mitk::Type_None, mitk::BS_NoButton, mitk::Key_none);
mitk::StateEvent *stateEvent = new mitk::StateEvent(1013, event);
MITK_TEST_CONDITION_REQUIRED(myStateMachine->HandleEvent(stateEvent) ,"Testing HandleEvent by statechange")
//go from state 2 to state 1; don't execute an action
mitk::StateEvent *nextStateEvent = new mitk::StateEvent(1002, event);
MITK_TEST_CONDITION_REQUIRED(myStateMachine->HandleEvent(nextStateEvent) ,"Testing HandleEvent returning to startstate")
myStateMachine = NULL;
MITK_TEST_CONDITION_REQUIRED(myStateMachine.IsNull(),"Testing setting pointer to NULL")
// Clean up...
delete event;
delete stateEvent;
delete nextStateEvent;
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkStateTest.cpp b/Core/Code/Testing/mitkStateTest.cpp
index a728c93496..a95a7c3ab4 100644
--- a/Core/Code/Testing/mitkStateTest.cpp
+++ b/Core/Code/Testing/mitkStateTest.cpp
@@ -1,114 +1,113 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkState.h>
#include <mitkTransition.h>
#include "mitkTestingMacros.h"
#include <fstream>
/**
*http://msdn.microsoft.com/en-us/library/e5ewb1h3.aspx
* VS9 memory leakage detection
**/
//#ifdef WIN32
//#ifdef _DEBUG
//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>
//#endif
//#endif
int mitkStateTest(int /*argc*/, char* /*argv*/[])
{
int stateId = 10;
//Create State
mitk::State::Pointer state = mitk::State::New("state", stateId);
//check reference count
MITK_TEST_CONDITION_REQUIRED(state->GetReferenceCount() == 1,"Testing ReferenceCount of State");
//check Id
MITK_TEST_CONDITION_REQUIRED(state->GetId()==stateId,"Testing GetID ");
int count = 0;
//Create Transition
std::string firstTName = "firstTransition";
std::string secondTName = "secondTransition";
mitk::Transition* firstTransition = new mitk::Transition(firstTName, count, count+1);
MITK_TEST_CONDITION_REQUIRED(state->AddTransition( firstTransition ),"Adding first transition");
MITK_TEST_CONDITION_REQUIRED(state->IsValidEvent(count+1),"Check if the first EventId is valid");
MITK_TEST_CONDITION_REQUIRED(state->GetTransition(count+1) == firstTransition ,"Getting first transition");
MITK_TEST_CONDITION_REQUIRED(state->GetReferenceCount() == 1,"Testing ReferenceCount still one");
++count;
mitk::Transition* secondTransition = new mitk::Transition(secondTName, count, count+1);
MITK_TEST_CONDITION_REQUIRED(state->AddTransition( secondTransition ),"Adding second transition");
MITK_TEST_CONDITION_REQUIRED(state->IsValidEvent(count+1),"Check if the second EventId is valid");
MITK_TEST_CONDITION_REQUIRED(state->GetTransition(count+1) == secondTransition ,"Getting second transition");
MITK_TEST_CONDITION_REQUIRED(state->GetReferenceCount() == 1,"Testing ReferenceCount still one");
++count;
MITK_TEST_CONDITION_REQUIRED( ! state->IsValidEvent(count+1),"Check if a non existent EventId is valid");
//deleting state and checking if transitions are deleted
state = NULL;
MITK_TEST_CONDITION_REQUIRED(state.IsNull(),"Testing setting state to null and deleting it with it");
std::cout << "Check state with cyclic definition: StateA->TransitionA->StateA: \n";
stateId = 20;
const char* name = "StateA";
state = mitk::State::New(name, stateId);
MITK_TEST_CONDITION_REQUIRED(state->GetId()==stateId,"Testing GetID ");
MITK_TEST_CONDITION_REQUIRED(state->GetName()==name,"Testing GetID ");
MITK_TEST_CONDITION_REQUIRED(state->GetReferenceCount() == 1,"Testing ReferenceCount of State");
std::cout << "Add next state to transition: ";
count = 0;
//creating first transition
firstTransition = new mitk::Transition(firstTName, stateId, count+1);
firstTransition->SetNextState(state);
state->AddTransition(firstTransition);
MITK_TEST_CONDITION_REQUIRED(state->GetReferenceCount() == 1,"Testing ReferenceCount still one");
//creating second transition
secondTransition = new mitk::Transition(secondTName, stateId, count+2);
secondTransition ->SetNextState(state);
state->AddTransition(secondTransition);
MITK_TEST_CONDITION_REQUIRED(state->GetReferenceCount() == 1,"Testing ReferenceCount still one");
//destroying it again.
state = NULL;
MITK_TEST_CONDITION_REQUIRED(state.IsNull(),"Testing setting state to null and deleting it with it");
//doesn't have to be done because the memory is freed in ~State destructor
//delete firstTransition;
//delete secondTransition;
//#ifdef WIN32
//#ifdef _DEBUG
////memory leakage detection
//_CrtDumpMemoryLeaks();
//#endif
//#endif
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkStepperTest.cpp b/Core/Code/Testing/mitkStepperTest.cpp
index eae713cd0a..08a9f73d0e 100644
--- a/Core/Code/Testing/mitkStepperTest.cpp
+++ b/Core/Code/Testing/mitkStepperTest.cpp
@@ -1,46 +1,45 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkStepper.h"
#include "mitkTestingMacros.h"
int mitkStepperTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN(StepperTest)
mitk::Stepper::Pointer stepperA;
stepperA = mitk::Stepper::New();
MITK_TEST_CONDITION_REQUIRED(stepperA.IsNotNull(),"Stepper instantiation.")
// number of steps defaults to zero, SetPos should have no effect, GetPos should return zero
stepperA->SetPos(10);
MITK_TEST_CONDITION_REQUIRED(stepperA->GetPos() == 0,"Pos remains zero if m_Steps is zero.")
mitk::Stepper::Pointer stepperB = mitk::Stepper::New();
stepperA->SetSteps(4);
//stepperA->PingPongOn();
stepperB->SetSteps(6);
// stepperB->PingPongOn();
/* for (int i=0 ; i<10; i++) {
std::cout << i << ": A: " << stepperA->GetPos() << " B:" << stepperB->GetPos() << std::endl;
stepperA->Next();
stepperB->Next();
}*/
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkSurfaceTest.cpp b/Core/Code/Testing/mitkSurfaceTest.cpp
index d55cb5bb09..0f2830cb5a 100644
--- a/Core/Code/Testing/mitkSurfaceTest.cpp
+++ b/Core/Code/Testing/mitkSurfaceTest.cpp
@@ -1,152 +1,151 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurface.h"
#include "mitkCommon.h"
#include "mitkVector.h"
#include "mitkTestingMacros.h"
#include "mitkTimeSlicedGeometry.h"
#include "vtkPolyData.h"
#include "vtkSphereSource.h"
#include <fstream>
int mitkSurfaceTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("Surface");
mitk::Surface::Pointer surface = mitk::Surface::New();
MITK_TEST_CONDITION_REQUIRED( surface.GetPointer(), "Testing initialization!" );
mitk::Surface::Pointer cloneSurface = surface->Clone();
MITK_TEST_CONDITION_REQUIRED( cloneSurface.GetPointer(), "Testing clone surface initialization!" );
vtkSphereSource* sphereSource = vtkSphereSource::New();
sphereSource->SetCenter(0,0,0);
sphereSource->SetRadius(5.0);
sphereSource->SetThetaResolution(10);
sphereSource->SetPhiResolution(10);
sphereSource->Update();
vtkPolyData* polys = sphereSource->GetOutput();
MITK_TEST_CONDITION_REQUIRED(surface->GetVtkPolyData() == NULL, "Testing initial state of vtkPolyData");
surface->SetVtkPolyData( polys );
sphereSource->Delete();
MITK_TEST_CONDITION_REQUIRED(surface->GetVtkPolyData()!= NULL, "Testing set vtkPolyData");
cloneSurface= NULL;
cloneSurface = surface->Clone();
MITK_TEST_CONDITION_REQUIRED(cloneSurface->GetVtkPolyData()!= NULL, "Testing set vtkPolyData of cloned surface!");
cloneSurface = NULL;
vtkFloatingPointType bounds[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
polys->ComputeBounds();
polys->GetBounds( bounds );
surface->UpdateOutputInformation();
surface->SetRequestedRegionToLargestPossibleRegion();
mitk::BoundingBox* bb = const_cast<mitk::BoundingBox*>(surface->GetGeometry()->GetBoundingBox());
mitk::BoundingBox::BoundsArrayType surfBounds = bb->GetBounds();
bool passed = false;
if ( bounds[0] == surfBounds[0] && bounds[1] == surfBounds[1]
&& bounds[2] == surfBounds[2] && bounds[3] == surfBounds[3]
&& bounds[4] == surfBounds[4] && bounds[5] == surfBounds[5] )
{
passed = true;
}
MITK_TEST_CONDITION_REQUIRED(passed, "Testing GetBoundingBox()!");
surface->Expand(5);
surface->Update();
surface->SetRequestedRegionToLargestPossibleRegion();
mitk::Surface::RegionType requestedRegion = surface->GetRequestedRegion();
MITK_TEST_CONDITION_REQUIRED(requestedRegion.GetSize(3) == 5, "Testing mitk::Surface::Expand( timesteps ): ");
vtkFloatingPointType boundsMat[5][6];
for (int i=0;i<5;i++) {
vtkSphereSource* sphereSource = vtkSphereSource::New();
sphereSource->SetCenter(0,0,0);
sphereSource->SetRadius(1.0 * (i+1.0));
sphereSource->SetThetaResolution(10);
sphereSource->SetPhiResolution(10);
sphereSource->Update();
sphereSource->GetOutput()->ComputeBounds();
sphereSource->GetOutput()->GetBounds( boundsMat[i] );
surface->SetVtkPolyData( sphereSource->GetOutput(),i );
sphereSource->Delete();
}
surface->UpdateOutputInformation();
surface->SetRequestedRegionToLargestPossibleRegion();
passed = true;
for (int i=0;i<5;i++)
{
mitk::BoundingBox::BoundsArrayType surfBounds = (const_cast<mitk::BoundingBox*>(surface->GetTimeSlicedGeometry()->GetGeometry3D(i)->GetBoundingBox()))->GetBounds();
if ( boundsMat[i][0] != surfBounds[0]
|| boundsMat[i][1] != surfBounds[1]
|| boundsMat[i][2] != surfBounds[2]
|| boundsMat[i][3] != surfBounds[3]
|| boundsMat[i][4] != surfBounds[4]
|| boundsMat[i][5] != surfBounds[5] )
{
passed = false;
break;
}
}
MITK_TEST_CONDITION_REQUIRED(passed, "Testing mitk::Surface::Testing 4D surface data creation!" );
const mitk::TimeSlicedGeometry* inputTimeGeometry = surface->GetUpdatedTimeSlicedGeometry();
int time = 3;
int timestep=0;
timestep = inputTimeGeometry->MSToTimeStep( time );
MITK_TEST_CONDITION_REQUIRED(time == timestep, "Testing correctness of geometry for surface->GetUpdatedTimeSlicedGeometry()!");
sphereSource = vtkSphereSource::New();
sphereSource->SetCenter(0,0,0);
sphereSource->SetRadius( 100.0 );
sphereSource->SetThetaResolution(10);
sphereSource->SetPhiResolution(10);
sphereSource->Update();
surface->SetVtkPolyData( sphereSource->GetOutput(), 3 );
sphereSource->Delete();
inputTimeGeometry = surface->GetUpdatedTimeSlicedGeometry();
time = 3;
timestep=0;
timestep = inputTimeGeometry->MSToTimeStep( time );
MITK_TEST_CONDITION_REQUIRED(time == timestep, "Explicitly changing the data of timestep 3 and checking for timebounds correctness of surface's geometry again!");
unsigned int numberoftimesteps = surface->GetTimeSteps();
mitk::Surface::Pointer dummy = mitk::Surface::New();
dummy->Graft(surface);
MITK_TEST_CONDITION_REQUIRED( dummy->GetVtkPolyData() != NULL, "Testing copying a Surface with Graft()!");
MITK_TEST_CONDITION_REQUIRED( dummy->GetTimeSteps() == numberoftimesteps, "orig-numberofTimeSteps:" << numberoftimesteps << " copy-numberofTimeSteps:" << dummy->GetTimeSteps());
surface = NULL;
MITK_TEST_CONDITION_REQUIRED( surface.IsNull(), "Testing destruction of surface!");
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkSurfaceToSurfaceFilterTest.cpp b/Core/Code/Testing/mitkSurfaceToSurfaceFilterTest.cpp
index caf2cd5202..86187efa21 100644
--- a/Core/Code/Testing/mitkSurfaceToSurfaceFilterTest.cpp
+++ b/Core/Code/Testing/mitkSurfaceToSurfaceFilterTest.cpp
@@ -1,123 +1,122 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2009-06-18 16:11:33 +0200 (Do, 18 Jun 2009) $
-Version: $Revision: 17789 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurface.h"
#include "mitkSurfaceToSurfaceFilter.h"
#include "mitkCommon.h"
#include "mitkVector.h"
#include "mitkTimeSlicedGeometry.h"
#include "vtkPolyData.h"
#include "vtkSphereSource.h"
#include <fstream>
int mitkSurfaceToSurfaceFilterTest(int /*argc*/, char* /*argv*/[])
{
mitk::Surface::Pointer surface;
surface = mitk::Surface::New();
vtkSphereSource* sphereSource = vtkSphereSource::New();
sphereSource->SetCenter(0,0,0);
sphereSource->SetRadius(5.0);
sphereSource->SetThetaResolution(10);
sphereSource->SetPhiResolution(10);
sphereSource->Update();
vtkPolyData* polys = sphereSource->GetOutput();
surface->SetVtkPolyData( polys );
sphereSource->Delete();
mitk::SurfaceToSurfaceFilter::Pointer filter = mitk::SurfaceToSurfaceFilter::New();
std::cout << "Testing mitk::SurfaceToSurfaceFilter::SetInput() and ::GetNumberOfInputs() : " ;
filter->SetInput( surface );
if ( filter->GetNumberOfInputs() < 1 )
{
std::cout<<"[FAILED] : zero inputs set "<<std::endl;
return EXIT_FAILURE;
}
std::cout << "Testing if GetInput returns the right Input : " << std::endl;
if ( filter->GetInput() != surface )
{
std::cout<<"[FAILED] : GetInput does not return correct input. "<<std::endl;
return EXIT_FAILURE;
}
std::cout << "[SUCCESS] : input correct" << std::endl;
if ( filter->GetInput(5) != NULL )
{
std::cout<<"[FAILED] : GetInput returns inputs that were not set. "<<std::endl;
return EXIT_FAILURE;
}
std::cout << "[SUCCESS] : Input nr.5 was not set -> is NULL" << std::endl;
std::cout << "Testing whether Output is created correctly : " << std::endl;
if ( filter->GetNumberOfOutputs() != filter->GetNumberOfInputs() )
{
std::cout <<"[FAILED] : number of outputs != number of inputs" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[SUCCESS] : number of inputs == number of outputs." << std::endl;
mitk::Surface::Pointer outputSurface = filter->GetOutput(0);
if ( outputSurface->GetVtkPolyData()->GetNumberOfPolys() != surface->GetVtkPolyData()->GetNumberOfPolys() )
{
std::cout << "[FAILED] : number of Polys in PolyData of output != number of Polys in PolyData of input" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[SUCCESS] : number of Polys in PolyData of input and output are identical." << std::endl;
filter->Update();
outputSurface = filter->GetOutput(0);
if ( outputSurface->GetSizeOfPolyDataSeries() != surface->GetSizeOfPolyDataSeries() )
{
std::cout << "[FAILED] : number of PolyDatas in PolyDataSeries of output != number of PolyDatas of input" << std::endl;
return EXIT_FAILURE;
}
std::cout << "[SUCCESS] : Size of PolyDataSeries of input and output are identical." << std::endl;
std::cout << "Testing removeInputs() : " << std::endl;
unsigned int numOfInputs = filter->GetNumberOfInputs();
filter->RemoveInputs( mitk::Surface::New() );
if ( filter->GetNumberOfInputs() != numOfInputs )
{
std::cout << "[FAILED] : input was removed that was not set." << std::endl;
return EXIT_FAILURE;
}
std::cout << "[SUCCESS] : no iput was removed that was not set." << std::endl;
filter->RemoveInputs( surface );
if ( filter->GetNumberOfInputs() != 0 )
{
std::cout << "[FAILED] : existing input was not removed correctly." << std::endl;
return EXIT_FAILURE;
}
std::cout << "[SUCCESS] : existing input was removed correctly." << std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkSurfaceVtkWriterTest.cpp b/Core/Code/Testing/mitkSurfaceVtkWriterTest.cpp
index 5cb1bd14cf..080c8e0d32 100644
--- a/Core/Code/Testing/mitkSurfaceVtkWriterTest.cpp
+++ b/Core/Code/Testing/mitkSurfaceVtkWriterTest.cpp
@@ -1,86 +1,85 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkSurfaceVtkWriter.h"
#include "mitkTestingMacros.h"
#include <vtkPolyDataReader.h>
#include <vtkPolyDataWriter.h>
#include <iostream>
/**
* Simple example for a test for the (non-existent) class "ClassName".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkSurfaceVtkWriterTest(int /*argc*/ , char* argv[])
{
// always start with this!
MITK_TEST_BEGIN("SurfaceVtkWriter")
// let's create an object of our class
mitk::SurfaceVtkWriter<vtkPolyDataWriter>::Pointer mySurfaceVtkWriter = mitk::SurfaceVtkWriter<vtkPolyDataWriter>::New();
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
MITK_TEST_CONDITION_REQUIRED(mySurfaceVtkWriter.IsNotNull(),"Testing instantiation")
// create contour
vtkPolyDataReader* reader = vtkPolyDataReader::New();
reader->SetFileName(argv[1]);
reader->Update();
if (reader->GetOutput())
{
mitk::Surface::Pointer surface = mitk::Surface::New();
surface->SetVtkPolyData(reader->GetOutput());
surface->Update();
MITK_TEST_CONDITION_REQUIRED(surface.IsNotNull(),"Surface creation")
try{
// test for exception handling
MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject)
mySurfaceVtkWriter->SetInput(surface);
mySurfaceVtkWriter->SetFileName("/usr/bin");
mySurfaceVtkWriter->Update();
MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject)
}
catch(...) {
//this means that a wrong exception (i.e. no itk:Exception) has been thrown
std::cout << "Wrong exception (i.e. no itk:Exception) caught during write [FAILED]" << std::endl;
return EXIT_FAILURE;
}
// write your own tests here and use the macros from mitkTestingMacros.h !!!
// do not write to std::cout and do not return from this function yourself!
// always end with this!
}
//Delete reader correctly
reader->Delete();
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkTestUtilSharedLibrary.cpp b/Core/Code/Testing/mitkTestUtilSharedLibrary.cpp
index 5e48b10b60..d7dee58205 100644
--- a/Core/Code/Testing/mitkTestUtilSharedLibrary.cpp
+++ b/Core/Code/Testing/mitkTestUtilSharedLibrary.cpp
@@ -1,168 +1,167 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <string>
#include <stdexcept>
#include "mitkTestingConfig.h"
#if defined(__APPLE__)
#define PLATFORM_APPLE
#endif
#if defined(unix) || defined(__unix) || defined(__APPLE__)
#include <dlfcn.h>
#define PLATFORM_UNIX
#elif defined(_WIN32)
#include <Windows.h>
#include <strsafe.h>
#define PLATFORM_WINDOWS
#else
#error Unsupported platform
#endif
namespace mitk {
class SharedLibraryHandle
{
public:
SharedLibraryHandle() : m_Handle(0) {}
SharedLibraryHandle(const std::string& name)
: m_Name(name), m_Handle(0)
{}
virtual ~SharedLibraryHandle() {}
void Load()
{
Load(m_Name);
}
void Load(const std::string& name)
{
if (m_Handle) throw std::logic_error(std::string("Library already loaded: ") + name);
std::string libPath = GetAbsolutePath(name);
#ifdef PLATFORM_UNIX
m_Handle = dlopen(libPath.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (!m_Handle)
{
const char* err = dlerror();
throw std::runtime_error(err ? std::string(err) : libPath);
}
#else
m_Handle = LoadLibrary(libPath.c_str());
if (!m_Handle)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)libPath.c_str()) + 50) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("Loading %s failed with error %d: %s"),
libPath.c_str(), dw, lpMsgBuf);
std::string errMsg((LPCTSTR)lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
throw std::runtime_error(errMsg);
}
#endif
m_Name = name;
}
void Unload()
{
if (m_Handle)
{
#ifdef PLATFORM_UNIX
dlclose(m_Handle);
#else
FreeLibrary((HMODULE)m_Handle);
#endif
m_Handle = 0;
}
}
std::string GetAbsolutePath(const std::string& name)
{
return GetLibraryPath() + "/" + Prefix() + name + Suffix();
}
std::string GetAbsolutePath()
{
return GetLibraryPath() + "/" + Prefix() + m_Name + Suffix();
}
static std::string GetLibraryPath()
{
return std::string(MITK_RUNTIME_OUTPUT_DIR);
}
static std::string Suffix()
{
#ifdef PLATFORM_WINDOWS
return ".dll";
#elif defined(PLATFORM_APPLE)
return ".dylib";
#else
return ".so";
#endif
}
static std::string Prefix()
{
#if defined(PLATFORM_UNIX)
return "lib";
#else
return "";
#endif
}
private:
SharedLibraryHandle(const SharedLibraryHandle&);
SharedLibraryHandle& operator = (const SharedLibraryHandle&);
std::string m_Name;
void* m_Handle;
};
} // namespace mitk
diff --git a/Core/Code/Testing/mitkTimeSlicedGeometryTest.cpp b/Core/Code/Testing/mitkTimeSlicedGeometryTest.cpp
index ccba0d8cb2..d4626e6a7e 100644
--- a/Core/Code/Testing/mitkTimeSlicedGeometryTest.cpp
+++ b/Core/Code/Testing/mitkTimeSlicedGeometryTest.cpp
@@ -1,454 +1,453 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2006-06-09 15:24:07 +0200 (Fr, 09 Jun 2006) $
-Version: $Revision: 7074 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkImage.h"
#include "mitkPlaneGeometry.h"
#include "mitkTimeSlicedGeometry.h"
#include "mitkSlicedGeometry3D.h"
#include "mitkGeometry2D.h"
#include "mitkTestingMacros.h"
#include <vnl/vnl_quaternion.h>
#include <vnl/vnl_quaternion.txx>
#include <fstream>
void mitkTimeSlicedGeometry_ChangeImageGeometryConsideringOriginOffset_Test()
{
// additional tests to check the function ChangeImageGeometryConsideringOriginOffset(..)
//first create a new timeslicedgeometry
mitk::TimeSlicedGeometry::Pointer geoTime = mitk::TimeSlicedGeometry::New();
mitk::Geometry3D::Pointer geo3d = mitk::Geometry3D::New();
geo3d->Initialize();
int numOfTimeSteps = 5;
geoTime->InitializeEvenlyTimed(geo3d, numOfTimeSteps);
for (int i=0; i < numOfTimeSteps; i++)
{
mitk::Geometry3D::Pointer geo3d_sub = mitk::Geometry3D::New();
geo3d_sub->Initialize();
geoTime->SetGeometry3D(geo3d_sub, i);
}
MITK_TEST_OUTPUT( << "Testing whether geoTime->GetImageGeometry() is false by default");
MITK_TEST_CONDITION_REQUIRED( geoTime->GetImageGeometry()==false, "");
MITK_TEST_OUTPUT( << "Testing whether first and last geometry in the geoTime have GetImageGeometry()==false by default");
mitk::Geometry3D* subSliceGeo3D_first = geoTime->GetGeometry3D(0);
mitk::Geometry3D* subSliceGeo3D_last = geoTime->GetGeometry3D(numOfTimeSteps-1);
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_first->GetImageGeometry()==false, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_last->GetImageGeometry()==false, "");
// Save some Origins and cornerpoints
mitk::Point3D OriginTimeGeo( geoTime->GetOrigin() );
mitk::Point3D OriginFirstGeo( subSliceGeo3D_first->GetOrigin() );
mitk::Point3D OriginLastGeo( subSliceGeo3D_last->GetOrigin() );
mitk::Point3D CornerPoint0TimeGeo(geoTime->GetCornerPoint(0));
mitk::Point3D CornerPoint1FirstGeo(subSliceGeo3D_first->GetCornerPoint(1));
mitk::Point3D CornerPoint2LastGeo(subSliceGeo3D_last->GetCornerPoint(2));
//std::cout << "vorher Origin: " << subSliceGeo3D_first->GetOrigin() << std::endl;
//std::cout << "vorher Corner: " << subSliceGeo3D_first->GetCornerPoint(0) << std::endl;
MITK_TEST_OUTPUT( << "Calling geoTime->ChangeImageGeometryConsideringOriginOffset(true)");
geoTime->ChangeImageGeometryConsideringOriginOffset(true);
//std::cout << "nachher Origin: " << subSliceGeo3D_first->GetOrigin() << std::endl;
//std::cout << "nachher Corner: " << subSliceGeo3D_first->GetCornerPoint(0) << std::endl;
MITK_TEST_OUTPUT( << "Testing whether geoTime->GetImageGeometry() is now true");
MITK_TEST_CONDITION_REQUIRED( geoTime->GetImageGeometry()==true, "");
MITK_TEST_OUTPUT( << "Testing whether first and last geometry in the SlicedGeometry3D have GetImageGeometry()==true now");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_first->GetImageGeometry()==true, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_last->GetImageGeometry()==true, "");
MITK_TEST_OUTPUT( << "Testing wether offset has been added to origins");
// Manually adding Offset.
OriginTimeGeo[0] += (geoTime->GetSpacing()[0]) / 2;
OriginTimeGeo[1] += (geoTime->GetSpacing()[1]) / 2;
OriginTimeGeo[2] += (geoTime->GetSpacing()[2]) / 2;
OriginFirstGeo[0] += (subSliceGeo3D_first->GetSpacing()[0]) / 2;
OriginFirstGeo[1] += (subSliceGeo3D_first->GetSpacing()[1]) / 2;
OriginFirstGeo[2] += (subSliceGeo3D_first->GetSpacing()[2]) / 2;
OriginLastGeo[0] += (subSliceGeo3D_last->GetSpacing()[0]) / 2;
OriginLastGeo[1] += (subSliceGeo3D_last->GetSpacing()[1]) / 2;
OriginLastGeo[2] += (subSliceGeo3D_last->GetSpacing()[2]) / 2;
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_first->GetCornerPoint(1)==CornerPoint1FirstGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_last->GetCornerPoint(2)==CornerPoint2LastGeo, "");
MITK_TEST_CONDITION_REQUIRED( geoTime->GetCornerPoint(0)==CornerPoint0TimeGeo, "");
MITK_TEST_CONDITION_REQUIRED( geoTime->GetOrigin()==OriginTimeGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_first->GetOrigin()==OriginFirstGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_last->GetOrigin()==OriginLastGeo, "");
MITK_TEST_OUTPUT( << "Calling geoTime->ChangeImageGeometryConsideringOriginOffset(false)");
geoTime->ChangeImageGeometryConsideringOriginOffset(false);
MITK_TEST_OUTPUT( << "Testing whether geoTime->GetImageGeometry() is now false");
MITK_TEST_CONDITION_REQUIRED( geoTime->GetImageGeometry()==false, "");
MITK_TEST_OUTPUT( << "Testing whether first and last geometry in the geoTime have GetImageGeometry()==false now");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_first->GetImageGeometry()==false, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_last->GetImageGeometry()==false, "");
MITK_TEST_OUTPUT( << "Testing wether offset has been added to origins");
// Manually substracting Offset.
OriginTimeGeo[0] -= (geoTime->GetSpacing()[0]) / 2;
OriginTimeGeo[1] -= (geoTime->GetSpacing()[1]) / 2;
OriginTimeGeo[2] -= (geoTime->GetSpacing()[2]) / 2;
OriginFirstGeo[0] -= (subSliceGeo3D_first->GetSpacing()[0]) / 2;
OriginFirstGeo[1] -= (subSliceGeo3D_first->GetSpacing()[1]) / 2;
OriginFirstGeo[2] -= (subSliceGeo3D_first->GetSpacing()[2]) / 2;
OriginLastGeo[0] -= (subSliceGeo3D_last->GetSpacing()[0]) / 2;
OriginLastGeo[1] -= (subSliceGeo3D_last->GetSpacing()[1]) / 2;
OriginLastGeo[2] -= (subSliceGeo3D_last->GetSpacing()[2]) / 2;
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_first->GetCornerPoint(1)==CornerPoint1FirstGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_last->GetCornerPoint(2)==CornerPoint2LastGeo, "");
MITK_TEST_CONDITION_REQUIRED( geoTime->GetCornerPoint(0)==CornerPoint0TimeGeo, "");
MITK_TEST_CONDITION_REQUIRED( geoTime->GetOrigin()==OriginTimeGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_first->GetOrigin()==OriginFirstGeo, "");
MITK_TEST_CONDITION_REQUIRED( subSliceGeo3D_last->GetOrigin()==OriginLastGeo, "");
}
int mitkTimeSlicedGeometryTest(int /*argc*/, char* /*argv*/[])
{
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
mitk::Point3D origin;
mitk::Vector3D right, bottom, normal;
mitk::ScalarType width, height;
mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
width = 100; widthInMM = width*0.5;
height = 200; heightInMM = height*1.2;
thicknessInMM = 1.5;
mitk::FillVector3D(origin, 2.5, -3.3, 17.2);
mitk::FillVector3D(right, widthInMM, 0, 0);
mitk::FillVector3D(bottom, 0, heightInMM, 0);
mitk::FillVector3D(normal, 0, 0, thicknessInMM);
std::cout << "Creating TimeSlicedGeometry" <<std::endl;
mitk::TimeSlicedGeometry::Pointer timeSlicedGeometry = mitk::TimeSlicedGeometry::New();
if(timeSlicedGeometry.IsNull())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
unsigned int numOfTimeSteps = 5;
std::cout << "Testing TimeSlicedGeometry::Initialize(timesteps = " << numOfTimeSteps << "): " <<std::endl;
timeSlicedGeometry->InitializeEvenlyTimed(numOfTimeSteps);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::GetTimeSteps()==" << numOfTimeSteps << ": " <<std::endl;
if(timeSlicedGeometry->GetTimeSteps()!=numOfTimeSteps)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::GetEvenlyTimed(): " <<std::endl;
if(timeSlicedGeometry->GetEvenlyTimed()!=true)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
mitk::TimeBounds timeBounds1;
timeBounds1[0] = 1.3;
timeBounds1[1] = 2.4;
std::cout << "Initializing a PlaneGeometry by InitializeStandardPlane(rightVector, downVector, spacing = NULL): "<<std::endl;
planegeometry->InitializeStandardPlane(right.Get_vnl_vector(), bottom.Get_vnl_vector());
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Setting TimeBounds of PlaneGeometry by SetTimeBounds(): "<<std::endl;
planegeometry->SetTimeBounds(timeBounds1);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing PlaneGeometry::GetTimeBounds(): "<<std::endl;
if(planegeometry->GetTimeBounds() != timeBounds1)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
--numOfTimeSteps;
std::cout << "Testing TimeSlicedGeometry::InitializeEvenlyTimed(planegeometry, timesteps = " << numOfTimeSteps << "): " <<std::endl;
mitk::TimeSlicedGeometry::Pointer timeSlicedGeometry2 = mitk::TimeSlicedGeometry::New();
timeSlicedGeometry2->InitializeEvenlyTimed(planegeometry, numOfTimeSteps);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::GetTimeSteps()==" << numOfTimeSteps << ": " <<std::endl;
if(timeSlicedGeometry2->GetTimeSteps() != numOfTimeSteps)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::GetEvenlyTimed(): " <<std::endl;
if(timeSlicedGeometry2->GetEvenlyTimed()!=true)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::TimeStepToMS(): " << std::endl;
if(fabs(timeSlicedGeometry2->TimeStepToMS( 2 ) - 3.5) > mitk::eps)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::MSToTimeStep(): " << std::endl;
if(timeSlicedGeometry2->MSToTimeStep( 3.6 ) != 2)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::TimeStepToTimeStep(): " << std::endl;
// Re-use timeSlicedGeometry with new time bounds
mitk::TimeBounds timeBounds;
timeBounds[0] = 0.0;
timeBounds[1] = 1.0;
mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New();
geometry->Initialize();
geometry->SetTimeBounds( timeBounds );
timeSlicedGeometry->InitializeEvenlyTimed( geometry, numOfTimeSteps+1 );
if(timeSlicedGeometry2->TimeStepToTimeStep( timeSlicedGeometry, 4 ) != 2)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing availability and type (PlaneGeometry) of first geometry in the TimeSlicedGeometry: ";
mitk::PlaneGeometry* accessedplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(timeSlicedGeometry2->GetGeometry3D(0));
if(accessedplanegeometry==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing identity of first geometry to the planegeometry in the TimeSlicedGeometry (should not be cloned): ";
if(accessedplanegeometry != planegeometry.GetPointer())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing whether the spatial part of the first geometry in the TimeSlicedGeometry is identical to planegeometry by axis comparison and origin: "<<std::endl;
if((mitk::Equal(accessedplanegeometry->GetAxisVector(0), planegeometry->GetAxisVector(0))==false) ||
(mitk::Equal(accessedplanegeometry->GetAxisVector(1), planegeometry->GetAxisVector(1))==false) ||
(mitk::Equal(accessedplanegeometry->GetAxisVector(2), planegeometry->GetAxisVector(2))==false) ||
(mitk::Equal(accessedplanegeometry->GetOrigin(), planegeometry->GetOrigin())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing timebounds of first geometry: "<<std::endl;
if( timeBounds1 != accessedplanegeometry->GetTimeBounds() )
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing availability and type (PlaneGeometry) of second geometry in the TimeSlicedGeometry: ";
mitk::PlaneGeometry* secondplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(timeSlicedGeometry2->GetGeometry3D(1));
if(secondplanegeometry==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing PlaneGeometry::GetTimeBounds(): "<<std::endl;
const mitk::TimeBounds & secondtimebounds = secondplanegeometry->GetTimeBounds();
if( (timeBounds1[1] != secondtimebounds[0]) || (secondtimebounds[1] != secondtimebounds[0] + timeBounds1[1]-timeBounds1[0]) )
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing whether the spatial part of the second geometry in the TimeSlicedGeometry is identical to planegeometry by axis comparison and origin: "<<std::endl;
if((mitk::Equal(secondplanegeometry->GetAxisVector(0), planegeometry->GetAxisVector(0))==false) ||
(mitk::Equal(secondplanegeometry->GetAxisVector(1), planegeometry->GetAxisVector(1))==false) ||
(mitk::Equal(secondplanegeometry->GetAxisVector(2), planegeometry->GetAxisVector(2))==false) ||
(mitk::Equal(secondplanegeometry->GetOrigin(), planegeometry->GetOrigin())==false))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
// non-evenly-timed
std::cout << "Creating (new) TimeSlicedGeometry" <<std::endl;
timeSlicedGeometry2 = mitk::TimeSlicedGeometry::New();
if(timeSlicedGeometry2.IsNull())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
numOfTimeSteps += 7;
std::cout << "Testing TimeSlicedGeometry::InitializeEmpty(timesteps = " << numOfTimeSteps << "): " <<std::endl;
timeSlicedGeometry2->InitializeEmpty(numOfTimeSteps);
std::cout << "Testing TimeSlicedGeometry::GetEvenlyTimed():" <<std::endl;
if(timeSlicedGeometry2->GetEvenlyTimed()!=false)
{
std::cout<<"[FAILED]"<<std::endl; ///\todo additionally test Initialize, default should be non-evenly-timed
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::SetEvenlyTimed(false):" <<std::endl;
timeSlicedGeometry2->SetEvenlyTimed(false);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::GetEvenlyTimed()==false:" <<std::endl;
if(timeSlicedGeometry2->GetEvenlyTimed()!=false)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::GetTimeSteps()==" << numOfTimeSteps << ": " <<std::endl;
if(timeSlicedGeometry2->GetTimeSteps() != numOfTimeSteps)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing availability of first geometry in the TimeSlicedGeometry (should not exist): ";
mitk::Geometry3D* accessedgeometry = timeSlicedGeometry2->GetGeometry3D(0);
if(accessedgeometry!=NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::SetGeometry3D(planegeometry, timesteps = 0): " <<std::endl;
timeSlicedGeometry2->SetGeometry3D(planegeometry, 0);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing availability and type (PlaneGeometry) of first geometry in the TimeSlicedGeometry: ";
accessedplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(timeSlicedGeometry2->GetGeometry3D(0));
if(accessedplanegeometry==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing identity of first geometry to the planegeometry in the TimeSlicedGeometry: ";
if(accessedplanegeometry != planegeometry.GetPointer())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing availability of second geometry in the TimeSlicedGeometry (should not exist): ";
accessedgeometry = timeSlicedGeometry2->GetGeometry3D(1);
if(accessedgeometry!=NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Setting planegeometry2 to a cloned version of planegeometry: "<<std::endl;
mitk::PlaneGeometry::Pointer planegeometry2;
planegeometry2 = dynamic_cast<mitk::PlaneGeometry*>(planegeometry->Clone().GetPointer());;
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Changing timebounds of planegeometry2: "<<std::endl;
mitk::TimeBounds timeBounds3;
timeBounds3[0] = timeBounds[1];
timeBounds3[1] = timeBounds3[0]+13.2334;
planegeometry2->SetTimeBounds(timeBounds3);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing TimeSlicedGeometry::SetGeometry3D(planegeometry2, timesteps = 1): " <<std::endl;
timeSlicedGeometry2->SetGeometry3D(planegeometry2, 1);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing availability and type (PlaneGeometry) of second geometry in the TimeSlicedGeometry: ";
accessedplanegeometry = dynamic_cast<mitk::PlaneGeometry*>(timeSlicedGeometry2->GetGeometry3D(1));
if(accessedplanegeometry==NULL)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing identity of second geometry to the planegeometry2 in the TimeSlicedGeometry: ";
if(accessedplanegeometry != planegeometry2.GetPointer())
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Testing timebounds of second geometry: "<<std::endl;
if( timeBounds3 != accessedplanegeometry->GetTimeBounds() )
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
// run additional tests to check the function ChangeImageGeometryConsideringOriginOffset(..)
mitkTimeSlicedGeometry_ChangeImageGeometryConsideringOriginOffset_Test();
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkTransferFunctionTest.cpp b/Core/Code/Testing/mitkTransferFunctionTest.cpp
index 6a4f70265e..946b0c4cac 100644
--- a/Core/Code/Testing/mitkTransferFunctionTest.cpp
+++ b/Core/Code/Testing/mitkTransferFunctionTest.cpp
@@ -1,278 +1,277 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkTransferFunction.h"
#include "mitkTransferFunctionInitializer.h"
#include "mitkTestingMacros.h"
#include <iostream>
/**
* Unit test for class mitk::TransferFunction.
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkTransferFunctionTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("TransferFunction");
// let's create an object of our class
mitk::TransferFunction::Pointer myTransferFunction = mitk::TransferFunction::New();
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
MITK_TEST_CONDITION_REQUIRED( myTransferFunction.IsNotNull(), "Testing instantiation" );
/*************************************************************************/
// Create and set control point arrays for scalar opacity transfer function
mitk::TransferFunction::ControlPoints scalarOpacityPoints;
scalarOpacityPoints.push_back( std::make_pair( 0.0, 0.0 ) );
scalarOpacityPoints.push_back( std::make_pair( 5.0, 0.3 ) );
scalarOpacityPoints.push_back( std::make_pair( 10.0, 1.0 ) );
myTransferFunction->SetScalarOpacityPoints( scalarOpacityPoints );
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetScalarOpacityFunction()->GetSize() == 3,
"Adding three point/value pairs to scalar opacity transfer function via VTK interface" );
// Create and set control point arrays for gradient opacity transfer function
mitk::TransferFunction::ControlPoints gradientOpacityPoints;
gradientOpacityPoints.push_back( std::make_pair( 0.0, 0.2 ) );
gradientOpacityPoints.push_back( std::make_pair( 3.0, 0.7 ) );
gradientOpacityPoints.push_back( std::make_pair( 7.0, 0.8 ) );
gradientOpacityPoints.push_back( std::make_pair( 15.0, 0.9 ) );
myTransferFunction->SetGradientOpacityPoints( gradientOpacityPoints );
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetGradientOpacityFunction()->GetSize() == 4,
"Adding four point/value pairs to gradient opacity transfer function via VTK interface" );
// Create and set control point arrays for color transfer function
mitk::TransferFunction::RGBControlPoints colorPoints;
itk::RGBPixel< double > rgb0, rgb1, rgb2, rgb3;
rgb0[0] = 0.1f; rgb0[1] = 0.3f; rgb0[2] = 0.5f;
colorPoints.push_back( std::make_pair( 2.0, rgb0 ) );
rgb1[0] = 0.3; rgb1[1] = 0.8; rgb1[2] = 0.9;
colorPoints.push_back( std::make_pair( 3.0, rgb1 ) );
rgb2[0] = 0.6; rgb2[1] = 0.5; rgb2[2] = 0.4;
colorPoints.push_back( std::make_pair( 4.0, rgb2 ) );
rgb3[0] = 0.7; rgb3[1] = 0.1; rgb3[2] = 0.2;
colorPoints.push_back( std::make_pair( 5.0, rgb3 ) );
myTransferFunction->SetRGBPoints( colorPoints );
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetColorTransferFunction()->GetSize() == 4,
"Adding four point/value pairs to color transfer function via VTK interface" );
/*************************************************************************/
// Add a new point to scalar opacity transfer function
myTransferFunction->AddScalarOpacityPoint( 3.0, 0.2 );
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetScalarOpacityFunction()->GetSize() == 4,
"Adding new point/value to scalar opacity transfer function via MITK interface" );
// Add a new point to gradient opacity transfer function
myTransferFunction->AddGradientOpacityPoint( 19.0, 1.0 );
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetGradientOpacityFunction()->GetSize() == 5,
"Adding new point/value to gradient opacity transfer function via MITK interface" );
// Add a new point to color transfer function
myTransferFunction->AddRGBPoint( 1.0, 0.0, 0.1, 0.2 );
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetColorTransferFunction()->GetSize() == 5,
"Adding new point/value to color transfer function via MITK interface" );
/*************************************************************************/
// Retrieve two points from scalar opacity transfer function
double v1, v2;
v1 = myTransferFunction->GetScalarOpacityFunction()->GetValue( 3.0 );
v2 = myTransferFunction->GetScalarOpacityFunction()->GetValue( 10.0 );
MITK_TEST_CONDITION_REQUIRED(
(fabs( v1 - 0.2 ) < 1.0e-5) && (fabs( v2 - 1.0 ) < 1.0e-5),
"Retrieving values at two points from scalar opacity transfer function" );
// Retrieve two points from gradient opacity transfer function
v1 = myTransferFunction->GetGradientOpacityFunction()->GetValue( 0.0 );
v2 = myTransferFunction->GetGradientOpacityFunction()->GetValue( 19.0 );
MITK_TEST_CONDITION_REQUIRED(
(fabs( v1 - 0.2 ) < 1.0e-5) && (fabs( v2 - 1.0 ) < 1.0e-5),
"Retrieving values at two points from gradient opacity transfer function" );
// Retrieve two points from color transfer function
vtkFloatingPointType vrgb1[3], vrgb2[3];
myTransferFunction->GetColorTransferFunction()->GetColor( 1.0, vrgb1 );
myTransferFunction->GetColorTransferFunction()->GetColor( 4.0, vrgb2 );
std::cout << vrgb2[0] << ", " << vrgb2[1] << ", " << vrgb2[2] << std::endl;
MITK_TEST_CONDITION_REQUIRED(
(fabs( vrgb1[0] - 0.0 ) < 1.0e-5)
&& (fabs( vrgb1[1] - 0.1 ) < 1.0e-5)
&& (fabs( vrgb1[2] - 0.2 ) < 1.0e-5)
&& (fabs( vrgb2[0] - 0.6 ) < 1.0e-5)
&& (fabs( vrgb2[1] - 0.5 ) < 1.0e-5)
&& (fabs( vrgb2[2] - 0.4 ) < 1.0e-5),
"Retrieving values at two points from color transfer function" );
/*************************************************************************/
// Remove point from scalar opacity transfer function (should return new
// number of points)
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->RemoveScalarOpacityPoint( 3.0 ) == 1,
"Removing point from scalar opacity transfer function (should return point index)" );
// Remove point from scalar opacity transfer function (should return new
// number of points)
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->RemoveGradientOpacityPoint( 0.0 ) == 0,
"Removing point from gradient opacity transfer function (should return point index)" );
// Remove point from color transfer function (should return new
// number of points)
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->RemoveRGBPoint( 5.0 ) == 4,
"Removing point from color transfer function (should return point ndex)" );
/*************************************************************************/
// Try to remove non-existing point from scalar opacity transfer function (should return -1)
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->RemoveScalarOpacityPoint( 2.5 ) == -1,
"Trying to remove non-existing point from scalar opacity transfer function (should return -1)" );
// Try to remove non-existing point from gradient opacity transfer function (should return -1)
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->RemoveGradientOpacityPoint( 2.5 ) == -1,
"Trying to remove non-existing point from gradient opacity transfer function (should return -1)" );
// Try to remove non-existing point from color transfer function (should return -1)
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->RemoveRGBPoint( 2.5 ) == -1,
"Trying to remove non-existing point from color transfer function (should return -1)" );
/*************************************************************************/
// Retrieve copy of scalar opacity points (check for correct content and size)
mitk::TransferFunction::ControlPoints newScalarOpacityPoints =
myTransferFunction->GetScalarOpacityPoints();
MITK_TEST_CONDITION_REQUIRED(
(newScalarOpacityPoints.size() == 3)
&& (fabs(newScalarOpacityPoints[2].first - 10.0) < 1.0e-5)
&& (fabs(newScalarOpacityPoints[2].second - 1.0) < 1.0e-5),
"Retrieving copy of scalar opacity points (checking for correct content and size)" );
// Retrieve copy of gradient opacity points (check for correct content and size)
mitk::TransferFunction::ControlPoints newGradientOpacityPoints =
myTransferFunction->GetGradientOpacityPoints();
MITK_TEST_CONDITION_REQUIRED(
(newGradientOpacityPoints.size() == 4)
&& (fabs(newGradientOpacityPoints[3].first - 19.0) < 1.0e-5)
&& (fabs(newGradientOpacityPoints[3].second - 1.0) < 1.0e-5),
"Retrieving copy of gradient opacity points (checking for correct content and size)" );
// Retrieve copy of color transfer points (check for correct content and size)
mitk::TransferFunction::RGBControlPoints newRGBPoints =
myTransferFunction->GetRGBPoints();
MITK_TEST_CONDITION_REQUIRED(
(newRGBPoints.size() == 4)
&& (fabs(newRGBPoints[3].first - 4.0) < 1.0e-5)
&& (fabs(newRGBPoints[3].second[0] - 0.6) < 1.0e-5)
&& (fabs(newRGBPoints[3].second[1] - 0.5) < 1.0e-5)
&& (fabs(newRGBPoints[3].second[2] - 0.4) < 1.0e-5),
"Retrieving copy of color transfer function points (checking for correct content and size)" );
/*************************************************************************/
// Clear scalar opacity points (resulting array should be empty)
myTransferFunction->ClearScalarOpacityPoints();
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetScalarOpacityPoints().size() == 0,
"Clearing scalar opacity points (resulting array should be empty)" );
myTransferFunction->ClearGradientOpacityPoints();
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetGradientOpacityPoints().size() == 0,
"Clearing gradient opacity points (resulting array should be empty)" );
myTransferFunction->ClearRGBPoints();
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetRGBPoints().size() == 0,
"Clearing color transfer function points (resulting array should be empty)" );
/******************TRANSFERFUNCTION INITIALIZER TEST***************************/
mitk::TransferFunction::Pointer dummyTransferFunction = mitk::TransferFunction::New();
mitk::TransferFunctionInitializer::Pointer transferInit = mitk::TransferFunctionInitializer::New(dummyTransferFunction);
MITK_TEST_CONDITION_REQUIRED(
transferInit->GetTransferFunction().IsNotNull(),
"Testing if Transferfunction is set" );
MITK_TEST_CONDITION_REQUIRED(
transferInit->GetTransferFunction() == dummyTransferFunction,
"Testing if Transferfunction is the correct one" );
transferInit->SetTransferFunction(myTransferFunction);
MITK_TEST_CONDITION_REQUIRED(
transferInit->GetTransferFunction().IsNotNull(),
"Testing if Set Transferfunction works" );
MITK_TEST_CONDITION_REQUIRED(
transferInit->GetTransferFunction() == myTransferFunction,
"Testing if Set Transferfunction sets the correct one" );
const int size = 8;
int arPointNumbers[size][3] = {{3,1,6},
{2,1,2},
{4,1,5},
{3,1,5},
{4,1,7},
{4,2,7},
{4,1,4},
{6,2,6}};
std::string names[size] = {"SetDefaultMode",
"SetCtBlackWhiteMode",
"SetCtThoraxLargeMode",
"SetCtThoraxSmallMode",
"SetCtBoneMode",
"SetCtBoneGradientMode",
"SetCtCardiacMode",
"SetMrGenericMode"};
for(int i =0; i<size; i++)
{
transferInit->SetTransferFunctionMode(i);
std::cout << "Punkte: " << myTransferFunction->GetScalarOpacityFunction()->GetSize() << std::endl;
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetScalarOpacityFunction()->GetSize() == arPointNumbers[i][0],
"Testing if in " << names[i] << " the Scalar Opacity Function is set" );
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetGradientOpacityFunction()->GetSize() == arPointNumbers[i][1],
"Testing if in " << names[i] << " the Gradient Opacity Function is set" );
MITK_TEST_CONDITION_REQUIRED(
myTransferFunction->GetColorTransferFunction()->GetSize() == arPointNumbers[i][2],
"Testing if in " << names[i] << " the Color Transfer Function is set" );
}
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkTransitionTest.cpp b/Core/Code/Testing/mitkTransitionTest.cpp
index 4a72849d2f..f23bd9314f 100644
--- a/Core/Code/Testing/mitkTransitionTest.cpp
+++ b/Core/Code/Testing/mitkTransitionTest.cpp
@@ -1,117 +1,116 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkTransition.h>
#include <mitkAction.h>
#include <mitkState.h>
#include <fstream>
int mitkTransitionTest(int /*argc*/, char* /*argv*/[])
{
int nextStateId = 10;
int eventId = 100;
//Create Transition
itk::WeakPointer<mitk::Transition> transition = new mitk::Transition("transitionname", nextStateId, eventId);
//check nextStateId
std::cout << "Check StateId: ";
if (transition->GetNextStateId()!=nextStateId)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
//check EventId
std::cout << "Check EventId: ";
if (transition->GetEventId()!=eventId || !transition->IsEvent(eventId))
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
unsigned int count = 1;
//Create Action
mitk::Action::Pointer firstAction = mitk::Action::New(count);
transition->AddAction(firstAction);
//check ActionCount
std::cout << "Check ActionCount after first addition of an action: ";
if (transition->GetActionCount() != count)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
++count;
//Create Action
mitk::Action::Pointer secondAction = mitk::Action::New(count);
transition->AddAction(secondAction);
//check ActionCount
std::cout << "check action Count after second addition of an action: ";
if (transition->GetActionCount() != count)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
count = 1;
//check ActionIterators
std::cout << "Check ActionIterators: ";
mitk::Transition::ActionVectorIterator iter = transition->GetActionBeginIterator();
mitk::Transition::ActionVectorConstIterator end = transition->GetActionEndIterator();
while (iter != end)
{
if((*iter)->GetActionId()!=(int)count)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
++count;
++iter;
}
std::cout<<"[PASSED]"<<std::endl;
//check setting State
std::cout << "Check setting a statepointer and reading it again: ";
int stateId = 10000;
mitk::State::Pointer state = mitk::State::New("statename", stateId);
transition->SetNextState(state);
if (transition->GetNextState()!=state)
{
std::cout<<"[FAILED]"<<std::endl;
return EXIT_FAILURE;
}
std::cout<<"[PASSED]"<<std::endl;
//delete the instanciated transition
delete transition;
//well done!!! Passed!
std::cout<<"[ALL PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkUndoControllerTest.cpp b/Core/Code/Testing/mitkUndoControllerTest.cpp
index 8fd173a772..2d1c1f80db 100644
--- a/Core/Code/Testing/mitkUndoControllerTest.cpp
+++ b/Core/Code/Testing/mitkUndoControllerTest.cpp
@@ -1,83 +1,82 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkUndoController.h"
#include "mitkVerboseLimitedLinearUndo.h"
#include "mitkTestingMacros.h"
#include <iostream>
/**
* Simple example for a test for the (non-existent) class "UndoController".
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkUndoControllerTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("UndoController")
// let's create an object of our class
mitk::UndoController* myUndoController = new mitk::UndoController();
// first test: did this work?
// using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since
// it makes no sense to continue without an object.
MITK_TEST_CONDITION_REQUIRED(myUndoController != NULL, "Testing instantiation")
//check default model (verbose...)
mitk::VerboseLimitedLinearUndo::Pointer standardModel = dynamic_cast<mitk::VerboseLimitedLinearUndo*>(myUndoController->GetCurrentUndoModel());
MITK_TEST_CONDITION_REQUIRED(standardModel.IsNotNull(),"Testing if the standard undo model VerboseLimitedLinearUndo is returned")
//switch to limitedlinearundomodel
myUndoController->AddUndoModel(mitk::UndoController::LIMITEDLINEARUNDO);
mitk::LimitedLinearUndo::Pointer linearModel = dynamic_cast<mitk::LimitedLinearUndo*>(myUndoController->GetCurrentUndoModel());
MITK_TEST_CONDITION_REQUIRED(linearModel.IsNotNull(),"Testing to add and then to read a LimitedLinearUndoModel")
//switching to verbose again
myUndoController->SwitchUndoModel(mitk::UndoController::VERBOSE_LIMITEDLINEARUNDO);
mitk::VerboseLimitedLinearUndo::Pointer anotherVerboseModelPointer = dynamic_cast<mitk::VerboseLimitedLinearUndo*>(myUndoController->GetCurrentUndoModel());
MITK_TEST_CONDITION_REQUIRED(standardModel == anotherVerboseModelPointer,"Testing to switch back again and to be sure, that the poiinters are the same")
//removing verbose; model should be switch to limited
myUndoController->RemoveUndoModel(mitk::UndoController::VERBOSE_LIMITEDLINEARUNDO);
mitk::LimitedLinearUndo::Pointer anotherLinearModel = dynamic_cast<mitk::LimitedLinearUndo*>(myUndoController->GetCurrentUndoModel());
MITK_TEST_CONDITION_REQUIRED(linearModel == anotherLinearModel,"Testing to remove the VerboseLimitedLinearUndoModel and to automatically switch to LimitedLinearUndo")
//switch to limitedlinearundomodel
myUndoController->AddUndoModel(mitk::UndoController::VERBOSE_LIMITEDLINEARUNDO);
mitk::VerboseLimitedLinearUndo::Pointer newVerboseModelPointer = dynamic_cast<mitk::VerboseLimitedLinearUndo*>(myUndoController->GetCurrentUndoModel());
MITK_TEST_CONDITION_REQUIRED(newVerboseModelPointer != standardModel,"Testing to add verbose model and if the new model is equal to the deleted one. Should not be the case!")
//removing boith models
myUndoController->RemoveUndoModel(mitk::UndoController::VERBOSE_LIMITEDLINEARUNDO);
//should not detele, to maintain an UndoController with at least one UndoModel
myUndoController->RemoveUndoModel(mitk::UndoController::LIMITEDLINEARUNDO);
mitk::LimitedLinearUndo::Pointer limited = dynamic_cast<mitk::LimitedLinearUndo*>(myUndoController->GetCurrentUndoModel());
MITK_TEST_CONDITION_REQUIRED(limited.IsNotNull(),"Testing to erase all models. Should be impossible to maintain a working model in UndoController")
delete myUndoController;
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkVectorTest.cpp b/Core/Code/Testing/mitkVectorTest.cpp
index b4f15e05e6..6340522ab4 100644
--- a/Core/Code/Testing/mitkVectorTest.cpp
+++ b/Core/Code/Testing/mitkVectorTest.cpp
@@ -1,126 +1,125 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision$
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <mitkTestingMacros.h>
#include <mitkVector.h>
int mitkVectorTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("mitkVector");
// test itk vector equality methods
itk::Vector<float,3> itkVector_1;
itkVector_1[0] = 4.6;
itkVector_1[1] = 9.76543;
itkVector_1[2] = 746.09;
itk::Vector<float,3> itkVector_2;
itk::Vector<float,3> itkVector_3;
for (int i=0; i<3; i++)
{
itkVector_2[i] = itkVector_1[i] - sqrt(mitk::eps/3);
itkVector_3[i] = itkVector_1[i] - sqrt(mitk::eps/3.1);
}
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(itkVector_1,itkVector_1), "Test vector equality using the same vector with mitk::eps");
MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(itkVector_1,itkVector_2), "Test vector equality using different vectors with an element-wise difference greater than mitk::eps");
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(itkVector_1,itkVector_3), "Test vector equality using different vectors with an element-wise difference less than mitk::eps");
// test itk point equality methods
itk::Point<float,3> itkPoint_1;
itk::Point<float,3> itkPoint_2;
itk::Point<float,3> itkPoint_3;
for (int i=0; i<3; i++)
{
itkPoint_1[i] = itkVector_1[i];
itkPoint_2[i] = itkVector_2[i];
itkPoint_3[i] = itkVector_3[i];
}
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(itkPoint_1,itkPoint_1), "Test point equality using the same point with mitk::eps");
MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(itkPoint_1,itkPoint_2), "Test point equality using different points with an element-wise difference greater than mitk::eps");
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(itkPoint_1,itkPoint_3), "Test point equality using different points with an element-wise difference less than mitk::eps");
// test mitk vnl vector equality methods
mitk::VnlVector mitk_vnl_vector_1(3);
mitk::VnlVector mitk_vnl_vector_2(3);
mitk::VnlVector mitk_vnl_vector_3(3);
for (int i=0; i<3; i++)
{
mitk_vnl_vector_1.put(i,itkVector_1[i]);
mitk_vnl_vector_2.put(i,itkVector_2[i]);
mitk_vnl_vector_3.put(i,itkVector_3[i]);
}
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(mitk_vnl_vector_1,mitk_vnl_vector_1), "Test mitk vnl vector equality using the same mitk vnl vector with mitk::eps");
MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(mitk_vnl_vector_1,mitk_vnl_vector_2), "Test mitk vnl vector equality using different mitk vnl vectors with an element-wise difference greater than mitk::eps");
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(mitk_vnl_vector_1,mitk_vnl_vector_3), "Test mitk vnl vector equality using different mitk vnl vectors with an element-wise difference less than mitk::eps");
// test vnl_vector equality method
vnl_vector_fixed<mitk::ScalarType,7> vnlVector_1;
vnlVector_1[3] = 56.98;
vnlVector_1[4] = 22.32;
vnlVector_1[5] = 1.00;
vnlVector_1[6] = 119.02;
vnl_vector_fixed<mitk::ScalarType,7> vnlVector_2;
vnl_vector_fixed<mitk::ScalarType,7> vnlVector_3;
for (int i=0; i<7; i++)
{
if (i<3)
{
vnlVector_1.put(i,itkVector_1[i]);
}
vnlVector_2[i] = vnlVector_1[i]- sqrt(mitk::eps/6.9);
vnlVector_3[i] = vnlVector_1[i]- sqrt(mitk::eps/7.1);
}
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vnlVector_1,vnlVector_1), "Test vnl vector equality using the same vnl vector with mitk::eps");
MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(vnlVector_1,vnlVector_2), "Test vnl vector equality using different vnl vectors with an element-wise difference greater than mitk::eps");
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(vnlVector_1,vnlVector_3), "Test vnl vector equality using different vnl vectors with an element-wise difference less than mitk::eps");
// test scalar equality method
double scalar1 = 0.5689;
double scalar2 = scalar1 + mitk::eps;
double scalar3 = scalar1 + mitk::eps*0.95;
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(scalar1,scalar1), "Test scalar equality using the same scalar with mitk::eps");
MITK_TEST_CONDITION_REQUIRED(!mitk::Equal(scalar1,scalar2), "Test scalar equality using the different scalars with a difference greater than mitk::eps");
MITK_TEST_CONDITION_REQUIRED(mitk::Equal(scalar1,scalar3), "Test scalar equality using the different scalars with a difference less than mitk::eps");
// test matrix equality methods
vnl_matrix_fixed<mitk::ScalarType,3,3> vnlMatrix3x3_1;
vnlMatrix3x3_1(0,0) = 1.1;
vnlMatrix3x3_1(0,1) = 0.4;
vnlMatrix3x3_1(0,2) = 5.3;
vnlMatrix3x3_1(1,0) = 2.7;
vnlMatrix3x3_1(1,1) = 3578.56418;
vnlMatrix3x3_1(1,2) = 123.56;
vnlMatrix3x3_1(2,0) = 546.89;
vnlMatrix3x3_1(2,1) = 0.0001;
vnlMatrix3x3_1(2,2) = 1.0;
vnl_matrix_fixed<mitk::ScalarType,3,3> vnlMatrix3x3_2;
vnlMatrix3x3_2(0,0) = 1.1000009;
vnlMatrix3x3_2(0,1) = 0.4000009;
vnlMatrix3x3_2(0,2) = 5.3000009;
vnlMatrix3x3_2(1,0) = 2.7000009;
vnlMatrix3x3_2(1,1) = 3578.5641809;
vnlMatrix3x3_2(1,2) = 123.5600009;
vnlMatrix3x3_2(2,0) = 546.8900009;
vnlMatrix3x3_2(2,1) = 0.0001009;
vnlMatrix3x3_2(2,2) = 1.0000009;
mitk::ScalarType epsilon = 0.000001;
MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualElementWise(vnlMatrix3x3_1,vnlMatrix3x3_1,0.0),"Test for matrix equality with given epsilon=0.0 and exactly the same matrix elements");
MITK_TEST_CONDITION_REQUIRED(!mitk::MatrixEqualElementWise(vnlMatrix3x3_1,vnlMatrix3x3_2,0.0),"Test for matrix equality with given epsilon=0.0 and slightly different matrix elements");
MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualElementWise(vnlMatrix3x3_1,vnlMatrix3x3_2,epsilon),"Test for matrix equality with given epsilon and slightly different matrix elements");
MITK_TEST_CONDITION_REQUIRED(!mitk::MatrixEqualRMS(vnlMatrix3x3_1,vnlMatrix3x3_2,0.0),"Test for matrix equality with given epsilon=0.0 and slightly different matrix elements");
MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualRMS(vnlMatrix3x3_1,vnlMatrix3x3_2,epsilon),"Test for matrix equality with given epsilon and slightly different matrix elements");
MITK_TEST_END();
}
diff --git a/Core/Code/Testing/mitkVerboseLimitedLinearUndoTest.cpp b/Core/Code/Testing/mitkVerboseLimitedLinearUndoTest.cpp
index 8bc719709c..79c0c5cf16 100644
--- a/Core/Code/Testing/mitkVerboseLimitedLinearUndoTest.cpp
+++ b/Core/Code/Testing/mitkVerboseLimitedLinearUndoTest.cpp
@@ -1,146 +1,145 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkOperation.h"
#include "mitkUndoController.h"
#include "mitkVerboseLimitedLinearUndo.h"
#include "mitkInteractionConst.h"
#include "mitkTestingMacros.h"
#include <iostream>
int g_GlobalCounter = 0;
namespace mitk {
/**
* @brief Class to check that the destructor of object Operation is called and memory freed
**/
class TestOperation : public Operation
{
public:
TestOperation(OperationType operationType)
: Operation(operationType)
{
g_GlobalCounter++;
};
virtual ~TestOperation()
{
g_GlobalCounter--;
};
};
}//namespace
/**
* @brief Test of the LimitedLinearUndo object
*
* This test was motivated by bug 3248 which had to check memory leakage
* while using mitkOperations within the UndoMechanism.
* OperationObjects are added to the UndoController and stored within
* two lists (m_UndoList and m_RedoList) inside LimitedLinearUndo and
* derived from this VerboseLimitedLinearUndo. When using Undo during
* runtime operations are moved from UndoList to RedoList. In case of
* a new interaction, causing new operations to be stored in the UndoList
* the RedoList needs to be cleared. For this, the operations and all
* connected objects need to be deleted and memory to be freed.
* And this what this test checks!
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkVerboseLimitedLinearUndoTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("VerboseLimitedLinearUndo")
// an UndoController for the management
mitk::UndoController* myUndoController = new mitk::UndoController();
//set model, even if it is verboseLimitedLinearUndo by default; this already is tested by UndoControllerTest!
myUndoController->SwitchUndoModel(mitk::UndoController::VERBOSE_LIMITEDLINEARUNDO);
for (int i = 0; i<2; i++)
{
mitk::TestOperation* doOp = new mitk::TestOperation(mitk::OpTEST);
mitk::TestOperation *undoOp = new mitk::TestOperation(mitk::OpTEST);
mitk::OperationEvent *operationEvent = new mitk::OperationEvent(NULL, doOp, undoOp, "Test");
myUndoController->SetOperationEvent(operationEvent);
//increase the ID to separate the operationEvents from each other. Otherwise they would be undone all together at once.
mitk::OperationEvent::IncCurrObjectEventId();
mitk::UndoStackItem::ExecuteIncrement();
}
//now 2 * 2 operation should have been instanciated
MITK_TEST_CONDITION_REQUIRED(g_GlobalCounter == 4,"checking initialization of mitkOperation");
//undo one operation; 1 operationEvent element in undo list, 1 in Redo list
myUndoController->Undo();
//sending two new OperationEvents: RedoList should be deleted and memory of operations freed
for (int i = 0; i<2; i++)
{
mitk::TestOperation* doOp = new mitk::TestOperation(mitk::OpTEST);
mitk::TestOperation *undoOp = new mitk::TestOperation(mitk::OpTEST);
mitk::OperationEvent *operationEvent = new mitk::OperationEvent(NULL, doOp, undoOp, "Test");
myUndoController->SetOperationEvent(operationEvent);
//increase the ID to separate the operationEvents from each other. Otherwise they would be undone all together at once.
mitk::OperationEvent::IncCurrObjectEventId();
mitk::UndoStackItem::ExecuteIncrement();
}
//2 operations should have been deleted, 4 should have been added
MITK_TEST_CONDITION_REQUIRED(g_GlobalCounter == 6,"checking adding of operations");
//two operations to RedoList
myUndoController->Undo();
myUndoController->ClearRedoList();
//one operationEvent containing 2 operations should have been deleted
MITK_TEST_CONDITION_REQUIRED(g_GlobalCounter == 4,"checking deleting RedoList");
//clear all
myUndoController->Clear();
MITK_TEST_CONDITION_REQUIRED(g_GlobalCounter == 0,"checking deleting all operations in UndoModel");
//sending two new OperationEvents
for (int i = 0; i<2; i++)
{
mitk::TestOperation* doOp = new mitk::TestOperation(mitk::OpTEST);
mitk::TestOperation *undoOp = new mitk::TestOperation(mitk::OpTEST);
mitk::OperationEvent *operationEvent = new mitk::OperationEvent(NULL, doOp, undoOp, "Test");
myUndoController->SetOperationEvent(operationEvent);
//increase the ID to separate the operationEvents from each other. Otherwise they would be undone all together at once.
mitk::OperationEvent::IncCurrObjectEventId();
mitk::UndoStackItem::ExecuteIncrement();
}
MITK_TEST_CONDITION_REQUIRED(g_GlobalCounter == 4,"checking added operations in UndoModel");
delete myUndoController;
//after deleting UndoController g_GlobalCounter will still be 4 because m_CurrentUndoModel inside myUndoModel is a static singleton
MITK_TEST_CONDITION_REQUIRED(g_GlobalCounter == 4,"checking singleton UndoModel");
// always end with this!
MITK_TEST_END()
//operations will be deleted after terminating the application
}
diff --git a/Core/Code/Testing/mitkVtkPropRendererTest.cpp b/Core/Code/Testing/mitkVtkPropRendererTest.cpp
index f3945f4fd2..6bd6ec1ced 100644
--- a/Core/Code/Testing/mitkVtkPropRendererTest.cpp
+++ b/Core/Code/Testing/mitkVtkPropRendererTest.cpp
@@ -1,215 +1,214 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date$
-Version: $Revision: 13308 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkProperty.h"
#include "vtkUnsignedCharArray.h"
#include <mitkPicFileReader.h>
#include <mitkImage.h>
#include <mitkDataStorage.h>
#include <mitkLevelWindow.h>
#include <mitkLevelWindowProperty.h>
#include <mitkVtkPropRenderer.h>
#include <vtkMitkRenderProp.h>
#include <mitkVtkLayerController.h>
#include <mitkNativeRenderWindowInteractor.h> // Needs MitkExt!
#include <itksys/SystemTools.hxx>
#include <fstream>
int mitkVtkPropRendererTest(int argc, char* argv[])
{
//independently read header of pic file
mitkIpPicDescriptor *picheader = NULL;
if (argc >= 1)
{
if(itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameExtension(argv[1])).find(".pic")!=std::string::npos)
picheader = mitkIpPicGetHeader(argv[1], NULL);
}
if( picheader==NULL)
{
std::cout<<"file not found/not a pic-file - test not applied [PASSED]"<<std::endl;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
static long int sum_orig_Pic3D_pic_gz = 14685408;
std::string argv_str(argv[1]);
mitkIpPicGetTags(argv[1], picheader);
//Read pic-Image from file
std::cout << "Reading image: ";
mitk::PicFileReader::Pointer reader = mitk::PicFileReader::New();
reader->SetFileName(argv[1]);
reader->Update();
std::cout<<"[PASSED]"<<std::endl;
mitk::Image::Pointer image = reader->GetOutput();
std::cout << "Creating node: ";
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(image);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating DataStorage: ";
mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Adding node via DataStorage: ";
ds->Add(node);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Adding level-window property: ";
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( image );
levWinProp->SetLevelWindow( levelwindow );
node->GetPropertyList()->SetProperty( "levelwindow", levWinProp );
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating a vtk sphere: ";
vtkSphereSource *sphere = vtkSphereSource::New();
sphere->SetRadius(1.0);
sphere->SetThetaResolution(18);
sphere->SetPhiResolution(18);
vtkPolyDataMapper *map = vtkPolyDataMapper::New();
map->SetInput(sphere->GetOutput());
sphere->Delete();
vtkActor *aSphere = vtkActor::New();
aSphere->SetMapper(map);
map->Delete();
aSphere->GetProperty()->SetColor(0,0,1); // sphere color blue
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating a renderer for the sphere: ";
vtkRenderer *sphereRenderer = vtkRenderer::New();
sphereRenderer->AddActor(aSphere);
aSphere->Delete();
//sphereRenderer->SetBackground(1,1,1); // Background color white
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating vtkRenderWindow and VtkPropRenderer: ";
vtkRenderWindow *renderWindow = vtkRenderWindow::New();
mitk::VtkPropRenderer::Pointer propRenderer = mitk::VtkPropRenderer::New( "the renderer", renderWindow );
//propRenderer->SetMapperID(2);
std::cout<<"[PASSED]"<<std::endl;
//renderWindow->AddRenderer(sphereRenderer);
//renderWindow->SetErase(0);
std::cout << "BaseRenderer::SetData(iterator): ";
propRenderer->SetDataStorage(ds);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Creating vtkMitkRenderProp and connecting it to the VtkPropRenderer: ";
vtkMitkRenderProp* renderProp = vtkMitkRenderProp::New();
renderProp->SetPropRenderer(propRenderer);
propRenderer->GetVtkRenderer()->AddViewProp(renderProp);
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Inserting the sphere into the foreground of the VtkLayerController: ";
mitk::VtkLayerController::GetInstance(renderWindow)->InsertForegroundRenderer(sphereRenderer,true);
std::cout<<"[PASSED]"<<std::endl;
// mouse interaction for debugging
//vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
//iren->SetRenderWindow(renderWindow);
std::cout << "Setting and getting size of renderWindow: ";
renderWindow->SetSize(400, 400);
int *size = renderWindow->GetSize();
std::cout<<"[PASSED]"<<std::endl;
std::cout << "Do the rendering: ";
renderWindow->Render();
std::cout<<"[PASSED]"<<std::endl;
//iren->Start();
std::cout << "Testing to pick a world position: ";
mitk::Point2D p;
mitk::Point3D p_mm;
p[0] = 10;
p[1] = 10;
propRenderer->PickWorldPoint(p, p_mm);
std::cout << "returned world position: " << p_mm << "\n";
std::cout << "Creating vtkUnsignedCharArray: ";
vtkUnsignedCharArray *vtkImage = vtkUnsignedCharArray::New();
std::cout<<"[PASSED]"<<std::endl;
cout << "Reading image from renderWindow" << std::endl;
renderWindow->GetRGBACharPixelData(0, 0, size[0]-1, size[1]-1, 0, vtkImage);
cout << "Read " << size[0]*size[1] << " data points\n";
cout << "Computing sum of all RGBA values..\n";
long int sum_now = 0;
for(int i=0;i<size[0]*size[1];i++)
sum_now += vtkImage->GetValue(i);
std::cout << "Sum of all RGBA values: " << sum_now << "\n";
std::cout << "Sum should be: " << sum_orig_Pic3D_pic_gz << "\n";
//std::string Pic3d_pic_gz_str("Pic3D.pic.gz");
//std::cout << "pic3d " << Pic3d_pic_gz_str << "\n";
//std::cout << "argv " << argv_str << "\n";
//std::cout << "find " << (int) argv_str.find("Pic3D.pic.gz") << "\n";
//std::cout << "size " << argv_str.size() << "\n";
//if(argv_str.size() - ((int) argv_str.find("Pic3D.pic.gz")) == 12)
//{
// std::cout << "Input image is Pic3D.pic.gz\n";
// std::cout << "Sum should be: " << sum_orig_Pic3D_pic_gz << "\n";
// if(sum_orig_Pic3D_pic_gz!=sum_now)
// {
// std::cout<<"[FAILED]"<<std::endl;
// return EXIT_FAILURE;
// }
// std::cout<<"[PASSED]"<<std::endl;
//}
//else
//{
// std::cout<<"Unknown image, comparison test skipped"<<std::endl;
//}
propRenderer->GetVtkRenderer()->RemoveViewProp(renderProp);
renderProp->Delete();
propRenderer = NULL;
sphereRenderer->Delete();
renderWindow->Delete();
vtkImage->Delete();
ds = NULL;
std::cout<<"[TEST DONE]"<<std::endl;
return EXIT_SUCCESS;
}
diff --git a/Core/Code/Testing/mitkVtkWidgetRenderingTest.cpp b/Core/Code/Testing/mitkVtkWidgetRenderingTest.cpp
index 9e11a6dcf4..afdfb59d9c 100644
--- a/Core/Code/Testing/mitkVtkWidgetRenderingTest.cpp
+++ b/Core/Code/Testing/mitkVtkWidgetRenderingTest.cpp
@@ -1,92 +1,91 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2008-02-25 17:27:17 +0100 (Mo, 25 Feb 2008) $
-Version: $Revision: 7837 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include "mitkVtkWidgetRendering.h"
#include <vtkRenderWindow.h>
#include <vtkScalarBarWidget.h>
#include "mitkTestingMacros.h"
#include <iostream>
/**
* Test for class mitk::VtkWidgetRendering (for rendering vtkWidgets on the
* screen)
*
* argc and argv are the command line parameters which were passed to
* the ADD_TEST command in the CMakeLists.txt file. For the automatic
* tests, argv is either empty for the simple tests or contains the filename
* of a test image for the image tests (see CMakeLists.txt).
*/
int mitkVtkWidgetRenderingTest(int /* argc */, char* /*argv*/[])
{
// always start with this!
MITK_TEST_BEGIN("mitkVTKWidgetRenderingTest")
// Test: instantiation
mitk::VtkWidgetRendering::Pointer widgetRendering = mitk::VtkWidgetRendering::New();
MITK_TEST_CONDITION_REQUIRED(widgetRendering.IsNotNull(),"Testing instantiation")
// Test: Create and set vtkRenderWindow
vtkRenderWindow *renderWindow = vtkRenderWindow::New();
//mitk::VtkPropRenderer::Pointer propRenderer = mitk::VtkPropRenderer::New( "the renderer", renderWindow );
//propRenderer->SetMapperID(2);
widgetRendering->SetRenderWindow( renderWindow );
MITK_TEST_CONDITION_REQUIRED(widgetRendering->GetRenderWindow() == renderWindow,
"Setting vtkRenderWindow...")
// Test: Try to enable before widget has been set (should stay disabled)
widgetRendering->Enable();
MITK_TEST_CONDITION(!widgetRendering->IsEnabled(),
"Trying to enable widget rendering before setting widget")
widgetRendering->Disable();
// Test: Retrieve widget before it has been set (should return NULL)
MITK_TEST_CONDITION(widgetRendering->GetVtkWidget() == NULL,
"Trying to retrieve widget before it has been set")
// Test: Create vtkWidget instance (vtkScalarWidget) and add it
vtkScalarBarWidget *scalarBarWidget = vtkScalarBarWidget::New();
widgetRendering->SetVtkWidget( scalarBarWidget );
MITK_TEST_CONDITION(widgetRendering->GetVtkWidget() == scalarBarWidget,
"Retrieving widget after it has been set")
// Test: Try to enable widget rendering (should work now)
widgetRendering->Enable();
MITK_TEST_CONDITION(widgetRendering->IsEnabled(),
"Enabling widget rendering")
// Test: Try to disable widget rendering (should be disabled)
widgetRendering->Disable();
MITK_TEST_CONDITION(!widgetRendering->IsEnabled(),
"Disabling widget rendering")
// Clean up
scalarBarWidget->Delete();
renderWindow->Delete();
// write your own tests here and use the macros from mitkTestingMacros.h !!!
// do not write to std::cout and do not return from this function yourself!
// always end with this!
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/mitkWeakPointerTest.cpp b/Core/Code/Testing/mitkWeakPointerTest.cpp
index 6ea1fa82c1..800aa86273 100644
--- a/Core/Code/Testing/mitkWeakPointerTest.cpp
+++ b/Core/Code/Testing/mitkWeakPointerTest.cpp
@@ -1,52 +1,51 @@
-/*=========================================================================
-
- Program: BlueBerry Platform
- Language: C++
- Date: $Date$
- Version: $Revision$
-
- Copyright (c) German Cancer Research Center, Division of Medical and
- Biological Informatics. All rights reserved.
- See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
-
- =========================================================================*/
+/*===================================================================
+
+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.
+
+===================================================================*/
#include "mitkTestingMacros.h"
#include <mitkWeakPointer.h>
#include <itkObject.h>
int mitkWeakPointerTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("WeakPointer")
mitk::WeakPointer<itk::Object> weakPointer;
mitk::WeakPointer<itk::Object> weakPointer2;
// Testing constructors and reference counting
itk::Object::Pointer smartPointer = itk::Object::New();
mitk::WeakPointer<itk::Object> weakPointer3(smartPointer);
mitk::WeakPointer<itk::Object> weakPointer4(weakPointer);
{
itk::Object::Pointer tmpSmartPointer(weakPointer);
itk::Object::Pointer tmpSmartPointer2(weakPointer2);
MITK_TEST_CONDITION_REQUIRED(tmpSmartPointer.GetPointer() == tmpSmartPointer2.GetPointer(), "Testing equal pointers");
}
weakPointer = smartPointer;
weakPointer2 = weakPointer;
MITK_TEST_CONDITION_REQUIRED(1 == smartPointer->GetReferenceCount(), "Testing reference count");
smartPointer = 0;
MITK_TEST_CONDITION_REQUIRED(weakPointer.IsNull(), "Testing expired weak pointer (smart pointer assignment)");
MITK_TEST_CONDITION_REQUIRED(weakPointer2.IsNull(), "Testing expired weak pointer (weak pointer assignment)");
MITK_TEST_CONDITION_REQUIRED(weakPointer3.IsNull(), "Testing expired weak pointer (smart pointer constructor)");
MITK_TEST_CONDITION_REQUIRED(weakPointer4.IsNull(), "Testing expired weak pointer (copy constructor)")
MITK_TEST_END()
}
diff --git a/Core/Code/Testing/vtkMitkThickSlicesFilterTest.cpp b/Core/Code/Testing/vtkMitkThickSlicesFilterTest.cpp
index a83d29e14d..1678842870 100644
--- a/Core/Code/Testing/vtkMitkThickSlicesFilterTest.cpp
+++ b/Core/Code/Testing/vtkMitkThickSlicesFilterTest.cpp
@@ -1,101 +1,100 @@
-/*=========================================================================
+/*===================================================================
-Program: Medical Imaging & Interaction Toolkit
-Language: C++
-Date: $Date: 2007-09-26 18:50:26 +0200 (Mi, 26 Sep 2007) $
-Version: $Revision: 9585 $
+The Medical Imaging Interaction Toolkit (MITK)
-Copyright (c) German Cancer Research Center, Division of Medical and
-Biological Informatics. All rights reserved.
-See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+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 the above copyright notices for more information.
+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.
+
+===================================================================*/
#include <vtkImageData.h>
#include "mitkTestingMacros.h"
#include "vtkMitkThickSlicesFilter.h"
/**
* 3x3x3 test image
*/
vtkImageData *GenerateTestImageForTSFilter()
{
// a 2x2x2 image
short myData[] =
{
234,234,
123,565,
-213,800,
1000,-20
};
vtkImageData *i = vtkImageData::New();
i->SetExtent(0,1,0,1,0,1);
i->SetScalarTypeToShort();
i->AllocateScalars();
short *p = (short*)i->GetScalarPointer();
memcpy(p,myData,2*2*2*sizeof(short));
return i;
}
void CheckResultImageForTSFilter(vtkImageData *i)
{
int *e=i->GetExtent();
MITK_TEST_CONDITION_REQUIRED( e[0] == 0 && e[1] == 1 && e[2] == 0 && e[3] == 1 && e[4] == 0 && e[5] == 0 , "output image has correct extent" )
MITK_TEST_CONDITION_REQUIRED( i->GetScalarType() == VTK_SHORT , "output image has correct scalar type" )
short expectedResult[] =
{
234,800,
1000,565
};
short *d = (short*)i->GetScalarPointer();
MITK_TEST_CONDITION_REQUIRED( memcmp(d,expectedResult,sizeof(expectedResult)) == 0 , "output image has correct content" )
}
/**
* todo
*/
int vtkMitkThickSlicesFilterTest(int /*argc*/, char* /*argv*/[])
{
MITK_TEST_BEGIN("ThickSlicesFilter")
vtkImageData *i,*o;
i = GenerateTestImageForTSFilter();
vtkMitkThickSlicesFilter *f = vtkMitkThickSlicesFilter::New();
f->SetThickSliceMode( 0 ); // MIP
f->SetInput( i );
f->Update();
o = f->GetOutput();
CheckResultImageForTSFilter(o);
//Delete vtk variable correctly
i->Delete();
f->Delete();
MITK_TEST_END()
}

File Metadata

Mime Type
application/octet-stream
Expires
Tue, Jun 4, 5:44 AM (1 d, 23 h)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
TVsrMldsR5YE
Default Alt Text
(4 MB)

Event Timeline