00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qmainwindow.h>
00022 #include <qpopupmenu.h>
00023 #include "SlicerWidget.h"
00024 #include "SlicerBase.h"
00025 #include <qlayout.h>
00026 #include <iostream>
00027 #include <image/NrroImage.h>
00028 #include <mathGutz.h>
00029 #include <nrro/nrroUtil.h>
00030
00031 using namespace std;
00032 using namespace gutz;
00033
00034
00035
00036
00037 SlicerWidget::SlicerWidget(QWidget *parent, char *name, WFlags f)
00038 :QWidget(parent,name,f),
00039 _sliceCanvas(0),
00040 _sliceView(0),
00041 _slider(0),
00042 _number(0),
00043 _sliceImage(0),
00044 _axisCombo(0),
00045 _curAxis(X_AXIS),
00046 _curSlice(0),
00047 _vol(0),
00048 _filter(BoxKernel)
00049 {
00050 _sliceCanvas = new QCanvas(200,200);
00051 _sliceCanvas->setDoubleBuffering(true);
00052 _sliceCanvas->setBackgroundColor(QColor(0,0,0));
00053
00054 _sliceView = new SliceView(_sliceCanvas,this,"slice canvas");
00055 _sliceView->setVScrollBarMode(QScrollView::AlwaysOff);
00056 _sliceView->setHScrollBarMode(QScrollView::AlwaysOff);
00057
00058 _slider = new QSlider(Qt::Horizontal,this,"slice number slider");
00059
00060 _axisCombo = new QComboBox(FALSE, this, "axis chooser");
00061
00062
00063 _sliceImage = new NrroCanvasImg(_sliceCanvas);
00064 _sliceImage->show();
00065
00066 conf();
00067 }
00068
00069
00070
00071
00072 SlicerWidget::~SlicerWidget()
00073 {
00074 if(_sliceCanvas) delete _sliceCanvas;
00075 if(_sliceView) delete _sliceView;
00076 if(_slider) delete _slider;
00077 if(_axisCombo) delete _axisCombo;
00078 if(_sliceImage) delete _sliceImage;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 void SlicerWidget::resizeEvent(QResizeEvent *re)
00088 {
00089 _sliceCanvas->resize(re->size().width(), re->size().height());
00090
00091 setSlice(_curSlice);
00092 _sliceCanvas->setAllChanged();
00093 _sliceCanvas->update();
00094 update();
00095 }
00096
00097
00098
00099
00100
00101 void SlicerWidget::setVolume(VolumeSP vol)
00102 {
00103 if(vol.isNull())
00104 {
00105 cerr << typeid(*this).name()
00106 << "::setVolume(), attempting to set a null volume" << endl;
00107 return;
00108 }
00109 _vol = vol;
00110 setAxis(_curAxis);
00111 setSlice(_curSlice);
00112 }
00113
00114
00115
00116
00117 void SlicerWidget::setAxis(int axisId)
00118 {
00119
00120 if((X_AXIS != axisId)&&(Y_AXIS !=axisId)&&(Z_AXIS != axisId))
00121 {
00122 cerr << typeid(*this).name()
00123 << "::setAxis(), invalid axis id" << endl;
00124 return;
00125 }
00126 _curAxis = axisId;
00127
00128
00129 if(_vol.isNull()) return;
00130
00131
00132
00133 _axisCombo->setCurrentItem(_curAxis);
00134
00135
00136 if(_vol->fields.getField(0) && _vol->fields.getField(0)->getNrro().isNull())
00137 return;
00138
00139
00140 NrroSP n = _vol->fields.getField(0)->getNrro();
00141 int l = 0;
00142 if(_curAxis == X_AXIS)
00143 {
00144 if(n->dim() == 3)
00145 {
00146 l = n->dim(0)-1;
00147 }
00148 else
00149 {
00150 l = n->dim(1)-1;
00151 }
00152 }
00153 if(_curAxis == Y_AXIS)
00154 {
00155 if(n->dim() == 3)
00156 {
00157 l = n->dim(1)-1;
00158 }
00159 else
00160 {
00161 l = n->dim(2)-1;
00162 }
00163 }
00164 if(_curAxis == Z_AXIS)
00165 {
00166 if(n->dim() == 3)
00167 {
00168 l = n->dim(2)-1;
00169 }
00170 else
00171 {
00172 l = n->dim(3)-1;
00173 }
00174 }
00175
00176
00177 _slider->setMaxValue(l);
00178
00179 setSlice(_curSlice);
00180 }
00181
00182
00183
00184
00185 void SlicerWidget::setSlice(int slicePos)
00186 {
00187 if(_vol.isNull())
00188 {
00189 cerr << typeid(*this).name()
00190 << "::setSlice(), null volume" << endl;
00191 return;
00192 }
00193
00194
00195 if(_vol->fields.size() == 0)
00196 {
00197 return;
00198 }
00199
00200 NrroSP field = _vol->fields.getField(0)->getNrro();
00201 if(field.isNull())
00202 {
00203 cerr << typeid(*this).name()
00204 << "::setSlice(), null nrro field" << endl;
00205 return;
00206 }
00207
00208 _curSlice = clamp(0,slicePos,_slider->maxValue());
00209
00210
00211 int inc = 0;
00212 if(field->dim() == 4) inc = 1;
00213
00214
00215 NrroSP slice = field->slice(_curAxis+inc,_curSlice);
00216 slice->setKind(Nrro::IMAGE);
00217
00218
00219 vec2i vsize(_sliceView->getWidth(),
00220 _sliceView->getHeight());
00221
00222
00223
00224
00225 vec2f vmin(_sliceView->getPos());
00226 vec2f vmax = vmin + _sliceView->getAspect() * _sliceView->getZoom();
00227 _sliceImage->setNrro(reshapeNrroImageA(slice,vsize,vmin,vmax,_filter),field->getMinMax());
00228
00229 _sliceCanvas->setAllChanged();
00230 _sliceCanvas->update();
00231
00232 _slider->setValue(_curSlice);
00233 }
00234
00235
00236
00237
00238 void SlicerWidget::setFieldOn(int fieldNum)
00239 {
00240
00241 }
00242
00243 void SlicerWidget::setFieldOff(int fieldNum)
00244 {
00245
00246 }
00247
00248
00249
00250
00251 void SlicerWidget::setPickPos(int xp, int yp)
00252 {
00253
00254 int vx, vy, vz;
00255
00256 if(_vol.isNull()) return;
00257
00258 NrroSP n = _vol->fields.getField(0)->getNrro();
00259 if(n.isNull()) return;
00260
00261
00262 int inc = 0;
00263 if(n->dim() == 4) inc = 1;
00264
00265
00266 float tx = _sliceView->getPos().x
00267 + xp*(_sliceView->getAspect().x * _sliceView->getZoom())/_sliceView->getWidth();
00268 float ty = _sliceView->getPos().y
00269 + yp*(_sliceView->getAspect().y * _sliceView->getZoom())/_sliceView->getHeight();
00270
00271 cerr << "pos = " << _sliceView->getPos() << endl;
00272 cerr << "aspect = " << _sliceView->getAspect() << endl;;
00273 cerr << "zoom = " << _sliceView->getZoom() << endl;
00274 cerr << "tx, ty " << tx << " " << ty << endl;
00275
00276 if(_curAxis == X_AXIS)
00277 {
00278 vec2f aspect(vec2f_one);
00279 if(n->axisSize(1+inc) > n->axisSize(2+inc))
00280 aspect.y = n->axisSize(1+inc)/float(n->axisSize(2+inc));
00281 else
00282 aspect.x = n->axisSize(2+inc)/float(n->axisSize(1+inc));
00283
00284 vx = _curSlice;
00285 vy = static_cast<int>(tx * aspect.x * n->dim(1 + inc));
00286 vz = static_cast<int>(ty * aspect.y * n->dim(2 + inc));
00287 }
00288 else if(_curAxis == Y_AXIS)
00289 {
00290 vec2f aspect(vec2f_one);
00291 if(n->axisSize(0+inc) > n->axisSize(2+inc))
00292 aspect.y = n->axisSize(0+inc)/float(n->axisSize(2+inc));
00293 else
00294 aspect.x = n->axisSize(2+inc)/float(n->axisSize(0+inc));
00295 vx = static_cast<int>(tx * aspect.x * n->dim(0 + inc));
00296 vy = _curSlice;
00297 vz = static_cast<int>(ty * aspect.y * n->dim(2 + inc));
00298 }
00299 else if(_curAxis == Z_AXIS)
00300 {
00301 vec2f aspect(vec2f_one);
00302 if(n->axisSize(0+inc) > n->axisSize(1+inc))
00303 aspect.y = n->axisSize(0+inc)/float(n->axisSize(1+inc));
00304 else
00305 aspect.x = n->axisSize(1+inc)/float(n->axisSize(0+inc));
00306 vx = static_cast<int>(tx * aspect.x * n->dim(0 + inc));
00307 vy = static_cast<int>(ty * aspect.y * n->dim(1 + inc));
00308 vz = _curSlice;
00309 }
00310
00311 volPickPosChanged(vx,vy,vz);
00312 }
00313
00314
00315
00316
00317 void SlicerWidget::setVolPos(int xp, int yp, int zp)
00318 {
00319 if(_curAxis == X_AXIS)
00320 {
00321 setSlice(xp);
00322 }
00323 else if(_curAxis == Y_AXIS)
00324 {
00325 setSlice(yp);
00326 }
00327 else if(_curAxis == Z_AXIS)
00328 {
00329 setSlice(zp);
00330 }
00331 }
00332
00333
00334
00335
00336 void SlicerWidget::setFilter(int f)
00337 {
00338 switch(f){
00339 case SlicerBase::NEAREST:
00340 _filter = BoxKernel;
00341 break;
00342 case SlicerBase::BILIN:
00343 _filter = TentKernel;
00344 break;
00345 case SlicerBase::BICUBE:
00346 _filter = CatmulRomKernel;
00347 break;
00348 case SlicerBase::BSPLINE:
00349 _filter = BSplineKernel;
00350 break;
00351 default:
00352 cerr << "SlicerWidget::setFilter(), unknown filter" << endl;
00353 };
00354
00355 setSlice(_curSlice);
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 void SlicerWidget::conf()
00368 {
00369
00370 QHBoxLayout *topLayout = new QHBoxLayout( this, 5 );
00371
00372
00373
00374
00375 QGridLayout *grid = new QGridLayout(topLayout, 2,1);
00376
00377
00378 grid->addWidget(_sliceView,0,0);
00379
00380 connect(_sliceView,SIGNAL(pickPosChanged(int,int)), SLOT(setPickPos(int,int)));
00381
00382
00383
00384
00385 QGridLayout *sliderGrid = new QGridLayout(grid,2,2);
00386
00387
00388 sliderGrid->addWidget(_slider,0,0);
00389 _slider->setValue(_curSlice);
00390 connect(_slider,SIGNAL(valueChanged(int)),SLOT(setSlice(int)));
00391
00392
00393 QLCDNumber *num = new QLCDNumber(3,this,"slice number");
00394 num->setSegmentStyle(QLCDNumber::Flat);
00395 num->connect(_slider, SIGNAL(valueChanged(int)),SLOT(display(int)));
00396 sliderGrid->addWidget(num,0,1);
00397
00398
00399 sliderGrid->addWidget(_axisCombo,1,0);
00400 _axisCombo->insertItem("X axis", X_AXIS);
00401 _axisCombo->insertItem("Y axis", Y_AXIS);
00402 _axisCombo->insertItem("Z axis", Z_AXIS);
00403 _axisCombo->setCurrentItem(_curAxis);
00404 connect(_axisCombo,SIGNAL(activated(int)),SLOT(setAxis(int)));
00405
00406 }
00407
00408