00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00024 #include <QtGui>
00025 #include <QtGui/QPushButton>
00026 #include <QtGui/QVBoxLayout>
00027 #include <QtGui/QHBoxLayout>
00028 #include <QtGui/QMainWindow>
00029 #include <QtGui/QMenu>
00030 #include <QtGui/QMessageBox>
00031 #include <QtGui/QFileDialog>
00032 #include <QtGui/QGridLayout>
00033 #include <QtGui/QDockWidget>
00034 #include <QtGui/QButtonGroup>
00035 #include <QtGui/QRadioButton>
00036 #include <QtGui/QScrollArea>
00037
00038 #include <complex>
00039
00040 #include "app.h"
00041 #include "colormaker.h"
00042 #include "imagecalculator.h"
00043 #include "darkbody.h"
00044 #include "grayscale.h"
00045 #include "scriptedcolormaker.h"
00046 #include "fulllinear.h"
00047 #include "fractale.h"
00048 #include "buddhabrot.h"
00049 #include "mandelbrot.h"
00050 #include "julia.h"
00051 #include "newton.h"
00052 #include "bateauenfeu.h"
00053 #include "hexamandelbrot.h"
00054 #include "tricorn.h"
00055 #include "sharingan.h"
00056 #include "networkinput.h"
00057 #include "pluginfractale.h"
00058 #include "configurationloader.h"
00059 #include "mandelbrot3d.h"
00060 #include "lightningmaker.h"
00061
00067 App::App(QWidget *parent): QMainWindow(parent){
00068 applyStyle();
00069
00070 collectVectorialPalets();
00071 collectPluginFractales();
00072
00073 qsrand(0);
00074
00075 buildUI();
00076 connectSignals();
00077 calculatedImage = coloredImage = NULL;
00078 isNetworkUsed = false;
00079
00080 setCurrentWindow(buddhabrot::getBestWindow());
00081 }
00082
00087 App::~App(){
00088 if (coloredImage)
00089 delete coloredImage;
00090 if (calculatedImage)
00091 delete calculatedImage;
00092 if (renderingImage)
00093 delete renderingImage;
00094
00095 for (QMap<QString, fractale*>::iterator i = pluginFractales.begin(); i!=pluginFractales.end(); i++)
00096 delete i.value();
00097 }
00098
00102 void App::connectSignals(){
00103
00104 QObject::connect(renderingImage, SIGNAL(zoom(int, int)), this, SLOT(s_zoom(int, int)));
00105 QObject::connect(renderingImage, SIGNAL(unzoom(int, int)), this, SLOT(s_unzoom(int, int)));
00106 QObject::connect(renderingImage, SIGNAL(move(int, int)), this, SLOT(s_displayRealCoordinates(int, int)));
00107
00108
00109 QObject::connect(calculateButton, SIGNAL(clicked()), this, SLOT(s_generate()));
00110
00111
00112 QObject::connect(this, SIGNAL(processFinishing(int)), bar, SLOT(setValue(int)));
00113
00114
00115 QObject::connect(darkBodyBtn, SIGNAL(clicked()), this, SLOT(s_colorate_darkBody()));
00116 QObject::connect(grayBtn, SIGNAL(clicked()), this, SLOT(s_colorate_gray()));
00117 QObject::connect(fullBtn, SIGNAL(clicked()), this, SLOT(s_colorate_full()));
00118
00119
00120 QObject::connect(fractalType, SIGNAL(currentIndexChanged (int)), this, SLOT(s_changeFractale(int)));
00121
00122
00123 QObject::connect(parPointsAleatoires, SIGNAL(toggled (bool)), this, SLOT(s_displayPointsAleatoires(bool)));
00124
00125
00126 QObject::connect(useNetwork, SIGNAL(clicked (bool)), this, SLOT(s_enableNetwork(bool)));
00127 QObject::connect(clearNetwork, SIGNAL(clicked ()), this, SLOT(s_deleteLastNetwork()));
00128 QObject::connect(addNetwork, SIGNAL(clicked()), this, SLOT(s_addNetwork()));
00129 }
00130
00134 void App::buildUI(){
00135 setWindowTitle(tr("DVP Générateur de fractales"));
00136 setWindowIcon(QIcon("data/qt.ico"));
00137
00138
00139 createActions();
00140 createMenu();
00141
00142
00143 statusBar = QMainWindow::statusBar();
00144 statusBarLabel = new QLabel();
00145 statusBar->addPermanentWidget(statusBarLabel, 200);
00146 statusBar->show();
00147
00148
00149 renderingImage = new ZoomableImage();
00150 fractalType = new QComboBox();
00151 fractalType->setToolTip(tr("Choix de la fractale à calculer"));
00152 fractalType->addItem("BuddhaBrot", 0);
00153 fractalType->addItem("MultiBrot", 1);
00154 fractalType->addItem("MandelBrot", 2);
00155 fractalType->addItem("Julia (0.285)", 3);
00156 fractalType->addItem("Julia (-0.038088 + 0.9754633i)", 4);
00157 fractalType->addItem("Newton", 5);
00158 fractalType->addItem("Bateau en feu", 6);
00159 fractalType->addItem("Tricorn", 7);
00160 fractalType->addItem("Sharingan", 8);
00161 fractalType->addItem("MandelBrot3D", 9);
00162
00163
00164 int lastIndex = 10;
00165 for (QMap<QString, fractale*>::iterator i = pluginFractales.begin(); i!=pluginFractales.end(); i++, lastIndex++){
00166 fractalType->addItem(i.key(), lastIndex);
00167 }
00168
00169
00170 calculateButton = new QPushButton(tr("Calculer"));
00171 calculateButton->setToolTip(tr("Lancer le calcul"));
00172
00173 bar = new QProgressBar();
00174 bar->setVisible(false);
00175
00176
00177 QVBoxLayout *mainLayout = new QVBoxLayout();
00178 QHBoxLayout *hlayout = new QHBoxLayout();
00179
00180
00181 iterations = new QSpinBox();
00182 iterations->setMaximum(10000);
00183 iterations->setMinimum(10);
00184 iterations->setSingleStep(10);
00185 iterations->setValue(70);
00186 iterations->setToolTip(tr("Taille maximale des séries fractales"));
00187
00188
00189 sizes = new QComboBox();
00190 sizes->setToolTip(tr("Résolution de l'image résultat"));
00191
00192 QWidget *hlayoutWidget = new QWidget();
00193 hlayoutWidget->setLayout(hlayout);
00194 hlayout->addWidget(new QLabel(tr("Itérations")));
00195 hlayout->addWidget(iterations);
00196 hlayout->addWidget(sizes);
00197 sizes->addItem("128x128", 128);
00198 sizes->addItem("256x256", 256);
00199 sizes->addItem("512x512", 512);
00200 sizes->addItem("1024x1024", 1024);
00201 sizes->addItem("2048x2048", 2048);
00202 hlayout->addWidget(fractalType);
00203 hlayout->addWidget(calculateButton);
00204 hlayout->setSizeConstraint(QLayout::SetFixedSize);
00205 mainLayout->addWidget(hlayoutWidget);
00206
00207
00208 showAnimation = new QCheckBox(tr("Animer la génération"));
00209 showAnimation->setChecked(false);
00210 showAnimation->setVisible(false);
00211
00212 mainLayout->addWidget(showAnimation);
00213 mainLayout->addWidget(bar);
00214
00215 QScrollArea *area = new QScrollArea();
00216 area->setWidget(renderingImage);
00217 renderingImage->hide();
00218 mainLayout->addWidget(area);
00219
00220
00221 colorationWidget = new QWidget();
00222 QGridLayout *colorationLayout = new QGridLayout();
00223 darkBodyBtn = new QPushButton(tr("DarkBody"));
00224 darkBodyBtn->setStyleSheet("QWidget{ background-image: url(data/images/darkBody.png); background-repeat:repeat-y;}");
00225
00226 grayBtn = new QPushButton(tr("Niveau de gris"));
00227 grayBtn->setStyleSheet("QWidget{ background-image: url(data/images/gray.png); background-repeat:repeat-y;}");
00228
00229 fullBtn = new QPushButton(tr("Full linear"));
00230 fullBtn->setStyleSheet("QWidget{ background-image: url(data/images/fullLinear.png); background-repeat:repeat-y;}");
00231
00232 colorationLayout->addWidget(darkBodyBtn);
00233 colorationLayout->addWidget(grayBtn);
00234 colorationLayout->addWidget(fullBtn);
00235 colorationButtons.push_back(darkBodyBtn);
00236 colorationButtons.push_back(grayBtn);
00237 colorationButtons.push_back(fullBtn);
00238
00239
00240 for ( QStringList::Iterator it = palettesListe.begin(); it != palettesListe.end(); ++it ) {
00241 QPushButton *b = new QPushButton(*it);
00242
00243
00244 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("IBM 850"));
00245 QString filename = "data/palettes/%1.png";
00246 filename = filename.arg(*it);
00247 if (QFile::exists(filename)){
00248 QString style = QString("QWidget{ background-image: url(%1); background-repeat:repeat-y;}").arg(filename);
00249 b->setStyleSheet(style);
00250 }
00251
00252 colorationButtons.push_back(b);
00253 QObject::connect(b, SIGNAL(clicked()), this, SLOT(s_run_dynamic_coloration()));
00254 colorationLayout->addWidget(b);
00255 }
00256
00257 enableColorationButtons(false);
00258
00259 colorationWidget->setLayout(colorationLayout);
00260
00261
00262 dockColoration = new QDockWidget(tr("Coloration"));
00263 dockColoration->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
00264 addDockWidget(Qt::RightDockWidgetArea, dockColoration);
00265 dockColoration->setWidget(colorationWidget);
00266
00267
00268 windowDock = new QDockWidget(tr("Fenêtrage"));
00269 windowDock->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
00270
00271 QGridLayout *g = new QGridLayout();
00272 windowX1 = new QLineEdit(); windowX1->setInputMask(QString("#00.000")); windowX1->setMaxLength(8); windowX1->setAlignment(Qt::AlignCenter);
00273 windowY1 = new QLineEdit(); windowY1->setInputMask(QString("#00.000")); windowY1->setMaxLength(8); windowY1->setAlignment(Qt::AlignCenter);
00274 windowX2 = new QLineEdit(); windowX2->setInputMask(QString("#00.000")); windowX2->setMaxLength(8); windowX2->setAlignment(Qt::AlignCenter);
00275 windowY2 = new QLineEdit(); windowY2->setInputMask(QString("#00.000")); windowX2->setMaxLength(8); windowY2->setAlignment(Qt::AlignCenter);
00276 g->addWidget(windowY1, 0, 1);
00277 g->addWidget(windowY2, 2, 1);
00278 g->addWidget(windowX1, 1, 0);
00279 g->addWidget(windowX2, 1, 2);
00280 windowY1->setToolTip(tr("Borne complexe inférieure"));
00281 windowY2->setToolTip(tr("Borne complexe supérieure"));
00282 windowX1->setToolTip(tr("Borne réelle inférieure"));
00283 windowX2->setToolTip(tr("Borne réelle supérieure"));
00284 QWidget *ww = new QWidget();
00285 ww->setLayout(g);
00286 windowDock->setWidget(ww);
00287
00288 addDockWidget(Qt::RightDockWidgetArea, windowDock);
00289
00290
00291 iterationsDock = new QDockWidget(tr("Itérations"));
00292 iterationsDock->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
00293 addDockWidget(Qt::RightDockWidgetArea, iterationsDock);
00294 QWidget *www = new QWidget();
00295 QVBoxLayout *vb = new QVBoxLayout();
00296
00297 QButtonGroup *group = new QButtonGroup();
00298 parPointsAleatoires = new QRadioButton(tr("Par points aléatoires"));
00299 parPixel = new QRadioButton(tr("Par points pixels"));
00300 parPixel->setChecked(true);
00301
00302 group->addButton(parPointsAleatoires);
00303 group->addButton(parPixel);
00304 aleatoiresPoints = new QSpinBox();
00305 aleatoiresPoints->setMinimum(10000);
00306 aleatoiresPoints->setMaximum(1000000000);
00307 aleatoiresPoints->setSingleStep(10000);
00308 aleatoiresPoints->hide();
00309
00310 vb->setSizeConstraint(QLayout::SetMinimumSize);
00311 vb->addWidget(parPixel);
00312 vb->addWidget(parPointsAleatoires);
00313 vb->addWidget(aleatoiresPoints);
00314
00315 www->setLayout(vb);
00316 iterationsDock->setWidget(www);
00317
00318
00319 QDockWidget *networkDock = new QDockWidget(tr("Réseau"));
00320 networkDock->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
00321 addDockWidget(Qt::RightDockWidgetArea, networkDock);
00322 QWidget *wwww = new QWidget();
00323 vbnetworkDock = new QVBoxLayout();
00324
00325 useNetwork = new QCheckBox(QString(tr("Utiliser les agents réseau")));
00326
00327 vbnetworkDock->addWidget(useNetwork);
00328 QHBoxLayout *networkHLayout = new QHBoxLayout();
00329
00330 addNetwork = new QPushButton(QString(tr("Ajouter un agent réseau")));
00331 networkHLayout->addWidget(addNetwork);
00332 clearNetwork = new QPushButton(QString(tr("Supprimer")));
00333 networkHLayout->addWidget(clearNetwork);
00334 QWidget *networkHLayoutWidget = new QWidget();
00335 networkHLayoutWidget->setLayout(networkHLayout);
00336
00337 vbnetworkDock->addWidget(networkHLayoutWidget);
00338 NetworkInput *n = new NetworkInput();
00339 QObject::connect(n, SIGNAL(message(const QString&)), this, SLOT(s_receiveMessageFromNetwork(QString&)));
00340 networkAddresses.append(n);
00341 vbnetworkDock->addWidget(n);
00342
00343 wwww->setLayout(vbnetworkDock);
00344 networkDock->setWidget(wwww);
00345 s_enableNetwork(false);
00346
00347
00348
00349 QWidget *renderingWidget = new QWidget();
00350 renderingWidget->setLayout(mainLayout);
00351 setCentralWidget(renderingWidget);
00352 }
00353
00358 void App::enableColorationButtons(bool b){
00359 QList<QPushButton*>::iterator i = colorationButtons.begin();
00360 while (i != colorationButtons.end()){
00361 (*i)->setDisabled(!b);
00362 i++;
00363 }
00364 }
00365
00370 void App::s_displayRealCoordinates(int x, int y){
00371 float fx = currentWindow.left() + x* (currentWindow.width() / currentSize.width());
00372 float fy = currentWindow.top() + y* (currentWindow.height() / currentSize.height());
00373
00374 statusBarLabel->setText(QString(tr("(%1,%2)")).arg(fx).arg(fy));
00375 }
00376
00381 void App::applyStyle(){
00382 QFile file("data/style.qss");
00383 file.open(QFile::ReadOnly);
00384 QString styleSheet = QLatin1String(file.readAll());
00385 setStyleSheet(styleSheet);
00386 }
00391 void App::collectVectorialPalets(){
00392 QDir dir("data/palettes");
00393 QStringList filters;
00394 filters << "*.js";
00395 dir.setNameFilters(filters);
00396
00397 QFileInfoList list = dir.entryInfoList();
00398 for (int i = 0; i < list.size(); ++i) {
00399 QFileInfo fileInfo = list.at(i);
00400 QString fname = fileInfo.fileName();
00401
00402
00403 fname.truncate(fname.size()-3);
00404
00405 palettesListe.append(fname);
00406 }
00407 }
00408
00413 void App::collectPluginFractales(){
00414 QDir pluginsDir = QDir("data/fractales");
00415 foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
00416 QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
00417 QObject *plugin = loader.instance();
00418 if (plugin) {
00419 pluginfractale * op = qobject_cast<pluginfractale*>(plugin);
00420 if (op) {
00421 pluginFractales[op->getName()] =op;
00422 }
00423 }
00424 }
00425 }
00426
00427
00431 void App::createActions(){
00432 saveAct = new QAction(tr("&Sauver..."), this);
00433 saveAct->setShortcut(tr("Ctrl+S"));
00434 saveAct->setIcon(QIcon::fromTheme(QString(""), QIcon("data/icons/document-save.png")));
00435 connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
00436
00437 loadConfigAct = new QAction(tr("Charger un paramétrage..."), this);
00438 loadConfigAct->setIcon(QIcon::fromTheme(QString(""), QIcon("data/icons/param-load.png")));
00439 connect(loadConfigAct, SIGNAL(triggered()), this, SLOT(s_loadConfig()));
00440
00441 saveConfigAct = new QAction(tr("Sauvegarder le paramétrage..."), this);
00442 saveConfigAct->setIcon(QIcon::fromTheme(QString(""), QIcon("data/icons/param-save.png")));
00443 connect(saveConfigAct, SIGNAL(triggered()), this, SLOT(s_saveConfig()));
00444
00445 quitAct = new QAction(tr("&Quitter..."), this);
00446 quitAct->setIcon(QIcon::fromTheme(QString(""), QIcon("data/icons/quit.png")));
00447 connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));
00448
00449 aboutAct = new QAction(tr("&A propos..."), this);
00450 aboutAct->setIcon(QIcon::fromTheme(QString(""), QIcon("data/icons/about.png")));
00451 connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
00452 }
00456 void App::createMenu(){
00457 QMenu *fileMenu = new QMenu(tr("&Fichier"), this);
00458 fileMenu->addAction(saveAct);
00459 fileMenu->addAction(loadConfigAct);
00460 fileMenu->addAction(saveConfigAct);
00461 fileMenu->addAction(quitAct);
00462
00463 QMenu *aboutMenu = new QMenu("?", this);
00464 aboutMenu->addAction(aboutAct);
00465
00466 menuBar()->addMenu(fileMenu);
00467 menuBar()->addMenu(aboutMenu);
00468 }
00469
00473 void App::save(){
00474 QString fileName = QFileDialog::getSaveFileName(this,
00475 tr("Enregistrer le rendu"), QDir::currentPath(), QString(tr("Images PNG (*.png)")));
00476
00477 if (!fileName.isEmpty())
00478 renderingImage->pixmap()->save(fileName);
00479 }
00480
00484 void App::about(){
00485 QMessageBox::about(this, tr("A propos"), tr("Fruit de plusieurs semaines de travail, ce programme est ma modeste participation au Défi Qt de Developpez.com"));
00486 }
00487
00488
00489
00493 void App::generateStartFractaleWindows(){
00494 int fractaleType = fractalType->itemData(fractalType->currentIndex()).value<int>();
00495
00496 switch(fractaleType){
00497 case 0 :
00498 generateBuddhaBrot();
00499 break;
00500 case 2 :
00501 generateMandelBrot();
00502 break;
00503 case 3 :
00504 generateJulia(std::complex<float>(.285f,0));
00505 break;
00506 case 4 :
00507 generateJulia(std::complex<float>(-0.038088f, 0.9754633f));
00508 break;
00509 case 5 :
00510 generateNewton();
00511 break;
00512 case 6 :
00513 generateBateauEnFeu();
00514 break;
00515 case 1 :
00516 generateHexaMandelBrot();
00517 break;
00518 case 7 :
00519 generateTricorn();
00520 break;
00521 case 8 :
00522 generateSharingan();
00523 break;
00524 case 9:
00525 generateMandel3D();
00526 break;
00527 default:
00528
00529 QString name = fractalType->itemText(fractalType->currentIndex());
00530 generatePlugged(name);
00531 break;
00532 }
00533 }
00534
00538 void App::s_generate(){
00539
00540 float x1 = windowX1->text().toFloat();
00541 float x2 = windowX2->text().toFloat();
00542 float y1 = windowY1->text().toFloat();
00543 float y2 = windowY2->text().toFloat();
00544
00545 currentWindow = QRectF(x1,y1,x2-x1,y2-y1);
00546
00547 generateStartFractaleWindows();
00548 }
00549
00553 void App::s_loadConfig(){
00554 QString fileName = QFileDialog::getOpenFileName(this, tr("Ouvrir un paramétrage"), QDir::currentPath(), QString(tr("Paramétrage (*.dvp)")));
00555 if (!fileName.isEmpty()){
00556 ConfigurationLoader config(fileName);
00557
00558 iterations->setValue(config.getIterations());
00559
00560 useNetwork->setCheckState(config.getUseNetwork()?Qt::Checked:Qt::Unchecked);
00561 parPixel->setChecked(!config.getUseRandom());
00562 parPointsAleatoires->setChecked(config.getUseRandom());
00563 aleatoiresPoints->setValue(config.getRandomCount());
00564
00565 windowX1->setText(QString("%1").arg(config.getWindow().left()));
00566 windowX2->setText(QString("%1").arg(config.getWindow().right()));
00567 windowY1->setText(QString("%1").arg(config.getWindow().top()));
00568 windowY2->setText(QString("%1").arg(config.getWindow().bottom()));
00569
00570 setNetworkList(config.getNetworkAgents());
00571 }
00572 }
00573
00577 void App::s_saveConfig(){
00578 QString filename = QFileDialog::getSaveFileName(this, tr("Sauvegarder un paramétrage"), QDir::currentPath(), QString(tr("Paramétrage (*.dvp)")));
00579
00580 ConfigurationLoader config;
00581
00582 config.setIterations(iterations->text().toLong());
00583 config.setRandomCount(aleatoiresPoints->text().toLong());
00584 config.setUseNetwork(useNetwork->checkState() == Qt::Checked);
00585 config.setUseRandom(parPointsAleatoires->isChecked());
00586
00587 QRectF window(windowX1->text().toFloat(), windowY1->text().toFloat(),
00588 windowX2->text().toFloat() - windowX1->text().toFloat(),
00589 windowY2->text().toFloat() - windowY1->text().toFloat());
00590 config.setWindow(window);
00591 config.setNetworkAgents(collectNetworkAgents());
00592
00593 config.save(filename);
00594
00595 }
00596
00600 void App::setCurrentWindow(QRectF& r){
00601 windowX1->setText(QString("%1" ).arg(r.left()));
00602 windowX2->setText(QString("%1" ).arg(r.right()));
00603 windowY1->setText(QString("%1" ).arg(r.top()));
00604 windowY2->setText(QString("%1" ).arg(r.bottom()));
00605 }
00606
00610 void App::s_changeFractale(int type){
00611 switch(type){
00612 case 0:
00613 setCurrentWindow(buddhabrot::getBestWindow());
00614 break;
00615 case 1:
00616 setCurrentWindow(hexamandelbrot::getBestWindow());
00617 break;
00618 case 2:
00619 setCurrentWindow(mandelbrot::getBestWindow());
00620 break;
00621 case 3:
00622 case 4:
00623 setCurrentWindow(julia::getBestWindow());
00624 break;
00625 case 5:
00626 setCurrentWindow(newton::getBestWindow());
00627 break;
00628 case 6:
00629 setCurrentWindow(bateauEnFeu::getBestWindow());
00630 break;
00631 case 7:
00632 setCurrentWindow(tricorn::getBestWindow());
00633 break;
00634 case 8:
00635 setCurrentWindow(sharingan::getBestWindow());
00636 break;
00637 case 9:
00638 setCurrentWindow(mandelbrot::getBestWindow());
00639 break;
00640 }
00641 }
00642
00646 void App::generateBuddhaBrot(){
00647 buddhabrot b(std::complex<float>(), iterations->value());
00648 generateFractale(b);
00649 }
00650
00654 void App::generateMandel3D(){
00655 if (calculatedImage != NULL)
00656 delete calculatedImage;
00657
00658 threeDrendering.clear();
00659
00660 int resolution = sizes->itemData(sizes->currentIndex()).value<int>();
00661 currentSize = QSize(resolution,resolution);
00662
00663 renderingImage->setMinimumHeight(resolution);
00664 renderingImage->setMaximumHeight(resolution);
00665 renderingImage->setMinimumWidth(resolution);
00666 renderingImage->setMaximumWidth(resolution);
00667
00668 bar->setVisible(true);
00669 calculatedImage = new QImage(currentSize, QImage::Format_RGB888);
00670
00671
00672 calculatedImage->fill(QColor(0,0,0).rgb());
00673
00674
00675 float x1 = windowX1->text().toFloat();
00676 float x2 = windowX2->text().toFloat();
00677 float y1 = windowY1->text().toFloat();
00678 float y2 = windowY2->text().toFloat();
00679
00680 currentWindow = QRectF(x1,y1,x2-x1,y2-y1);
00681
00682 MandelBrot3d mandel(threeDrendering, normalMap, calculatedImage, currentWindow, resolution, iterations->value());
00683 QObject::connect(&mandel, SIGNAL(progress(int)), bar, SLOT(setValue(int)));
00684
00685 maxValue = mandel.process();
00686
00687
00688 if (coloredImage != NULL)
00689 delete coloredImage;
00690 coloredImage = new QImage(currentSize, QImage::Format_RGB888);
00691
00692 runLightning();
00693
00694 renderingImage->setPixmap(QPixmap::fromImage(*coloredImage));
00695 coloredImage->save("colored.bmp");
00696
00697 s_colorate_gray();
00698
00699 renderingImage->show();
00700 calculatedImage->save("./result.bmp");
00701
00702 bar->setVisible(false);
00703
00704 enableColorationButtons(true);
00705 statusBarLabel->setText("");
00706 }
00707
00711 void App::generatePlugged(QString& name){
00712 fractale *f = pluginFractales[name];
00713 f->setMaxIterations(iterations->value());
00714 generateFractale(*f);
00715 }
00716
00720 void App::generateHexaMandelBrot(){
00721 hexamandelbrot b(std::complex<float>(), iterations->value());
00722 generateFractale(b);
00723 }
00724
00728 void App::generateMandelBrot(){
00729 mandelbrot b(std::complex<float>(), iterations->value());
00730 generateFractale(b);
00731 }
00735 void App::s_run_dynamic_coloration(){
00736 QObject *from = sender();
00737 QPushButton * button = qobject_cast<QPushButton*>(from);
00738
00739 QString paletteName = button->text();
00740
00741 scriptedColorMaker d(1000, paletteName);
00742 colorate(d);
00743 }
00744
00748 void App::generateNewton(){
00749 newton b(std::complex<float>(), iterations->value());
00750 generateFractale(b);
00751 }
00752
00756 void App::generateJulia(std::complex<float> c){
00757 julia b(c, iterations->value());
00758 generateFractale(b);
00759 }
00760
00764 void App::generateBateauEnFeu(){
00765 bateauEnFeu b(std::complex<float>(), iterations->value());
00766 generateFractale(b);
00767 }
00771 void App::generateTricorn(){
00772 tricorn b(std::complex<float>(), iterations->value());
00773 generateFractale(b);
00774 }
00775
00779 void App::generateSharingan(){
00780 sharingan b(std::complex<float>(), iterations->value());
00781 generateFractale(b);
00782 }
00783
00784
00791 void App::generateFractale(fractale &f){
00792
00793 QRectF rect = currentWindow;
00794 int resolution = sizes->itemData(sizes->currentIndex()).value<int>();
00795 currentSize = QSize(resolution,resolution);
00796
00797 renderingImage->setMinimumHeight(currentSize.height());
00798 renderingImage->setMaximumHeight(currentSize.height());
00799 renderingImage->setMinimumWidth(currentSize.width());
00800 renderingImage->setMaximumWidth(currentSize.width());
00801
00802 bar->setVisible(true);
00803 if (calculatedImage != NULL)
00804 delete calculatedImage;
00805 calculatedImage = new QImage(currentSize, QImage::Format_RGB888);
00806
00807
00808 calculatedImage->fill(QColor(0,0,0).rgb());
00809
00810
00811 int nbThreads = QThread::idealThreadCount();
00812 if (nbThreads <= 0)
00813 nbThreads = 1;
00814
00815
00816 QStringList networkAgentsList = collectNetworkAgents();
00817
00818 if (networkAgentsList.count() == 0)
00819 statusBarLabel->setText(QString(tr("%1 thread(s) en cours ...")).arg(nbThreads));
00820 else
00821 if (networkAgentsList.count() == 1)
00822 statusBarLabel->setText(QString(tr("%1 thread(s) en cours + 1 agent réseau...")).arg(nbThreads));
00823 else
00824 statusBarLabel->setText(QString(tr("%1 thread(s) en cours + %2 agents réseau...")).arg(nbThreads).arg(networkAgentsList.count()));
00825
00826 enableColorationButtons(false);
00827
00828 bool type = parPointsAleatoires->isChecked();
00829 long nbRandom = aleatoiresPoints->value() / nbThreads;
00830
00831 ImageCalculator ic(nbThreads, calculatedImage, rect, currentSize, f, type, nbRandom, showAnimation->isChecked(), networkAgentsList);
00832 QObject::connect(&ic, SIGNAL(progress(int)), bar, SLOT(setValue(int)));
00833 QObject::connect(&ic, SIGNAL(render()), this, SLOT(s_render()));
00834 ic.run();
00835 ic.wait();
00836 maxValue = ic.maxValue;
00837
00838
00839 renderingImage->setPixmap(QPixmap::fromImage(*calculatedImage).scaled(renderingImage->size(),Qt::IgnoreAspectRatio, Qt::FastTransformation));
00840 calculatedImage->save("./result.bmp");
00841
00842 bar->setVisible(false);
00843 showAnimation->setVisible(true);
00844
00852 s_colorate_gray();
00853 colorationWidget->setVisible(true);
00854 renderingImage->show();
00855 enableColorationButtons(true);
00856 statusBarLabel->setText("");
00857 }
00858
00862 void App::s_zoom(int x, int y){
00863
00864 QPointF center ( currentWindow.left() + float(x) * currentWindow.width() / currentSize.width(),
00865 currentWindow.top() + float(y) * currentWindow.height() / currentSize.height()
00866 );
00867
00868 currentWindow = QRectF(center.x() - currentWindow.width()/4,
00869 center.y() - currentWindow.height()/4,
00870 currentWindow.width()/2,
00871 currentWindow.height()/2
00872 );
00873 setCurrentWindow(currentWindow);
00874
00875 s_generate();
00876
00877 }
00878
00882 void App::s_unzoom(int x, int y){
00883
00884 QPointF center ( currentWindow.left() + float(x) * currentWindow.width() / currentSize.width(),
00885 currentWindow.top() + float(y) * currentWindow.height() / currentSize.height()
00886 );
00887
00888 currentWindow = QRectF(center.x() - currentWindow.width(),
00889 center.y() - currentWindow.height(),
00890 currentWindow.width()*2,
00891 currentWindow.height()*2
00892 );
00893 setCurrentWindow(currentWindow);
00894
00895 s_generate();
00896
00897 }
00898
00902 void App::s_render(){
00903 renderingImage->setPixmap(QPixmap::fromImage(*calculatedImage).scaled(renderingImage->size(),Qt::IgnoreAspectRatio, Qt::FastTransformation));
00904
00905 if (showAnimation->checkState() == Qt::Checked)
00906 s_colorate_gray();
00907 }
00908
00912 void App::s_colorate_darkBody(){
00913 darkBody d(1000);
00914 colorate(d);
00915 }
00916
00920 void App::s_colorate_gray(){
00921 grayScale d(1000);
00922 colorate(d);
00923 }
00924
00928 void App::s_colorate_full(){
00929 fullLinear d(100);
00930 colorate(d);
00931 }
00932
00936 void App::s_displayPointsAleatoires(bool b){
00937 if (b)
00938 aleatoiresPoints->show();
00939 else
00940 aleatoiresPoints->hide();
00941 }
00942
00946 void App::s_enableNetwork(bool b){
00947 addNetwork->setDisabled(!b);
00948 clearNetwork->setDisabled(!b);
00949 isNetworkUsed = b;
00950 }
00951
00952
00956 void App::s_deleteLastNetwork(){
00957 if (networkAddresses.length() > 0){
00958 NetworkInput*e = networkAddresses.last();
00959 networkAddresses.pop_back();
00960 delete e;
00961 }
00962 }
00963
00967 void App::s_receiveMessageFromNetwork(QString& s){
00968 statusBar->showMessage(s);
00969 }
00970
00974 void App::s_addNetwork(){
00975 NetworkInput *n = new NetworkInput();
00976 networkAddresses.append(n);
00977 vbnetworkDock->addWidget(n);
00978 QObject::connect(n, SIGNAL(message(QString&)), this, SLOT(s_receiveMessageFromNetwork(QString&)));
00979 }
00980
00984 void App::colorate(colorMaker &color){
00985 if (coloredImage != NULL)
00986 delete coloredImage;
00987 coloredImage = new QImage(currentSize, QImage::Format_RGB888);
00988
00989 if (maxValue == 0 || maxValue > 10000000)
00990 maxValue = 256;
00991
00992 if (showAnimation->checkState() != Qt::Checked)
00993 bar->show();
00994
00995 for (int i=0; i<currentSize.width(); i++){
00996 for (int j=0; j<currentSize.height(); j++){
00997 QRgb r = calculatedImage->pixel(i,j);
00998 float value = ImageCalculator::RGBAToInt(r) * color.getNbLevels() / maxValue;
00999
01000 QColor newColor = color.get(value);
01001 coloredImage->setPixel(i,j, newColor.rgb());
01002 }
01003
01004 if (showAnimation->checkState() != Qt::Checked)
01005 bar->setValue(100 * i / currentSize.width());
01006 }
01007
01008 renderingImage->setPixmap(QPixmap::fromImage(*coloredImage));
01009 if (showAnimation->checkState() != Qt::Checked)
01010 bar->hide();
01011 coloredImage->save("colored.bmp");
01012 }
01013
01017 QStringList App::collectNetworkAgents(){
01018 QStringList networkAgentsList;
01019 for (QList<NetworkInput*>::iterator i = networkAddresses.begin(); i != networkAddresses.end(); i++)
01020 if ((*i)->getUrl() != QString(""))
01021 networkAgentsList << (*i)->getUrl();
01022
01023 return networkAgentsList;
01024 }
01025
01029 void App::setNetworkList(QList<QString>& l){
01030
01031 for (QList<NetworkInput*>::const_iterator i=networkAddresses.begin(); i!=networkAddresses.end(); i++){
01032 NetworkInput *n = *i;
01033 delete n;
01034 }
01035 networkAddresses.clear();
01036
01037
01038 for (QList<QString>::const_iterator i = l.begin(); i!=l.end(); i++){
01039 NetworkInput *n = new NetworkInput();
01040 n->setUrl(*i);
01041 QObject::connect(n, SIGNAL(message(const QString&)), this, SLOT(s_receiveMessageFromNetwork(QString&)));
01042 networkAddresses.append(n);
01043 vbnetworkDock->addWidget(n);
01044 }
01045 vbnetworkDock->update();
01046 }
01047
01051 void App::runLightning(){
01052
01053 lightningMaker m(threeDrendering, normalMap, currentWindow, currentSize, coloredImage,
01054 triplex(0,0,-3), triplex(-2,-2,-3));
01055 m.run();
01056 }