Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef QMITKTRANSFERFUNCTIONCANVAS_H_INCLUDED
00019 #define QMITKTRANSFERFUNCTIONCANVAS_H_INCLUDED
00020
00021 #include <mitkHistogramGenerator.h>
00022 #include "QmitkExtExports.h"
00023 #include <mitkRenderingManager.h>
00024
00025 #include <QWidget>
00026 #include <QLineEdit>
00027
00028 #include <vtkPiecewiseFunction.h>
00029
00030 #include <mitkCommon.h>
00031 #include <mitkImage.h>
00032 #include "mitkImageCast.h"
00033 #include <mitkWeakPointer.h>
00034
00035
00036 namespace mitk {
00037
00038 class QmitkExt_EXPORT SimpleHistogram
00039 {
00040 public:
00041
00042 SimpleHistogram()
00043 {
00044 valid=false;
00045 histogram=0;
00046 }
00047
00048 ~SimpleHistogram()
00049 {
00050 if(histogram)
00051 delete histogram;
00052 }
00053
00054 typedef itk::Image<short, 3> CTImage;
00055 typedef itk::ImageRegionIterator< CTImage > CTIteratorType;
00056 typedef itk::ImageRegionIteratorWithIndex< CTImage > CTIteratorIndexType;
00057
00058 typedef itk::Image<unsigned char, 3> BinImage;
00059 typedef itk::ImageRegionIterator< BinImage > BinIteratorType;
00060 typedef itk::ImageRegionIteratorWithIndex< BinImage > BinIteratorIndexType;
00061
00062 typedef unsigned long CountType;
00063
00064 protected:
00065
00066 CountType *histogram;
00067
00068 bool valid;
00069
00070 int first;
00071 int last;
00072 int min;
00073 int max;
00074 CountType highest;
00075 double invLogHighest;
00076
00077 public:
00078
00079 int GetMin()
00080 {
00081 if(!valid)
00082 return 0;
00083
00084 return min;
00085 }
00086
00087 int GetMax()
00088 {
00089 if(!valid)
00090 return 1;
00091
00092 return max;
00093 }
00094
00095 void ComputeFromImage( Image::Pointer source );
00096 float GetRelativeBin( float start, float end );
00097
00098 };
00099
00100 class QmitkExt_EXPORT SimpleHistogramCache
00101 {
00102 public:
00103
00104 static const unsigned int maxCacheSize = 64;
00105
00106 protected:
00107
00108 class Element
00109 {
00110 public:
00111 mitk::WeakPointer<mitk::Image> image;
00112 itk::TimeStamp m_LastUpdateTime;
00113 SimpleHistogram histogram;
00114 };
00115
00116 typedef std::list<Element*> CacheContainer;
00117
00118 CacheContainer cache;
00119
00120 public:
00121
00122 SimpleHistogramCache()
00123 {
00124
00125 }
00126
00127 ~SimpleHistogramCache()
00128 {
00129 TrimCache(true);
00130 }
00131
00132 SimpleHistogram *operator[](mitk::Image::Pointer sp_Image)
00133 {
00134 mitk::Image *p_Image = sp_Image.GetPointer();
00135
00136 if(!p_Image)
00137 {
00138 MITK_WARN << "SimpleHistogramCache::operator[] with null image called";
00139 return 0;
00140 }
00141
00142 Element *elementToUpdate = 0;
00143
00144 bool first = true;
00145
00146 for(CacheContainer::iterator iter = cache.begin(); iter != cache.end(); iter++)
00147 {
00148 Element *e = *iter;
00149 mitk::Image *p_tmp = e->image.GetPointer();
00150
00151 if(p_tmp == p_Image)
00152 {
00153 if(!first)
00154 {
00155 cache.erase(iter);
00156 cache.push_front(e);
00157 }
00158 if( p_Image->GetMTime() > e->m_LastUpdateTime.GetMTime())
00159 goto recomputeElement;
00160
00161
00162
00163 return &e->histogram;
00164 }
00165
00166 first = false;
00167 }
00168
00169 elementToUpdate = new Element();
00170 elementToUpdate->image = p_Image;
00171 cache.push_front(elementToUpdate);
00172 TrimCache();
00173
00174 recomputeElement:
00175
00176
00177
00178 elementToUpdate->histogram.ComputeFromImage(p_Image);
00179 elementToUpdate->m_LastUpdateTime.Modified();
00180 return &elementToUpdate->histogram;
00181 }
00182
00183 protected:
00184
00185 void TrimCache(bool full=false)
00186 {
00187 unsigned int targetSize = full?0:maxCacheSize;
00188
00189 while(cache.size()>targetSize)
00190 {
00191 delete cache.back();
00192 cache.pop_back();
00193 }
00194
00195 }
00196
00197 };
00198
00199
00200
00201 }
00202
00203
00204 class QmitkExt_EXPORT QmitkTransferFunctionCanvas : public QWidget
00205 {
00206
00207 Q_OBJECT
00208
00209 public:
00210
00211 QmitkTransferFunctionCanvas( QWidget * parent=0, Qt::WindowFlags f = 0 );
00212
00213 mitk::SimpleHistogram* GetHistogram()
00214 {
00215 return m_Histogram;
00216 }
00217
00218 void SetHistogram(mitk::SimpleHistogram *histogram)
00219 {
00220 m_Histogram = histogram;
00221 }
00222
00223 vtkFloatingPointType GetMin()
00224 {
00225 return m_Min;
00226 }
00227
00228 void SetMin(vtkFloatingPointType min)
00229 {
00230 this->m_Min = min;
00231 SetLower(min);
00232 }
00233
00234 vtkFloatingPointType GetMax()
00235 {
00236 return m_Max;
00237 }
00238
00239 void SetMax(vtkFloatingPointType max)
00240 {
00241 this->m_Max = max;
00242 SetUpper(max);
00243 }
00244
00245 vtkFloatingPointType GetLower()
00246 {
00247 return m_Lower;
00248 }
00249
00250 void SetLower(vtkFloatingPointType lower)
00251 {
00252 this->m_Lower = lower;
00253 }
00254
00255 vtkFloatingPointType GetUpper()
00256 {
00257 return m_Upper;
00258 }
00259
00260 void SetUpper(vtkFloatingPointType upper)
00261 {
00262 this->m_Upper = upper;
00263 }
00264
00265
00266
00267 void mousePressEvent( QMouseEvent* mouseEvent );
00268 virtual void paintEvent( QPaintEvent* e );
00269 virtual void DoubleClickOnHandle(int handle) = 0;
00270
00271 void mouseMoveEvent( QMouseEvent* mouseEvent );
00272 void mouseReleaseEvent( QMouseEvent* mouseEvent );
00273 void mouseDoubleClickEvent( QMouseEvent* mouseEvent );
00274 void PaintHistogram(QPainter &p);
00275
00276 virtual int GetNearHandle(int x,int y,unsigned int maxSquaredDistance = 32) = 0;
00277 virtual void AddFunctionPoint(vtkFloatingPointType x,vtkFloatingPointType val) = 0;
00278 virtual void RemoveFunctionPoint(vtkFloatingPointType x) = 0;
00279 virtual void MoveFunctionPoint(int index, std::pair<vtkFloatingPointType,vtkFloatingPointType> pos) = 0;
00280 virtual vtkFloatingPointType GetFunctionX(int index) = 0;
00281 virtual float GetFunctionY(int index) = 0;
00282 virtual int GetFunctionSize() = 0;
00283 int m_GrabbedHandle;
00284
00285 vtkFloatingPointType m_Lower, m_Upper, m_Min, m_Max;
00286
00287 std::pair<int,int> FunctionToCanvas(std::pair<vtkFloatingPointType,vtkFloatingPointType>);
00288 std::pair<vtkFloatingPointType,vtkFloatingPointType> CanvasToFunction(std::pair<int,int>);
00289
00290
00291 mitk::SimpleHistogram *m_Histogram;
00292
00293 void keyPressEvent ( QKeyEvent * e );
00294
00295 void SetImmediateUpdate(bool state);
00296
00297 static std::pair<vtkFloatingPointType,vtkFloatingPointType> ValidateCoord( std::pair<vtkFloatingPointType,vtkFloatingPointType> x )
00298 {
00299 if( x.first < -2048 ) x.first = -2048;
00300 if( x.first > 2048 ) x.first = 2048;
00301 if( x.second < 0 ) x.second = 0;
00302 if( x.second > 1 ) x.second = 1;
00303 return x;
00304 }
00305
00306 void SetX(float x)
00307 {
00308 if (m_GrabbedHandle != -1)
00309 {
00310 this->MoveFunctionPoint(m_GrabbedHandle, ValidateCoord(std::make_pair(x,GetFunctionY(m_GrabbedHandle))));
00311 update();
00312 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00313 }
00314 }
00315
00316 void SetY(float y)
00317 {
00318 if (m_GrabbedHandle != -1)
00319 {
00320 this->MoveFunctionPoint(m_GrabbedHandle, ValidateCoord(std::make_pair(GetFunctionX(m_GrabbedHandle),y)));
00321 update();
00322 mitk::RenderingManager::GetInstance()->RequestUpdateAll();
00323 }
00324 }
00325
00326 void SetQLineEdits(QLineEdit* xEdit, QLineEdit* yEdit)
00327 {
00328 m_XEdit = xEdit;
00329 m_YEdit = yEdit;
00330 m_LineEditAvailable = true;
00331 }
00332
00333 protected:
00334 bool m_ImmediateUpdate;
00335 float m_Range;
00336
00337 bool m_LineEditAvailable;
00338 QLineEdit* m_XEdit;
00339 QLineEdit* m_YEdit;
00340 };
00341 #endif
00342