densitybase.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                         densitybase.cpp  -  description
00003                              -------------------
00004     begin                : Thu Mar 17 2005
00005     copyright            : (C) 2005-2006 by Ben Swerts
00006     email                : bswerts@users.sourceforge.net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00018 
00026 
00027 
00028 
00030 
00031 // C++ header files
00032 #include <cassert>
00033 #include <cmath>
00034 
00035 // STL header files
00036 #include <algorithm>
00037 #include <functional>
00038 
00039 // Qt header files
00040 #include <qapplication.h>
00041 #include <qcheckbox.h>
00042 #include <qcombobox.h>
00043 #include <qdatetime.h>
00044 #include <qfile.h>
00045 #include <qfiledialog.h>
00046 #include <qgroupbox.h>
00047 #include <qinputdialog.h>
00048 #include <qlabel.h>
00049 #include <qlineedit.h>
00050 #include <qlistview.h>
00051 #include <qmessagebox.h>
00052 #include <qprogressbar.h>
00053 #include <qpushbutton.h>
00054 #include <qslider.h>
00055 #include <qstring.h>
00056 #include <qtextstream.h>
00057 #include <qvalidator.h>
00058 
00059 // Xbrabo header files
00060 #include "colorbutton.h"
00061 #include "densitybase.h"
00062 #include "densityloadthread.h"
00063 #include "isosurface.h"
00064 
00068 
00070 DensityBase::DensityBase(IsoSurface* surface, QWidget* parent, const char* name, bool modal, WFlags fl) : DensityWidget(parent, name, modal, fl),
00071   isoSurface(surface),
00072   loadingThread(0),
00073   columnColourWidth(-1)
00075 {
00076   assert(isoSurface != NULL);
00077   QDoubleValidator* v = new QDoubleValidator(-100.0,100.0,3,this);
00078   LineEditLevel->setValidator(v);
00079   ListViewParameters->setSorting(-1);
00080   ListViewParameters->setColumnWidthMode(COLUMN_ID,QListView::Manual);
00081   ListViewParameters->setColumnWidth(COLUMN_ID,0);
00082   ListViewParameters->setColumnWidthMode(COLUMN_RGB,QListView::Manual);
00083   ListViewParameters->setColumnWidth(COLUMN_RGB,0);
00084   ProgressBarA->hide();
00085   ProgressBarB->hide();
00086   enableWidgets();
00087   makeConnections();
00088 }
00089 
00091 DensityBase::~DensityBase()
00093 {
00094   if(loadingThread != 0)
00095   {
00096     if(loadingThread->running())
00097     {
00098       loadingThread->stop();
00099       loadingThread->wait();
00100     }
00101     delete loadingThread;
00102   }
00103 }
00104 
00106 bool DensityBase::surfaceVisible(const unsigned int surface)
00108 {
00109   if(surface >= surfaceProperties.size())
00110     return false;
00111 
00112   return surfaceProperties[surface].visible;
00113 }
00114 
00116 QColor DensityBase::surfaceColor(const unsigned int surface)
00118 {
00119   if(surface >= surfaceProperties.size())
00120     return QColor(0, 0, 0);
00121 
00122   return QColor(surfaceProperties[surface].colour);
00123 }
00124 
00126 unsigned int DensityBase::surfaceOpacity(const unsigned int surface)
00128 {
00129   if(surface >= surfaceProperties.size())
00130     return false;
00131 
00132   return surfaceProperties[surface].opacity;
00133 }
00134 
00136 unsigned int DensityBase::surfaceType(const unsigned int surface)
00138 {
00139   if(surface >= surfaceProperties.size())
00140     return false;
00141 
00142   return surfaceProperties[surface].type;
00143 }
00144 
00148 
00150 void DensityBase::loadDensityA()
00152 {
00153   loadDensity(true);
00154 }
00155 
00157 void DensityBase::loadDensityB()
00159 {
00160   loadDensity(false);
00161 }
00162 
00164 void DensityBase::addSurface()
00166 {
00168   QCheckListItem* item = new QCheckListItem(ListViewParameters, ListViewParameters->lastItem(), QString::null, QCheckListItem::CheckBox);
00169   item->setOn(true);
00170   ListViewParameters->blockSignals(true);
00171   ListViewParameters->setSelected(item, true);
00172   ListViewParameters->blockSignals(false);
00173   updateListView();
00174   item->setText(COLUMN_ID, QString::number(++idCounter));
00175   
00177   SurfaceProperties newSurface;
00178   newSurface.visible = true;
00179   newSurface.level = LineEditLevel->text().toDouble();
00180   newSurface.colour = ColorButtonLevel->color().rgb();
00181   newSurface.opacity = SliderOpacity->value();
00182   newSurface.type = ComboBoxType->currentItem();
00183   newSurface.deleted = false;
00184   newSurface.isNew = true;
00185   newSurface.ID = idCounter;
00186   surfaceProperties.push_back(newSurface);
00187 
00188   if(CheckBoxUpdate->isOn())
00189     updateAll();
00190   enableWidgets();
00191 }
00192 
00194 void DensityBase::addSurfacePair()
00197 {
00199   
00201   ListViewParameters->blockSignals(true);
00202   QCheckListItem* item = new QCheckListItem(ListViewParameters, ListViewParameters->lastItem(), QString::null, QCheckListItem::CheckBox);
00203   item->setOn(true);
00204   item->setText(COLUMN_ID, QString::number(++idCounter));
00205   QColor blue(0, 0, 255);
00206   item->setText(COLUMN_RGB, QString::number(blue.rgb()));
00207   if(0.05 > LabelMax->text().toDouble())
00208     item->setText(COLUMN_LEVEL, LabelMax->text());
00209   else
00210     item->setText(COLUMN_LEVEL, "0.05");
00211   const int columnColourWidth = ListViewParameters->columnWidth(COLUMN_COLOUR);
00212   QPixmap pm(ListViewParameters->width(), item->height() - 2);
00213   pm.fill(blue);
00214   item->setPixmap(COLUMN_COLOUR,pm);
00215   item->setText(COLUMN_OPACITY, QString::number(SliderOpacity->value()));
00216   item->setText(COLUMN_TYPE, ComboBoxType->currentText());
00218   SurfaceProperties newSurface;
00219   newSurface.visible = true;
00220   newSurface.level = LineEditLevel->text().toDouble();
00221   newSurface.colour = blue.rgb();
00222   newSurface.opacity = SliderOpacity->value();
00223   newSurface.type = ComboBoxType->currentItem();
00224   newSurface.deleted = false;
00225   newSurface.isNew = true;
00226   newSurface.ID = idCounter;
00227   surfaceProperties.push_back(newSurface);
00228 
00230   QCheckListItem* item2 = new QCheckListItem(ListViewParameters, item, QString::null, QCheckListItem::CheckBox);
00231   item2->setOn(true);
00232   item2->setText(COLUMN_ID, QString::number(++idCounter));
00233   QColor red(255, 0, 0);
00234   item2->setText(COLUMN_RGB, QString::number(red.rgb()));
00235   if(-item->text(COLUMN_LEVEL).toDouble() < LabelMin->text().toDouble())
00236     item2->setText(COLUMN_LEVEL, LabelMin->text());
00237   else
00238     item2->setText(COLUMN_LEVEL, "-" + item->text(COLUMN_LEVEL));
00239   pm.fill(red);
00240   item2->setPixmap(COLUMN_COLOUR,pm);
00241   ListViewParameters->setColumnWidth(COLUMN_COLOUR, columnColourWidth);
00242   item2->setText(COLUMN_OPACITY, QString::number(SliderOpacity->value()));
00243   item2->setText(COLUMN_TYPE, ComboBoxType->currentText());
00244   ListViewParameters->blockSignals(false);
00245   
00247   newSurface.level = LineEditLevel->text().toDouble();
00248   newSurface.colour = red.rgb();
00249   newSurface.ID = idCounter;
00250   surfaceProperties.push_back(newSurface);
00251 
00252   ListViewParameters->setSelected(item2, true);
00253   updateSettings();
00254 
00255   qDebug("RGB values for blue: " + item->text(COLUMN_RGB)); 
00256   qDebug("RGB values for red:  " + item2->text(COLUMN_RGB)); 
00257 
00258   if(CheckBoxUpdate->isOn())
00259     updateAll();
00260   enableWidgets();
00261 }
00262 
00264 void DensityBase::deleteSurface()
00266 {
00268   QListViewItem* item = ListViewParameters->selectedItem();
00269   if(item == NULL)
00270     return;
00271 
00273   unsigned int itemID = item->text(COLUMN_ID).toUInt();
00274   std::vector<SurfaceProperties>::iterator it = surfaceProperties.begin();
00275   while(it != surfaceProperties.end())
00276   {
00277     if((*it).ID == itemID)
00278       (*it).deleted = true;
00279     it++;
00280   }
00281 
00283   delete item;
00284   if(ListViewParameters->childCount() != 0)
00285   {
00286     ListViewParameters->setSelected(ListViewParameters->firstChild(), true);
00287     updateSettings();
00288   }
00289 
00290   if(CheckBoxUpdate->isOn())
00291     updateAll();
00292   enableWidgets();
00293 }
00294 
00296 void DensityBase::updateAll()
00298 {  
00299   bool somethingChanged = false;
00300 
00302   std::vector<SurfaceProperties>::reverse_iterator rit = surfaceProperties.rbegin();
00303   unsigned int surfaceIndex = surfaceProperties.size() - 1; 
00304   while(rit != surfaceProperties.rend())
00305   {
00306     if((*rit).deleted)
00307     {
00308       if(!(*rit).isNew)
00309       {
00310         isoSurface->removeSurface(surfaceIndex);
00311         emit deletedSurface(surfaceIndex);
00312         somethingChanged = true;
00313       }
00315       std::vector<SurfaceProperties>::iterator itd = surfaceProperties.begin();
00316       itd += surfaceIndex; // now itd should be equal to rit
00317       assert((*itd).ID == (*rit).ID);
00318       rit++;
00319       surfaceProperties.erase(itd);
00320     }
00321     else
00322       rit++;
00323     surfaceIndex--;
00324   }
00325 
00327   QListViewItemIterator it(ListViewParameters);
00328   for(unsigned int i = 0; i < surfaceProperties.size(); i++, it++)
00329   {
00330     if(surfaceProperties[i].isNew == true)
00331     {
00332       // this is a new surface so everything must be updated
00333       surfaceProperties[i].visible = dynamic_cast<QCheckListItem*>(it.current())->isOn();
00334       surfaceProperties[i].level = it.current()->text(COLUMN_LEVEL).toDouble();
00335       surfaceProperties[i].colour = it.current()->text(COLUMN_RGB).toUInt();
00336       surfaceProperties[i].opacity = it.current()->text(COLUMN_OPACITY).toUInt();
00337       surfaceProperties[i].type = typeToNum(it.current()->text(COLUMN_TYPE));
00338       surfaceProperties[i].isNew = false;
00339 
00340       isoSurface->addSurface(surfaceProperties[i].level);
00341       emit newSurface(isoSurface->numSurfaces() - 1);
00342       somethingChanged = true;
00343     }
00344     else
00345     {
00347       bool visibilityChanged = false;
00348       bool levelChanged = false;
00349       bool colorChanged = false;
00350       bool opacityChanged = false;
00351       bool typeChanged = false;
00352       if(dynamic_cast<QCheckListItem*>(it.current())->isOn() != surfaceProperties[i].visible)
00353         visibilityChanged = true;
00354       if(fabs(it.current()->text(COLUMN_LEVEL).toDouble() - surfaceProperties[i].level) >= deltaLevel*deltaLevel)
00355         levelChanged = true;
00356       if(it.current()->text(COLUMN_RGB).toUInt() != surfaceProperties[i].colour)
00357         colorChanged = true;
00358       if(it.current()->text(COLUMN_OPACITY).toUInt() != surfaceProperties[i].opacity)
00359         opacityChanged = true;
00360       if(typeToNum(it.current()->text(COLUMN_TYPE)) != surfaceProperties[i].type)
00361         typeChanged = true;
00363       surfaceProperties[i].visible = dynamic_cast<QCheckListItem*>(it.current())->isOn();
00364       surfaceProperties[i].level = it.current()->text(COLUMN_LEVEL).toDouble();
00365       surfaceProperties[i].colour = it.current()->text(COLUMN_RGB).toUInt();
00366       surfaceProperties[i].opacity = it.current()->text(COLUMN_OPACITY).toUInt();
00367       surfaceProperties[i].type = typeToNum(it.current()->text(COLUMN_TYPE));
00368 
00369       if(levelChanged)
00370         isoSurface->changeSurface(i, surfaceProperties[i].level); 
00371       if(levelChanged || colorChanged || opacityChanged || typeChanged)
00372       {       
00373         emit updatedSurface(i);
00374         somethingChanged = true;
00375       }
00376       else if(visibilityChanged)
00377         somethingChanged = true;
00378     }
00379   }
00380   if(somethingChanged)
00381     emit redrawScene();
00382 }
00383 
00387 
00389 void DensityBase::customEvent(QCustomEvent* e)
00391 {
00393   if(e->type() == 1001)
00394     updateProgress(*(static_cast<unsigned int*>(e->data())));
00396   else if(e->type() == 1002)
00397     updateDensity();
00398 }
00399 
00401 void DensityBase::showEvent(QShowEvent* e)
00404 {
00405   if(columnColourWidth != -1)
00406     ListViewParameters->setColumnWidth(COLUMN_COLOUR, columnColourWidth);
00407   DensityWidget::showEvent(e);
00408 }
00409 
00411 void DensityBase::hideEvent(QHideEvent* e)
00414 {
00415   columnColourWidth = ListViewParameters->columnWidth(COLUMN_COLOUR);
00416   DensityWidget::hideEvent(e);
00417 }
00418 
00422 
00424 void DensityBase::updateSliderLevel()
00426 {
00427   bool convOK;
00428   double level = LineEditLevel->text().toDouble(&convOK);
00429   if(!convOK)
00430     return;
00431   SliderLevel->blockSignals(true);
00432   SliderLevel->setValue(static_cast<int>(level/deltaLevel));
00433   SliderLevel->blockSignals(false);
00434 }
00435 
00437 void DensityBase::updateLineEditLevel()
00439 {
00440   LineEditLevel->setText(QString::number(SliderLevel->value()*deltaLevel,'f',3));
00441 }
00442 
00444 void DensityBase::updateListView()
00446 {
00447   //qDebug("calling updateListView");
00448   QListViewItem* item = ListViewParameters->selectedItem();
00449   if(item == 0)
00450     return;
00451   ListViewParameters->blockSignals(true);
00452   item->setText(COLUMN_LEVEL, LineEditLevel->text());
00454   if(item->pixmap(COLUMN_COLOUR) == 0 || item->text(COLUMN_RGB).toUInt() != ColorButtonLevel->color().rgb())
00455   {
00456     columnColourWidth = ListViewParameters->columnWidth(COLUMN_COLOUR);
00457     QPixmap pm(ListViewParameters->width(), item->height() - 2);
00458     pm.fill(ColorButtonLevel->color());
00459     item->setPixmap(COLUMN_COLOUR,pm);
00460     ListViewParameters->setColumnWidth(COLUMN_COLOUR, columnColourWidth);
00461   }
00462   item->setText(COLUMN_RGB, QString::number(ColorButtonLevel->color().rgb()));
00463   item->setText(COLUMN_OPACITY, QString::number(SliderOpacity->value()));
00464   item->setText(COLUMN_TYPE, ComboBoxType->currentText());
00465   ListViewParameters->blockSignals(false);
00466 
00467   if(CheckBoxUpdate->isOn())
00468     updateAll();
00469 }
00470 
00472 void DensityBase::updateSettings()
00475 {
00476   QListViewItem* item = ListViewParameters->selectedItem();
00477   if(item == 0)
00478     return;
00479   //qDebug("calling updateSettings");
00480   LineEditLevel->blockSignals(true);
00481   LineEditLevel->setText(item->text(COLUMN_LEVEL));
00482   LineEditLevel->blockSignals(false);
00483   SliderLevel->blockSignals(true);
00484   updateSliderLevel();
00485   SliderLevel->blockSignals(false);
00486   ColorButtonLevel->blockSignals(true);
00487   ColorButtonLevel->setColor(QColor(item->text(COLUMN_RGB).toUInt()));
00488   ColorButtonLevel->blockSignals(false);
00489   SliderOpacity->blockSignals(true);
00490   SliderOpacity->setValue(item->text(COLUMN_OPACITY).toUInt());
00491   SliderOpacity->blockSignals(false);
00492   updateOpacity();
00493   ComboBoxType->blockSignals(true);
00494   ComboBoxType->setCurrentText(item->text(COLUMN_TYPE));
00495   ComboBoxType->blockSignals(false);
00496 }
00497 
00499 void DensityBase::updateVisibility(QListViewItem* item, const QPoint&, int column)
00501 {
00502   if(item == 0)
00503     return;
00504   if(column != 0)
00505     return;
00506 
00508   if(CheckBoxUpdate->isOn())
00509     updateAll();
00510 }
00511 
00513 void DensityBase::updateOperation(const unsigned int op)
00519 {
00520   double maxDensity = 0.0, minDensity = 0.0;
00521   
00523   if(op == 0)
00524   {
00525     switch(ComboBoxOperation->currentItem())
00526     {
00527       case 0: // density A
00528               { 
00529                 std::vector<double>::iterator it = std::max_element(densityPointsA.begin(), densityPointsA.end());
00530                 maxDensity = *it; 
00531                 it = std::min_element(densityPointsA.begin(), densityPointsA.end());
00532                 minDensity = *it;
00533               }
00534               isoSurface->setParameters(&densityPointsA, numPointsA, deltaA, originA);
00535               break;
00536       case 1: // density B
00537               { 
00538                 std::vector<double>::iterator it = std::max_element(densityPointsB.begin(), densityPointsB.end());
00539                 maxDensity = *it; 
00540                 it = std::min_element(densityPointsB.begin(), densityPointsB.end());
00541                 minDensity = *it;
00542               }
00543               isoSurface->setParameters(&densityPointsB, numPointsB, deltaB, originB);
00544               break;
00545       case 2: // A + B
00546               {
00547                 std::vector<double> densitySum(densityPointsA.size());
00548                 std::transform(densityPointsA.begin(), densityPointsA.end(), densityPointsB.begin(), densitySum.begin(), std::plus<double>());     
00549                 std::vector<double>::iterator it = std::max_element(densitySum.begin(), densitySum.end());
00550                 maxDensity = *it; 
00551                 it = std::min_element(densitySum.begin(), densitySum.end());
00552                 minDensity = *it;
00553                 isoSurface->setParameters(&densitySum, numPointsA, deltaA, originA);  
00554               }
00555               break;
00556       case 3: // A - B
00557               {
00558                 std::vector<double> densityDiff(densityPointsA.size());
00559                 std::transform(densityPointsA.begin(), densityPointsA.end(), densityPointsB.begin(), densityDiff.begin(), std::minus<double>());     
00560                 std::vector<double>::iterator it = std::max_element(densityDiff.begin(), densityDiff.end());
00561                 maxDensity = *it; 
00562                 it = std::min_element(densityDiff.begin(), densityDiff.end());
00563                 minDensity = *it;
00564                 isoSurface->setParameters(&densityDiff, numPointsA, deltaA, originA);  
00565               }
00566               break;
00567       case 4: // B - A
00568               {
00569                 std::vector<double> densityDiff(densityPointsA.size());
00570                 std::transform(densityPointsB.begin(), densityPointsB.end(), densityPointsA.begin(), densityDiff.begin(), std::minus<double>());     
00571                 std::vector<double>::iterator it = std::max_element(densityDiff.begin(), densityDiff.end());
00572                 maxDensity = *it; 
00573                 it = std::min_element(densityDiff.begin(), densityDiff.end());
00574                 minDensity = *it;
00575                 isoSurface->setParameters(&densityDiff, numPointsA, deltaA, originA);  
00576               }
00577               break;
00578     }
00579   }
00581   else if(op == 1)
00582   {
00583     if(densityPointsB.empty())
00584     {
00587       ComboBoxOperation->setCurrentItem(0);
00588       updateOperation();
00589       return;
00590     }
00591     else if(identicalGrids())
00592     {
00594       if(ComboBoxOperation->count() == 2)
00595       {
00596         ComboBoxOperation->insertItem(tr("Add densities (A + B)"));
00597         ComboBoxOperation->insertItem(tr("Substract densities (A - B)"));
00598         ComboBoxOperation->insertItem(tr("Substract densities (B - A)"));
00599       }
00601       if(ComboBoxOperation->currentItem() != 1)
00602         updateOperation();
00603       return;
00604     }
00605     else
00606     {
00609       if(ComboBoxOperation->currentItem() > 2)
00610         ComboBoxOperation->setCurrentItem(0);
00612       while(ComboBoxOperation->count() > 2)
00613         ComboBoxOperation->removeItem(2);
00615       if(ComboBoxOperation->currentItem() != 1)
00616         updateOperation();
00617       return;
00618     }
00619   }
00621   else if(op == 2)
00622   {
00623     if(densityPointsA.empty())
00624     {
00627       ComboBoxOperation->setCurrentItem(1);
00628       updateOperation();
00629       return;
00630     }
00631     else if(identicalGrids())
00632     {
00634       if(ComboBoxOperation->count() == 2)
00635       {
00636         ComboBoxOperation->insertItem(tr("Add densities (A + B)"));
00637         ComboBoxOperation->insertItem(tr("Substract densities (A - B)"));
00638         ComboBoxOperation->insertItem(tr("Substract densities (B - A)"));
00639         // Qt does not recompute the optimal horizontal size for ComboBoxOperation
00640         // when items are added or removed. That's why the following 2 lines are added as a hack 
00641         // (from http://lists.trolltech.com/qt-interest/2002-05/thread00289-0.html)
00642         // -> only do this for enlarging, never for shrinking again
00643         ComboBoxOperation->setFont(ComboBoxOperation->font()); // invalidates sizeHint
00644         ComboBoxOperation->updateGeometry(); // recalculates sizeHint and re-layouts this widget
00645       }
00647       if(ComboBoxOperation->currentItem() != 0)
00648         updateOperation();
00649       return;
00650     }
00651     else
00652     {
00655       if(ComboBoxOperation->currentItem() > 2)
00656         ComboBoxOperation->setCurrentItem(1);
00658       while(ComboBoxOperation->count() > 2)
00659         ComboBoxOperation->removeItem(2);
00661       if(ComboBoxOperation->currentItem() != 0)
00662         updateOperation();
00663       return;
00664     }
00665   }
00666 
00669   
00671   //idCounter = 0;
00672   //ListViewParameters->clear();
00673   for(unsigned int i = surfaceProperties.size(); i > 0; i--)
00674   {
00675     if(surfaceProperties[i-1].level > maxDensity || surfaceProperties[i-1].level < minDensity)
00676     {
00677       if(!surfaceProperties[i-1].isNew)
00678         emit deletedSurface(i-1);
00679       // delete the corresponding listview item
00680       QListViewItem* item = ListViewParameters->firstChild();
00681       while(item)
00682       {
00683         if(item->text(COLUMN_ID).toUInt() == surfaceProperties[i-1].ID)
00684         {
00685           delete item;
00686           break;
00687         }
00688         item = item->nextSibling();
00689       }
00690       std::vector<SurfaceProperties>::iterator it = surfaceProperties.begin();
00691       it += i - 1;
00692       surfaceProperties.erase(it);
00693     }
00694   }
00696   for(unsigned int i = 0; i < surfaceProperties.size(); i++)
00697     surfaceProperties[i].isNew = true;
00698 
00700   if(CheckBoxUpdate->isOn())
00701     updateAll();
00702 
00704   LabelMax->setText(QString::number(maxDensity,'f'));
00705   LabelMin->setText(QString::number(minDensity,'f'));
00707   SliderLevel->setMaxValue(static_cast<int>(maxDensity/deltaLevel));
00708   SliderLevel->setMinValue(static_cast<int>(minDensity/deltaLevel));
00710   if(ListViewParameters->childCount() == 0)
00711   {
00712     if(maxDensity > 0.0) 
00713     {
00714       const double defaultLevel = maxDensity < 0.05 ? maxDensity : 0.05;
00715       LineEditLevel->setText(QString::number(defaultLevel,'f',3));
00716       SliderLevel->setValue(static_cast<int>(defaultLevel/deltaLevel));
00717       ColorButtonLevel->setColor(QColor(0, 0, 255));
00718     }
00719     else
00720     {
00721       const double defaultLevel = minDensity > -0.05 ? minDensity : -0.05;
00722       LineEditLevel->setText(QString::number(defaultLevel,'f',3));
00723       SliderLevel->setValue(static_cast<int>(defaultLevel/deltaLevel));
00724       ColorButtonLevel->setColor(QColor(255, 0, 0));
00725     }
00726   }
00727 
00728   enableWidgets();
00729 }
00730 
00732 void DensityBase::updateOpacity()
00735 {
00736   if(SliderOpacity->value() == 100)
00737     LabelOpacity->setText(QString::number(SliderOpacity->value()) + " %");
00738   else
00739     LabelOpacity->setText(" " + QString::number(SliderOpacity->value()) + " %");
00740 }
00741 
00745 
00747 void DensityBase::makeConnections()
00749 {
00751   connect(PushButtonLoadA, SIGNAL(clicked()), this, SLOT(loadDensityA()));
00752   connect(PushButtonLoadB, SIGNAL(clicked()), this, SLOT(loadDensityB()));
00753   connect(PushButtonAdd, SIGNAL(clicked()), this, SLOT(addSurface()));
00754   connect(PushButtonAdd2, SIGNAL(clicked()), this, SLOT(addSurfacePair()));
00755   connect(PushButtonDelete, SIGNAL(clicked()), this, SLOT(deleteSurface()));
00756   connect(PushButtonUpdate, SIGNAL(clicked()), this, SLOT(updateAll()));
00757   connect(PushButtonOK, SIGNAL(clicked()), this, SLOT(accept()));
00758   connect(PushButtonCancel, SIGNAL(clicked()), this, SLOT(reject()));
00759 
00761   connect(LineEditLevel, SIGNAL(textChanged(const QString&)), this, SLOT(updateSliderLevel()));
00762   connect(SliderLevel, SIGNAL(valueChanged(int)), this, SLOT(updateLineEditLevel()));
00763   connect(SliderOpacity, SIGNAL(valueChanged(int)), this, SLOT(updateOpacity()));
00764 
00766   connect(LineEditLevel, SIGNAL(textChanged(const QString&)), this, SLOT(updateListView()));
00767   connect(ColorButtonLevel, SIGNAL(newColor(QColor*)), this, SLOT(updateListView()));
00768   connect(SliderOpacity, SIGNAL(valueChanged(int)), this, SLOT(updateListView()));
00769   connect(ComboBoxType, SIGNAL(activated(int)), this, SLOT(updateListView()));
00770   connect(ListViewParameters, SIGNAL(clicked(QListViewItem*)), this, SLOT(updateSettings()));
00771   connect(ListViewParameters, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(updateVisibility(QListViewItem*, const QPoint&, int)));
00772 
00774   connect(ComboBoxOperation, SIGNAL(activated(int)), this, SLOT(updateOperation()));
00775 }
00776 
00778 void DensityBase::loadDensity(const bool densityA)
00783 {
00784   loadingDensityA = densityA;
00785 
00787   QString dialogText = tr("Select a cube file for density ");
00788   if(densityA)
00789     dialogText += "A";
00790   else
00791     dialogText += "B";
00792   QString filename = QFileDialog::getOpenFileName(QString::null, "Potdicht/Gaussian CUBE (*.cube)", this, 0, dialogText);
00793   if(filename.isEmpty())
00794     return;
00795   QFile* file = new QFile(filename);
00796   if(!file->open(IO_ReadOnly))
00797   {
00798     delete file;
00799     QMessageBox::warning(this, tr("Load Density"), tr("Unable to open the cube file"));
00800     return;
00801   }
00802 
00804   const double AUTOANG = 1.0/1.889726342;
00805   QTextStream* stream = new QTextStream(file);
00806   stream->readLine(); // ignore the first line
00807   newDescription = stream->readLine(); // the description of the type of density 
00808   QString line = stream->readLine();
00809   int numAtoms = line.mid(0,5).toInt();
00810   const float originX = line.mid(5,12).toFloat() * AUTOANG;
00811   const float originY = line.mid(17,12).toFloat() * AUTOANG;
00812   const float originZ = line.mid(29,12).toFloat() * AUTOANG;
00813   line = stream->readLine();
00814   const unsigned int numPointsX = line.mid(0,5).toUInt();
00815   const float deltaX = line.mid(5,12).toFloat() * AUTOANG;
00816   line = stream->readLine();
00817   const unsigned int numPointsY = line.mid(0,5).toUInt();
00818   const float deltaY = line.mid(17,12).toFloat() * AUTOANG;
00819   line = stream->readLine();
00820   const unsigned int numPointsZ = line.mid(0,5).toUInt();
00821   const float deltaZ = line.mid(29,12).toFloat() * AUTOANG;
00822   if(loadingDensityA)
00823   {
00824     numPointsA.setValues(numPointsX, numPointsY, numPointsZ);
00825     originA.setValues(originX, originY, originZ);
00826     deltaA.setValues(deltaX, deltaY, deltaZ);
00827   }
00828   else
00829   {
00830     numPointsB.setValues(numPointsX, numPointsY, numPointsZ);
00831     originB.setValues(originX, originY, originZ);
00832     deltaB.setValues(deltaX, deltaY, deltaZ);
00833   }
00835   for(int i = 0; i < abs(numAtoms); i++)
00836     stream->readLine();
00838   QStringList listMO;
00839   if(numAtoms < 0)
00840   {
00841     unsigned int numMO, mo;
00842     *stream >> numMO;
00843     qDebug("number of MO's present: %d", numMO);
00844           for(unsigned int i = 0; i < numMO; i++)
00845     {
00846             *stream >> mo;
00847       listMO << QString::number(mo);
00848     }
00849   }
00851   unsigned int numSkipValues = 0;
00852   if(listMO.size() > 1) 
00853   {
00854     QString result = QInputDialog::getItem(tr("Select the desired MO"), tr("The file contains multiple entries for\n")+newDescription+"\nSelect the desired molecular orbital", listMO,0,false,0,this);
00855     newDescription += QString(" for MO " + result);
00856     double skipValue;
00857     for(QStringList::iterator it = listMO.begin(); it != listMO.end(); it++, numSkipValues++)
00858     {
00859       // exit if the right MO is found
00860       if(*it == result)
00861         break;
00862       *stream >> skipValue;
00863     }
00864     numSkipValues = listMO.size() - 1;
00865   }
00866   else if(listMO.size() == 1)
00867     newDescription += QString(" for MO " + listMO[0]);
00868 
00870   const unsigned int totalPoints = numPointsX * numPointsY * numPointsZ;
00871   if(loadingDensityA)
00872   { 
00873     ProgressBarA->setTotalSteps(totalPoints);
00874     ProgressBarA->setProgress(0);
00875     ProgressBarA->show();
00876     LabelDensityA->hide();
00877     loadingThread = new DensityLoadThread(&densityPointsA, stream, this, numSkipValues, totalPoints);
00878   }
00879   else
00880   { 
00881     ProgressBarB->setTotalSteps(totalPoints);
00882     ProgressBarB->setProgress(0);
00883     ProgressBarB->show();
00884     LabelDensityB->hide();
00885     loadingThread = new DensityLoadThread(&densityPointsB, stream, this, numSkipValues, totalPoints);
00886   }
00887   loadingThread->start(QThread::LowPriority);
00888 
00889   enableWidgets(); 
00890 }
00891 
00893 void DensityBase::updateDensity()
00895 {
00897   if(loadingThread == 0)
00898     return;
00899 
00900   if(!loadingThread->finished())
00901     loadingThread->wait(); // blocking wait
00902 
00903   if(!loadingThread->success())
00904   {
00905     delete loadingThread;
00906     loadingThread = 0;
00907     enableWidgets();
00908     return;
00909   }
00910   
00911   delete loadingThread;
00912   loadingThread = 0;
00913 
00916   if( (loadingDensityA && !densityPointsB.empty()) || (!loadingDensityA && !densityPointsA.empty())
00917       && !identicalGrids())
00918     QMessageBox::warning(this, tr("Load Density"), tr("The grid of the new density does not equal\nthat of the other density.\nCombinations will not be allowed."));
00919 
00920   if(loadingDensityA)
00921   {
00922     ProgressBarA->setProgress(ProgressBarA->totalSteps());
00923     updateOperation(1);
00924     LabelDensityA->setText(newDescription);
00925     ProgressBarA->hide();
00926     LabelDensityA->show();
00927   }
00928   else
00929   {
00930     ProgressBarB->setProgress(ProgressBarB->totalSteps());
00931     updateOperation(2);
00932     LabelDensityB->setText(newDescription);
00933     ProgressBarB->hide();
00934     LabelDensityB->show();
00935   }
00936   enableWidgets();
00937 }
00938 
00940 void DensityBase::updateProgress(const unsigned int progress)
00942 {
00943   if(loadingDensityA)
00944     ProgressBarA->setProgress(progress);
00945   else
00946     ProgressBarB->setProgress(progress);
00947 }
00948 
00950 unsigned int DensityBase::typeToNum(const QString& type)
00956 {
00957   if(type == tr("Solid"))
00958     return 0;
00959   else if(type == tr("Wireframe"))
00960     return 1;
00961   else if(type == tr("Dots"))
00962     return 2;
00963   return 3;
00964 }
00965 
00967 void DensityBase::enableWidgets()
00970 {
00972   if(loadingThread != 0)
00973   {
00974     PushButtonLoadA->setEnabled(false);
00975     PushButtonLoadB->setEnabled(false);
00976     ComboBoxOperation->setEnabled(false);
00977   }
00978   else
00979   {
00980     PushButtonLoadA->setEnabled(true);
00981     PushButtonLoadB->setEnabled(true);
00982     if(!densityPointsA.empty() && !densityPointsB.empty())
00983       ComboBoxOperation->setEnabled(true);
00984     else
00985       ComboBoxOperation->setEnabled(false);
00986   }
00987 
00989   if(!isoSurface->densityPresent())
00990   {
00991     ListViewParameters->setEnabled(false);
00992     PushButtonAdd->setEnabled(false);
00993     PushButtonAdd2->setEnabled(false);
00994     PushButtonDelete->setEnabled(false);
00995     PushButtonUpdate->setEnabled(false);
00996     CheckBoxUpdate->setEnabled(false);
00997     GroupBoxSettings->setEnabled(false);
00998   }
00999   else
01000   {
01002     ListViewParameters->setEnabled(true);
01003     PushButtonAdd->setEnabled(true);
01005     if(LabelMax->text().toDouble() <= deltaLevel || LabelMin->text().toDouble() >= -deltaLevel)
01006       PushButtonAdd2->setEnabled(false);
01007     else
01008       PushButtonAdd2->setEnabled(true);
01009     PushButtonUpdate->setEnabled(true);
01010     CheckBoxUpdate->setEnabled(true);
01012     if(ListViewParameters->childCount() != 0)
01013     {
01014       PushButtonDelete->setEnabled(true);
01015       GroupBoxSettings->setEnabled(true);
01016     }
01017     else
01018     {
01019       PushButtonDelete->setEnabled(false);
01020       GroupBoxSettings->setEnabled(false);
01021     }
01022   }
01023 }
01024 
01026 bool DensityBase::identicalGrids()
01029 {
01030   /*
01031   if(densityPointsA.size() != densityPointsB.size())
01032     qDebug("grids are not identical because sizes differ: %d and %d",densityPointsA.size(),densityPointsB.size());
01033 
01034   if(!(originA == originB))
01035     qDebug("grids are not identical because origins differ: A(%f,%f,%f) and B(%f,%f,%f)",originA.x(),originA.y(),originA.z(),originB.x(),originB.y(),originB.z());
01036 
01037   if(!(numPointsA == numPointsB))
01038     qDebug("grids are not identical because numPoints differ: A(%d,%d,%d) and B(%d,%d,%d)",numPointsA.x(),numPointsA.y(),numPointsA.z(),numPointsB.x(),numPointsB.y(),numPointsB.z());
01039 
01040   if(!(deltaA == deltaB))
01041     qDebug("grids are not identical because deltas differ: A(%f,%f,%f) and B(%f,%f,%f)",deltaA.x(),deltaA.y(),deltaA.z(),deltaB.x(),deltaB.y(),deltaB.z());
01042   */
01043   return densityPointsA.size() == densityPointsB.size() && originA == originB && numPointsA == numPointsB && deltaA == deltaB;
01044 }
01045 
01049 
01050 const double DensityBase::deltaLevel = 0.001; 
01051 

Generated on Fri May 19 14:31:54 2006 for Brabosphere by  doxygen 1.4.6-NO