Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/Application/vtkpost/isocontour.cpp
3203 views
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 isocontour *
27
* *
28
*****************************************************************************
29
* *
30
* Authors: Mikko Lyly, Juha Ruokolainen and Peter R�back *
31
* Email: [email protected] *
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
41
#include <QtGui>
42
#include <QColorDialog>
43
#include <iostream>
44
#include "epmesh.h"
45
#include "vtkpost.h"
46
#include "isocontour.h"
47
#include "timestep.h"
48
49
#include <vtkUnstructuredGrid.h>
50
#include <vtkPointData.h>
51
#include <vtkFloatArray.h>
52
#include <vtkContourFilter.h>
53
#include <vtkDataSetMapper.h>
54
#include <vtkLookupTable.h>
55
#include <vtkProperty.h>
56
#include <vtkActor.h>
57
#include <vtkTubeFilter.h>
58
#include <vtkClipPolyData.h>
59
#include <vtkPlane.h>
60
61
using namespace std;
62
63
IsoContour::IsoContour(QWidget *parent)
64
: QDialog(parent)
65
{
66
ui.setupUi(this);
67
68
connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancelButtonClicked()));
69
connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyButtonClicked()));
70
connect(ui.okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked()));
71
connect(ui.contoursCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(contoursSelectionChanged(int)));
72
connect(ui.colorCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(colorSelectionChanged(int)));
73
connect(ui.keepContourLimits, SIGNAL(stateChanged(int)), this, SLOT(keepContourLimitsSlot(int)));
74
connect(ui.keepColorLimits, SIGNAL(stateChanged(int)), this, SLOT(keepColorLimitsSlot(int)));
75
76
setWindowIcon(QIcon(":/icons/Mesh3D.png"));
77
78
ui.cancelButton->setIcon(QIcon::fromTheme("dialog-error-round"));
79
ui.applyButton->setIcon(QIcon::fromTheme("view-refresh"));
80
ui.okButton->setIcon(QIcon::fromTheme("dialog-accept"));
81
82
setNullColor(Qt::blue);
83
connect(ui.nullColorButton, SIGNAL(clicked()), this, SLOT(nullColorButtonClicked()));
84
}
85
86
IsoContour::~IsoContour()
87
{
88
}
89
90
void IsoContour::applyButtonClicked()
91
{
92
emit(drawIsoContourSignal());
93
}
94
95
void IsoContour::cancelButtonClicked()
96
{
97
emit(hideIsoContourSignal());
98
close();
99
}
100
101
void IsoContour::okButtonClicked()
102
{
103
emit(drawIsoContourSignal());
104
close();
105
}
106
107
void IsoContour::populateWidgets(VtkPost* vtkPost)
108
{
109
this->scalarField = vtkPost->GetScalarField();
110
this->scalarFields = vtkPost->GetScalarFields();
111
112
QString contoursName = ui.contoursCombo->currentText();
113
QString colorName = ui.colorCombo->currentText();
114
115
ui.contoursCombo->clear();
116
ui.colorCombo->clear();
117
118
for(int i = 0; i < scalarFields; i++) {
119
ScalarField *sf = &scalarField[i];
120
ui.contoursCombo->addItem(sf->name);
121
ui.colorCombo->addItem(sf->name);
122
}
123
124
this->SetFieldName(contoursName);
125
this->SetColorName(colorName);
126
127
contoursSelectionChanged(ui.contoursCombo->currentIndex());
128
colorSelectionChanged(ui.colorCombo->currentIndex());
129
130
ui.contourList->clear();
131
}
132
133
void IsoContour::contoursSelectionChanged(int newIndex)
134
{
135
ScalarField *sf = &this->scalarField[newIndex];
136
if(!ui.keepContourLimits->isChecked()) {
137
ui.contoursMinEdit->setText(QString::number(sf->minVal));
138
ui.contoursMaxEdit->setText(QString::number(sf->maxVal));
139
}
140
}
141
142
void IsoContour::colorSelectionChanged(int newIndex)
143
{
144
ScalarField *sf = &this->scalarField[newIndex];
145
if(!ui.keepColorLimits->isChecked()) {
146
ui.colorMinEdit->setText(QString::number(sf->minVal));
147
ui.colorMaxEdit->setText(QString::number(sf->maxVal));
148
}
149
if(ui.colorCombo->currentIndex() == 0 ){ // i.e. Null field
150
ui.nullColorLabel->show();
151
ui.nullColorButton->show();
152
ui.colorMinEdit->setEnabled(false);
153
ui.colorMaxEdit->setEnabled(false);
154
ui.colorMinLabel->setEnabled(false);
155
ui.colorMaxLabel->setEnabled(false);
156
ui.keepColorLimits->setEnabled(false);
157
}else{
158
ui.nullColorLabel->hide();
159
ui.nullColorButton->hide();
160
ui.colorMinEdit->setEnabled(true);
161
ui.colorMaxEdit->setEnabled(true);
162
ui.colorMinLabel->setEnabled(true);
163
ui.colorMaxLabel->setEnabled(true);
164
ui.keepColorLimits->setEnabled(true);
165
}
166
}
167
168
void IsoContour::keepContourLimitsSlot(int state)
169
{
170
if(state == 0)
171
contoursSelectionChanged(ui.contoursCombo->currentIndex());
172
}
173
174
void IsoContour::keepColorLimitsSlot(int state)
175
{
176
if(state == 0)
177
colorSelectionChanged(ui.colorCombo->currentIndex());
178
}
179
180
void IsoContour::draw(VtkPost* vtkPost, TimeStep* timeStep)
181
{
182
int contourIndex = ui.contoursCombo->currentIndex();
183
QString contourName = ui.contoursCombo->currentText();
184
int contours = ui.contoursSpin->value() + 1;
185
int lineWidth = ui.lineWidthSpin->value();
186
double contourMinVal = ui.contoursMinEdit->text().toDouble();
187
double contourMaxVal = ui.contoursMaxEdit->text().toDouble();
188
int colorIndex = ui.colorCombo->currentIndex();
189
QString colorName = ui.colorCombo->currentText();
190
double colorMinVal = ui.colorMinEdit->text().toDouble();
191
double colorMaxVal = ui.colorMaxEdit->text().toDouble();
192
bool useTubeFilter = ui.useTubeFilter->isChecked();
193
int tubeRadius = ui.tubeRadius->value();
194
int tubeQuality = ui.tubeQuality->value();
195
bool useClip = ui.useClip->isChecked();
196
useClip |= vtkPost->GetClipAll();
197
198
// contour list:
199
QString contourListText = ui.contourList->text().trimmed();
200
QStringList contourList = contourListText.split(";");
201
int contourValues = contourList.count();
202
203
#if WITH_QT6
204
vector<double> contourValue;
205
for(int i = 0; i < contourValues; i++)
206
contourValue.push_back(contourList.at(i).toDouble());
207
sort(contourValue.begin(), contourValue.end());
208
#else
209
QVector<double> contourValue(contourValues);
210
for(int i = 0; i < contourValues; i++)
211
contourValue[i] = contourList.at(i).toDouble();
212
qSort(contourValue);
213
#endif
214
215
bool useListValues = false;
216
if(!contourListText.isEmpty())
217
useListValues = true;
218
219
ScalarField* sf = &scalarField[contourIndex];
220
int maxDataStepsContour = sf->values / vtkPost->NofNodes();
221
int step = timeStep->ui.timeStep->value();
222
if(step > maxDataStepsContour) step = maxDataStepsContour;
223
if(step > timeStep->maxSteps) step = timeStep->maxSteps;
224
int contourOffset = vtkPost->NofNodes() * (step-1);
225
226
sf = &scalarField[colorIndex];
227
int maxDataStepsColor = sf->values / vtkPost->NofNodes();
228
step = timeStep->ui.timeStep->value();
229
if(step > maxDataStepsColor) step = maxDataStepsColor;
230
if(step > timeStep->maxSteps) step = timeStep->maxSteps;
231
int colorOffset = vtkPost->NofNodes() * (step-1);
232
233
if(contourName == "Null") return;
234
235
// Scalars:
236
//----------
237
vtkPost->GetSurfaceGrid()->GetPointData()->RemoveArray("IsoContour");
238
vtkFloatArray* contourArray = vtkFloatArray::New();
239
sf = &scalarField[contourIndex];
240
contourArray->SetNumberOfComponents(1);
241
contourArray->SetNumberOfTuples(vtkPost->NofNodes());
242
contourArray->SetName("IsoContour");
243
for(int i = 0; i < vtkPost->NofNodes(); i++)
244
contourArray->SetComponent(i, 0, sf->value[i + contourOffset]);
245
vtkPost->GetSurfaceGrid()->GetPointData()->AddArray(contourArray);
246
247
vtkPost->GetSurfaceGrid()->GetPointData()->RemoveArray("IsoContourColor");
248
vtkFloatArray* colorArray = vtkFloatArray::New();
249
sf = &scalarField[colorIndex];
250
colorArray->SetName("IsoContourColor");
251
colorArray->SetNumberOfComponents(1);
252
colorArray->SetNumberOfTuples(vtkPost->NofNodes());
253
for(int i = 0; i < vtkPost->NofNodes(); i++)
254
colorArray->SetComponent(i, 0, sf->value[i + colorOffset]);
255
vtkPost->GetSurfaceGrid()->GetPointData()->AddArray(colorArray);
256
257
// Isocontours:
258
//--------------
259
vtkContourFilter* iso = vtkContourFilter::New();
260
vtkPost->GetSurfaceGrid()->GetPointData()->SetActiveScalars("IsoContour");
261
#if VTK_MAJOR_VERSION <= 5
262
iso->SetInput(vtkPost->GetSurfaceGrid());
263
#else
264
iso->SetInputData(vtkPost->GetSurfaceGrid());
265
#endif
266
iso->ComputeScalarsOn();
267
if(useListValues) {
268
iso->SetNumberOfContours(contourValues);
269
for(int i = 0; i < contourValues; i++)
270
iso->SetValue(i, contourValue[i]);
271
} else {
272
iso->GenerateValues(contours, contourMinVal, contourMaxVal);
273
}
274
275
// Tube filter:
276
//-------------
277
vtkTubeFilter* tubes = vtkTubeFilter::New();
278
if(useTubeFilter) {
279
double r = vtkPost->GetLength() * tubeRadius / 2000.0;
280
tubes->SetInputConnection(iso->GetOutputPort());
281
tubes->SetNumberOfSides(tubeQuality);
282
tubes->SetRadius(r);
283
}
284
285
// Apply clip plane:
286
//-------------------
287
vtkClipPolyData* clipper = vtkClipPolyData::New();
288
if(useClip) {
289
if(useTubeFilter) {
290
clipper->SetInputConnection(tubes->GetOutputPort());
291
} else {
292
clipper->SetInputConnection(iso->GetOutputPort());
293
}
294
clipper->SetClipFunction(vtkPost->GetClipPlane());
295
clipper->GenerateClipScalarsOn();
296
clipper->GenerateClippedOutputOn();
297
}
298
299
// Mapper:
300
//---------
301
vtkDataSetMapper* mapper = vtkDataSetMapper::New();
302
if(useClip) {
303
mapper->SetInputConnection(clipper->GetOutputPort());
304
} else {
305
if(useTubeFilter) {
306
mapper->SetInputConnection(tubes->GetOutputPort());
307
} else {
308
mapper->SetInputConnection(iso->GetOutputPort());
309
}
310
}
311
mapper->ScalarVisibilityOn();
312
mapper->SelectColorArray("IsoContourColor");
313
mapper->SetScalarModeToUsePointFieldData();
314
mapper->SetScalarRange(colorMinVal, colorMaxVal);
315
mapper->InterpolateScalarsBeforeMappingOn();
316
//mapper->SetLookupTable(vtkPost->GetCurrentLut());
317
mapper->SetLookupTable(vtkPost->GetLut("Isocontour"));
318
// mapper->ImmediateModeRenderingOn();
319
if(ui.colorCombo->currentIndex() == 0 ){ // i.e. Null field
320
mapper->SetScalarRange(0, 1);
321
double h = nullColor.hueF();
322
double s = nullColor.saturationF();
323
double v = nullColor.valueF();
324
int nColor =128;
325
vtkLookupTable* nullLut = vtkLookupTable::New();
326
nullLut->SetHueRange(h, h);
327
nullLut->SetSaturationRange(s, s);
328
nullLut->SetValueRange(v, v);
329
nullLut->SetNumberOfColors(nColor);
330
nullLut->Build();
331
mapper->SetLookupTable(nullLut);
332
nullLut->Delete();
333
}
334
335
// Actor & renderer:
336
//-------------------
337
vtkPost->GetIsoContourActor()->SetMapper(mapper);
338
vtkPost->GetIsoContourActor()->GetProperty()->SetLineWidth(lineWidth);
339
vtkPost->SetCurrentIsoContourName(colorName);
340
341
// Clean up:
342
//----------
343
mapper->Delete();
344
clipper->Delete();
345
tubes->Delete();
346
iso->Delete();
347
colorArray->Delete();
348
contourArray->Delete();
349
}
350
351
352
// Public slots:
353
//---------------
354
QString IsoContour::GetFieldName()
355
{
356
return ui.contoursCombo->currentText();
357
}
358
359
QString IsoContour::GetColorName()
360
{
361
return ui.colorCombo->currentText();
362
}
363
364
bool IsoContour::SetFieldName(QString name)
365
{
366
for(int i = 0; i < ui.contoursCombo->count(); i++) {
367
if(ui.contoursCombo->itemText(i) == name) {
368
ui.contoursCombo->setCurrentIndex(i);
369
return true;
370
}
371
}
372
return false;
373
}
374
375
bool IsoContour::SetColorName(QString name)
376
{
377
for(int i = 0; i < ui.colorCombo->count(); i++) {
378
if(ui.colorCombo->itemText(i) == name) {
379
ui.colorCombo->setCurrentIndex(i);
380
return true;
381
}
382
}
383
return false;
384
}
385
386
void IsoContour::SetMinFieldVal(double f)
387
{
388
ui.contoursMinEdit->setText(QString::number(f));
389
}
390
391
void IsoContour::SetMaxFieldVal(double f)
392
{
393
ui.contoursMaxEdit->setText(QString::number(f));
394
}
395
396
void IsoContour::SetContours(int n)
397
{
398
ui.contoursSpin->setValue(n);
399
}
400
401
void IsoContour::SetContourValues(QString values)
402
{
403
ui.contourList->setText(values);
404
}
405
406
void IsoContour::KeepFieldLimits(bool b)
407
{
408
ui.keepContourLimits->setChecked(b);
409
}
410
411
void IsoContour::SetMinColorVal(double f)
412
{
413
ui.colorMinEdit->setText(QString::number(f));
414
}
415
416
void IsoContour::SetMaxColorVal(double f)
417
{
418
ui.colorMaxEdit->setText(QString::number(f));
419
}
420
421
void IsoContour::KeepColorLimits(bool b)
422
{
423
ui.keepColorLimits->setChecked(b);
424
}
425
426
void IsoContour::UseTubeFilter(bool b)
427
{
428
ui.useTubeFilter->setChecked(b);
429
}
430
431
void IsoContour::UseClipPlane(bool b)
432
{
433
ui.useClip->setChecked(b);
434
}
435
436
void IsoContour::SetLineWidth(int n)
437
{
438
ui.lineWidthSpin->setValue(n);
439
}
440
441
void IsoContour::SetTubeQuality(int n)
442
{
443
ui.tubeQuality->setValue(n);
444
}
445
446
void IsoContour::SetTubeRadius(int n)
447
{
448
ui.tubeRadius->setValue(n);
449
}
450
451
void IsoContour::nullColorButtonClicked()
452
{
453
setNullColor(QColorDialog::getColor(nullColor));
454
}
455
456
void IsoContour::setNullColor(QColor color){
457
if(!color.isValid()) return;
458
459
nullColor = color;
460
461
QPalette plt(ui.nullColorLabel->palette());
462
plt.setColor(QPalette::WindowText, nullColor);
463
ui.nullColorLabel->setPalette(plt);
464
}
465