Path: blob/devel/ElmerGUI/Application/vtkpost/isocontour.cpp
3203 views
/*****************************************************************************1* *2* Elmer, A Finite Element Software for Multiphysical Problems *3* *4* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland *5* *6* This program is free software; you can redistribute it and/or *7* modify it under the terms of the GNU General Public License *8* as published by the Free Software Foundation; either version 2 *9* of the License, or (at your option) any later version. *10* *11* This program is distributed in the hope that it will be useful, *12* but WITHOUT ANY WARRANTY; without even the implied warranty of *13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *14* GNU General Public License for more details. *15* *16* You should have received a copy of the GNU General Public License *17* along with this program (in file fem/GPL-2); if not, write to the *18* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *19* Boston, MA 02110-1301, USA. *20* *21*****************************************************************************/2223/*****************************************************************************24* *25* ElmerGUI isocontour *26* *27*****************************************************************************28* *29* Authors: Mikko Lyly, Juha Ruokolainen and Peter R�back *30* Email: [email protected] *31* Web: http://www.csc.fi/elmer *32* Address: CSC - IT Center for Science Ltd. *33* Keilaranta 14 *34* 02101 Espoo, Finland *35* *36* Original Date: 15 Mar 2008 *37* *38*****************************************************************************/3940#include <QtGui>41#include <QColorDialog>42#include <iostream>43#include "epmesh.h"44#include "vtkpost.h"45#include "isocontour.h"46#include "timestep.h"4748#include <vtkUnstructuredGrid.h>49#include <vtkPointData.h>50#include <vtkFloatArray.h>51#include <vtkContourFilter.h>52#include <vtkDataSetMapper.h>53#include <vtkLookupTable.h>54#include <vtkProperty.h>55#include <vtkActor.h>56#include <vtkTubeFilter.h>57#include <vtkClipPolyData.h>58#include <vtkPlane.h>5960using namespace std;6162IsoContour::IsoContour(QWidget *parent)63: QDialog(parent)64{65ui.setupUi(this);6667connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancelButtonClicked()));68connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyButtonClicked()));69connect(ui.okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked()));70connect(ui.contoursCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(contoursSelectionChanged(int)));71connect(ui.colorCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(colorSelectionChanged(int)));72connect(ui.keepContourLimits, SIGNAL(stateChanged(int)), this, SLOT(keepContourLimitsSlot(int)));73connect(ui.keepColorLimits, SIGNAL(stateChanged(int)), this, SLOT(keepColorLimitsSlot(int)));7475setWindowIcon(QIcon(":/icons/Mesh3D.png"));7677ui.cancelButton->setIcon(QIcon::fromTheme("dialog-error-round"));78ui.applyButton->setIcon(QIcon::fromTheme("view-refresh"));79ui.okButton->setIcon(QIcon::fromTheme("dialog-accept"));8081setNullColor(Qt::blue);82connect(ui.nullColorButton, SIGNAL(clicked()), this, SLOT(nullColorButtonClicked()));83}8485IsoContour::~IsoContour()86{87}8889void IsoContour::applyButtonClicked()90{91emit(drawIsoContourSignal());92}9394void IsoContour::cancelButtonClicked()95{96emit(hideIsoContourSignal());97close();98}99100void IsoContour::okButtonClicked()101{102emit(drawIsoContourSignal());103close();104}105106void IsoContour::populateWidgets(VtkPost* vtkPost)107{108this->scalarField = vtkPost->GetScalarField();109this->scalarFields = vtkPost->GetScalarFields();110111QString contoursName = ui.contoursCombo->currentText();112QString colorName = ui.colorCombo->currentText();113114ui.contoursCombo->clear();115ui.colorCombo->clear();116117for(int i = 0; i < scalarFields; i++) {118ScalarField *sf = &scalarField[i];119ui.contoursCombo->addItem(sf->name);120ui.colorCombo->addItem(sf->name);121}122123this->SetFieldName(contoursName);124this->SetColorName(colorName);125126contoursSelectionChanged(ui.contoursCombo->currentIndex());127colorSelectionChanged(ui.colorCombo->currentIndex());128129ui.contourList->clear();130}131132void IsoContour::contoursSelectionChanged(int newIndex)133{134ScalarField *sf = &this->scalarField[newIndex];135if(!ui.keepContourLimits->isChecked()) {136ui.contoursMinEdit->setText(QString::number(sf->minVal));137ui.contoursMaxEdit->setText(QString::number(sf->maxVal));138}139}140141void IsoContour::colorSelectionChanged(int newIndex)142{143ScalarField *sf = &this->scalarField[newIndex];144if(!ui.keepColorLimits->isChecked()) {145ui.colorMinEdit->setText(QString::number(sf->minVal));146ui.colorMaxEdit->setText(QString::number(sf->maxVal));147}148if(ui.colorCombo->currentIndex() == 0 ){ // i.e. Null field149ui.nullColorLabel->show();150ui.nullColorButton->show();151ui.colorMinEdit->setEnabled(false);152ui.colorMaxEdit->setEnabled(false);153ui.colorMinLabel->setEnabled(false);154ui.colorMaxLabel->setEnabled(false);155ui.keepColorLimits->setEnabled(false);156}else{157ui.nullColorLabel->hide();158ui.nullColorButton->hide();159ui.colorMinEdit->setEnabled(true);160ui.colorMaxEdit->setEnabled(true);161ui.colorMinLabel->setEnabled(true);162ui.colorMaxLabel->setEnabled(true);163ui.keepColorLimits->setEnabled(true);164}165}166167void IsoContour::keepContourLimitsSlot(int state)168{169if(state == 0)170contoursSelectionChanged(ui.contoursCombo->currentIndex());171}172173void IsoContour::keepColorLimitsSlot(int state)174{175if(state == 0)176colorSelectionChanged(ui.colorCombo->currentIndex());177}178179void IsoContour::draw(VtkPost* vtkPost, TimeStep* timeStep)180{181int contourIndex = ui.contoursCombo->currentIndex();182QString contourName = ui.contoursCombo->currentText();183int contours = ui.contoursSpin->value() + 1;184int lineWidth = ui.lineWidthSpin->value();185double contourMinVal = ui.contoursMinEdit->text().toDouble();186double contourMaxVal = ui.contoursMaxEdit->text().toDouble();187int colorIndex = ui.colorCombo->currentIndex();188QString colorName = ui.colorCombo->currentText();189double colorMinVal = ui.colorMinEdit->text().toDouble();190double colorMaxVal = ui.colorMaxEdit->text().toDouble();191bool useTubeFilter = ui.useTubeFilter->isChecked();192int tubeRadius = ui.tubeRadius->value();193int tubeQuality = ui.tubeQuality->value();194bool useClip = ui.useClip->isChecked();195useClip |= vtkPost->GetClipAll();196197// contour list:198QString contourListText = ui.contourList->text().trimmed();199QStringList contourList = contourListText.split(";");200int contourValues = contourList.count();201202#if WITH_QT6203vector<double> contourValue;204for(int i = 0; i < contourValues; i++)205contourValue.push_back(contourList.at(i).toDouble());206sort(contourValue.begin(), contourValue.end());207#else208QVector<double> contourValue(contourValues);209for(int i = 0; i < contourValues; i++)210contourValue[i] = contourList.at(i).toDouble();211qSort(contourValue);212#endif213214bool useListValues = false;215if(!contourListText.isEmpty())216useListValues = true;217218ScalarField* sf = &scalarField[contourIndex];219int maxDataStepsContour = sf->values / vtkPost->NofNodes();220int step = timeStep->ui.timeStep->value();221if(step > maxDataStepsContour) step = maxDataStepsContour;222if(step > timeStep->maxSteps) step = timeStep->maxSteps;223int contourOffset = vtkPost->NofNodes() * (step-1);224225sf = &scalarField[colorIndex];226int maxDataStepsColor = sf->values / vtkPost->NofNodes();227step = timeStep->ui.timeStep->value();228if(step > maxDataStepsColor) step = maxDataStepsColor;229if(step > timeStep->maxSteps) step = timeStep->maxSteps;230int colorOffset = vtkPost->NofNodes() * (step-1);231232if(contourName == "Null") return;233234// Scalars:235//----------236vtkPost->GetSurfaceGrid()->GetPointData()->RemoveArray("IsoContour");237vtkFloatArray* contourArray = vtkFloatArray::New();238sf = &scalarField[contourIndex];239contourArray->SetNumberOfComponents(1);240contourArray->SetNumberOfTuples(vtkPost->NofNodes());241contourArray->SetName("IsoContour");242for(int i = 0; i < vtkPost->NofNodes(); i++)243contourArray->SetComponent(i, 0, sf->value[i + contourOffset]);244vtkPost->GetSurfaceGrid()->GetPointData()->AddArray(contourArray);245246vtkPost->GetSurfaceGrid()->GetPointData()->RemoveArray("IsoContourColor");247vtkFloatArray* colorArray = vtkFloatArray::New();248sf = &scalarField[colorIndex];249colorArray->SetName("IsoContourColor");250colorArray->SetNumberOfComponents(1);251colorArray->SetNumberOfTuples(vtkPost->NofNodes());252for(int i = 0; i < vtkPost->NofNodes(); i++)253colorArray->SetComponent(i, 0, sf->value[i + colorOffset]);254vtkPost->GetSurfaceGrid()->GetPointData()->AddArray(colorArray);255256// Isocontours:257//--------------258vtkContourFilter* iso = vtkContourFilter::New();259vtkPost->GetSurfaceGrid()->GetPointData()->SetActiveScalars("IsoContour");260#if VTK_MAJOR_VERSION <= 5261iso->SetInput(vtkPost->GetSurfaceGrid());262#else263iso->SetInputData(vtkPost->GetSurfaceGrid());264#endif265iso->ComputeScalarsOn();266if(useListValues) {267iso->SetNumberOfContours(contourValues);268for(int i = 0; i < contourValues; i++)269iso->SetValue(i, contourValue[i]);270} else {271iso->GenerateValues(contours, contourMinVal, contourMaxVal);272}273274// Tube filter:275//-------------276vtkTubeFilter* tubes = vtkTubeFilter::New();277if(useTubeFilter) {278double r = vtkPost->GetLength() * tubeRadius / 2000.0;279tubes->SetInputConnection(iso->GetOutputPort());280tubes->SetNumberOfSides(tubeQuality);281tubes->SetRadius(r);282}283284// Apply clip plane:285//-------------------286vtkClipPolyData* clipper = vtkClipPolyData::New();287if(useClip) {288if(useTubeFilter) {289clipper->SetInputConnection(tubes->GetOutputPort());290} else {291clipper->SetInputConnection(iso->GetOutputPort());292}293clipper->SetClipFunction(vtkPost->GetClipPlane());294clipper->GenerateClipScalarsOn();295clipper->GenerateClippedOutputOn();296}297298// Mapper:299//---------300vtkDataSetMapper* mapper = vtkDataSetMapper::New();301if(useClip) {302mapper->SetInputConnection(clipper->GetOutputPort());303} else {304if(useTubeFilter) {305mapper->SetInputConnection(tubes->GetOutputPort());306} else {307mapper->SetInputConnection(iso->GetOutputPort());308}309}310mapper->ScalarVisibilityOn();311mapper->SelectColorArray("IsoContourColor");312mapper->SetScalarModeToUsePointFieldData();313mapper->SetScalarRange(colorMinVal, colorMaxVal);314mapper->InterpolateScalarsBeforeMappingOn();315//mapper->SetLookupTable(vtkPost->GetCurrentLut());316mapper->SetLookupTable(vtkPost->GetLut("Isocontour"));317// mapper->ImmediateModeRenderingOn();318if(ui.colorCombo->currentIndex() == 0 ){ // i.e. Null field319mapper->SetScalarRange(0, 1);320double h = nullColor.hueF();321double s = nullColor.saturationF();322double v = nullColor.valueF();323int nColor =128;324vtkLookupTable* nullLut = vtkLookupTable::New();325nullLut->SetHueRange(h, h);326nullLut->SetSaturationRange(s, s);327nullLut->SetValueRange(v, v);328nullLut->SetNumberOfColors(nColor);329nullLut->Build();330mapper->SetLookupTable(nullLut);331nullLut->Delete();332}333334// Actor & renderer:335//-------------------336vtkPost->GetIsoContourActor()->SetMapper(mapper);337vtkPost->GetIsoContourActor()->GetProperty()->SetLineWidth(lineWidth);338vtkPost->SetCurrentIsoContourName(colorName);339340// Clean up:341//----------342mapper->Delete();343clipper->Delete();344tubes->Delete();345iso->Delete();346colorArray->Delete();347contourArray->Delete();348}349350351// Public slots:352//---------------353QString IsoContour::GetFieldName()354{355return ui.contoursCombo->currentText();356}357358QString IsoContour::GetColorName()359{360return ui.colorCombo->currentText();361}362363bool IsoContour::SetFieldName(QString name)364{365for(int i = 0; i < ui.contoursCombo->count(); i++) {366if(ui.contoursCombo->itemText(i) == name) {367ui.contoursCombo->setCurrentIndex(i);368return true;369}370}371return false;372}373374bool IsoContour::SetColorName(QString name)375{376for(int i = 0; i < ui.colorCombo->count(); i++) {377if(ui.colorCombo->itemText(i) == name) {378ui.colorCombo->setCurrentIndex(i);379return true;380}381}382return false;383}384385void IsoContour::SetMinFieldVal(double f)386{387ui.contoursMinEdit->setText(QString::number(f));388}389390void IsoContour::SetMaxFieldVal(double f)391{392ui.contoursMaxEdit->setText(QString::number(f));393}394395void IsoContour::SetContours(int n)396{397ui.contoursSpin->setValue(n);398}399400void IsoContour::SetContourValues(QString values)401{402ui.contourList->setText(values);403}404405void IsoContour::KeepFieldLimits(bool b)406{407ui.keepContourLimits->setChecked(b);408}409410void IsoContour::SetMinColorVal(double f)411{412ui.colorMinEdit->setText(QString::number(f));413}414415void IsoContour::SetMaxColorVal(double f)416{417ui.colorMaxEdit->setText(QString::number(f));418}419420void IsoContour::KeepColorLimits(bool b)421{422ui.keepColorLimits->setChecked(b);423}424425void IsoContour::UseTubeFilter(bool b)426{427ui.useTubeFilter->setChecked(b);428}429430void IsoContour::UseClipPlane(bool b)431{432ui.useClip->setChecked(b);433}434435void IsoContour::SetLineWidth(int n)436{437ui.lineWidthSpin->setValue(n);438}439440void IsoContour::SetTubeQuality(int n)441{442ui.tubeQuality->setValue(n);443}444445void IsoContour::SetTubeRadius(int n)446{447ui.tubeRadius->setValue(n);448}449450void IsoContour::nullColorButtonClicked()451{452setNullColor(QColorDialog::getColor(nullColor));453}454455void IsoContour::setNullColor(QColor color){456if(!color.isValid()) return;457458nullColor = color;459460QPalette plt(ui.nullColorLabel->palette());461plt.setColor(QPalette::WindowText, nullColor);462ui.nullColorLabel->setPalette(plt);463}464465