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