1 /*****************************************************************************
2  *                                                                           *
3  *  Elmer, A Finite Element Software for Multiphysical Problems              *
4  *                                                                           *
5  *  Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland    *
6  *                                                                           *
7  *  This program is free software; you can redistribute it and/or            *
8  *  modify it under the terms of the GNU General Public License              *
9  *  as published by the Free Software Foundation; either version 2           *
10  *  of the License, or (at your option) any later version.                   *
11  *                                                                           *
12  *  This program is distributed in the hope that it will be useful,          *
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
15  *  GNU General Public License for more details.                             *
16  *                                                                           *
17  *  You should have received a copy of the GNU General Public License        *
18  *  along with this program (in file fem/GPL-2); if not, write to the        *
19  *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,         *
20  *  Boston, MA 02110-1301, USA.                                              *
21  *                                                                           *
22  *****************************************************************************/
23 
24 /*****************************************************************************
25  *                                                                           *
26  *  ElmerGUI timestep                                                        *
27  *                                                                           *
28  *****************************************************************************
29  *                                                                           *
30  *  Authors: Mikko Lyly, Juha Ruokolainen and Peter R�back                   *
31  *  Email:   Juha.Ruokolainen@csc.fi                                         *
32  *  Web:     http://www.csc.fi/elmer                                         *
33  *  Address: CSC - IT Center for Science Ltd.                                 *
34  *           Keilaranta 14                                                   *
35  *           02101 Espoo, Finland                                            *
36  *                                                                           *
37  *  Original Date: 15 Mar 2008                                               *
38  *                                                                           *
39  *****************************************************************************/
40 #if WITH_QT5
41   #include <QtWidgets>
42 #endif
43 #include <QtGui>
44 #include <iostream>
45 #include <vtkRenderWindow.h>
46 #include <vtkWindowToImageFilter.h>
47 #include <vtkPNGWriter.h>
48 #include "timestep.h"
49 
50 using namespace std;
51 
TimeStep(QWidget * parent)52 TimeStep::TimeStep(QWidget *parent)
53   : QDialog(parent)
54 {
55   ui.setupUi(this);
56 
57   connect(ui.loopButton, SIGNAL(clicked()), this, SLOT(loopButtonClicked()));
58   connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancelButtonClicked()));
59   connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyButtonClicked()));
60   connect(ui.okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked()));
61   connect(ui.browseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
62 
63   maxSteps = 0;
64   loopOn = false;
65   saveDir = "";
66 
67   setWindowTitle("Time step control");
68   setWindowIcon(QIcon(":/icons/Mesh3D.png"));
69 
70   ui.applyButton->setIcon(QIcon(":/icons/dialog-ok.png"));
71   ui.loopButton->setIcon(QIcon(":/icons/dialog-ok.png"));
72 }
73 
~TimeStep()74 TimeStep::~TimeStep()
75 {
76 }
77 
browseButtonClicked()78 void TimeStep::browseButtonClicked()
79 {
80   QString saveDir = QFileDialog::getExistingDirectory(this,
81 	 tr("Save directory"), "", QFileDialog::ShowDirsOnly
82 	       | QFileDialog::DontResolveSymlinks);
83 
84   ui.saveDirectory->setText(saveDir);
85 }
86 
cancelButtonClicked()87 void TimeStep::cancelButtonClicked()
88 {
89   close();
90 }
91 
okButtonClicked()92 void TimeStep::okButtonClicked()
93 {
94   applyButtonClicked();
95   cancelButtonClicked();
96 }
97 
applyButtonClicked()98 void TimeStep::applyButtonClicked()
99 {
100   int current = ui.timeStep->value();
101 
102   if(current < 1) {
103     current = 1;
104     ui.timeStep->setValue(current);
105   }
106 
107   if(current > maxSteps) {
108     current = maxSteps;
109     ui.timeStep->setValue(current);
110   }
111 
112   emit(timeStepChangedSignal());
113 }
114 
canProceedWithNextSlot(vtkRenderWindow * renderWindow)115 void TimeStep::canProceedWithNextSlot(vtkRenderWindow *renderWindow)
116 {
117   if(!loopOn) return;
118 
119   bool saveFrames = ui.saveFrames->isChecked();
120   int current = ui.timeStep->value();
121   int stop = ui.stop->value();
122   int increment = ui.increment->value();
123 
124   if(saveFrames) {
125     QString saveDir = ui.saveDirectory->text().trimmed();
126     if(saveDir.isEmpty()) saveDir = ".";
127     QString frameName = "frame" + QString::number(current) + ".png";
128     QString fileName = saveDir + "/" + frameName;
129 
130     vtkWindowToImageFilter *image = vtkWindowToImageFilter::New();
131     image->SetInput(renderWindow);
132     image->Update();
133 
134     vtkPNGWriter *writer =  vtkPNGWriter::New();
135     writer->SetInputConnection(image->GetOutputPort());
136 
137 #if WITH_QT5
138     writer->SetFileName(fileName.toLatin1().data());
139 #else
140     writer->SetFileName(fileName.toAscii().data());
141 #endif
142 
143     renderWindow->Render();
144     writer->Write();
145 
146     image->Delete();
147     writer->Delete();
148   }
149 
150   if(increment < 1) {
151     increment = 1;
152     ui.increment->setValue(increment);
153   }
154 
155   if(stop > maxSteps) {
156     stop = maxSteps;
157     ui.stop->setValue(stop);
158   }
159 
160   if(current > stop) {
161     loopOn = false;
162     ui.loopButton->setText("Loop");
163     ui.loopButton->setIcon(QIcon(":/icons/dialog-ok.png"));
164     this->repaint();
165 
166   } else {
167     ui.loopButton->setText("Stop");
168     ui.loopButton->setIcon(QIcon(":/icons/dialog-close.png"));
169     this->repaint();
170     current += increment;
171 
172     if(current > stop) {
173       loopOn = false;
174       ui.loopButton->setText("Loop");
175       ui.loopButton->setIcon(QIcon(":/icons/dialog-ok.png"));
176       this->repaint();
177       return;
178     }
179 
180     ui.timeStep->setValue(current);
181     this->repaint();
182     applyButtonClicked();
183   }
184 }
185 
loopButtonClicked()186 void TimeStep::loopButtonClicked()
187 {
188   if(loopOn) {
189     loopOn = false;
190     ui.loopButton->setText("Loop");
191     ui.loopButton->setIcon(QIcon(":/icons/dialog-ok.png"));
192     this->repaint();
193 
194   } else {
195     loopOn = true;
196     ui.loopButton->setText("Stop");
197     ui.loopButton->setIcon(QIcon(":/icons/dialog-close.png"));
198     this->repaint();
199     int start = ui.start->value();
200     int stop = ui.stop->value();
201     int increment = ui.increment->value();
202 
203     if(start < 1) {
204       start = 1;
205       ui.start->setValue(start);
206     }
207 
208     if(start > maxSteps) {
209       start = maxSteps;
210       ui.start->setValue(start);
211     }
212 
213     if(stop < 1) {
214       stop = 1;
215       ui.stop->setValue(stop);
216     }
217 
218     if(stop > maxSteps) {
219       stop = maxSteps;
220       ui.stop->setValue(stop);
221     }
222 
223     if(stop < start) {
224       stop = start;
225       ui.stop->setValue(stop);
226     }
227 
228     if(increment < 1) {
229       increment = 1;
230       ui.increment->setValue(increment);
231     }
232 
233     ui.timeStep->setValue(start);
234     this->repaint();
235     applyButtonClicked();
236   }
237 }
238 
SetCurrent(int n)239 void TimeStep::SetCurrent(int n)
240 {
241   ui.timeStep->setValue(n);
242 }
243 
SetStart(int n)244 void TimeStep::SetStart(int n)
245 {
246   ui.start->setValue(n);
247 }
248 
SetStop(int n)249 void TimeStep::SetStop(int n)
250 {
251   ui.stop->setValue(n);
252 }
253 
SetIncrement(int n)254 void TimeStep::SetIncrement(int n)
255 {
256   ui.increment->setValue(n);
257 }
258 
SetMatcCmd(QString cmd)259 void TimeStep::SetMatcCmd(QString cmd)
260 {
261   ui.doBefore->setText(cmd);
262 }
263 
RegenerateBeforeDrawing(bool b)264 void TimeStep::RegenerateBeforeDrawing(bool b)
265 {
266   ui.regenerateBeforeDrawing->setChecked(b);
267 }
268 
SaveFrames(bool b)269 void TimeStep::SaveFrames(bool b)
270 {
271   ui.saveFrames->setChecked(b);
272 }
273 
SetSaveDirectory(QString dirName)274 void TimeStep::SetSaveDirectory(QString dirName)
275 {
276   ui.saveDirectory->setText(dirName);
277 }
278 
Loop()279 void TimeStep::Loop()
280 {
281   loopButtonClicked();
282 }
283 
IsLooping()284 bool TimeStep::IsLooping()
285 {
286   return this->loopOn;
287 }
288 
DrawCurrent()289 void TimeStep::DrawCurrent()
290 {
291   if(loopOn) return;
292   this->applyButtonClicked();
293 }
294