]> SALOME platform Git repositories - modules/visu.git/blob - src/VISUGUI/VisuGUI_Selection.cxx
Salome HOME
Merge with version on tag OCC-V2_1_0d
[modules/visu.git] / src / VISUGUI / VisuGUI_Selection.cxx
1 //  VISU VISUGUI : GUI of VISU component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library 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 GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : VisuGUI_Selection.cxx
25 //  Author : Laurent CORNABE & Hubert ROLLAND 
26 //  Module : VISU
27 //  $Header$
28
29 #include "VisuGUI_Selection.h"
30
31 #include "SALOME_ListIteratorOfListIO.hxx"
32 #include "SALOME_Selection.h"
33 #include "VISU_Actor.h"
34 #include "VISU_PrsObject_i.hh"
35 #include "VISU_Prs3d_i.hh"
36 #include "VISU_PipeLine.hxx"
37 #include "VisuGUI.h"
38 #include "QAD_MessageBox.h"
39 #include "QAD_RightFrame.h"
40 #include "VTKViewer_ViewFrame.h"
41
42 #include <TColStd_IndexedMapOfInteger.hxx>
43
44 #include <map>
45
46 #include <qstring.h>
47 #include <qlabel.h>
48 #include <qspinbox.h>
49 #include <qlistbox.h>
50 #include <qlayout.h>
51 #include <qhbuttongroup.h>
52 #include <qradiobutton.h>
53 #include <qvalidator.h>
54 #include <qpushbutton.h>
55
56 #include <vtkDataSetMapper.h>
57 #include <vtkDataSet.h>
58 #include <vtkPointData.h>
59 #include <vtkCellData.h>
60 #include <vtkCell.h>
61
62 #include "utilities.h"
63
64 using namespace std;
65
66 extern VisuGUI *visuGUI;
67 static QAD_Study* myStudy = NULL;
68 static VisuGUI_SelectionDlg* mySelectionDlg = NULL;
69
70 VisuGUI_SelectionDlg::VisuGUI_SelectionDlg()    
71   : QDialog( QAD_Application::getDesktop(), 0, false, 
72              WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose)
73 {
74   if(mySelectionDlg)
75     mySelectionDlg->close(true);
76
77   setCaption( "Data on elements" );
78   setSizeGripEnabled( TRUE );
79   
80   QGridLayout* TopLayout = new QGridLayout(this);
81   TopLayout->setSpacing(6);
82   TopLayout->setMargin(11);
83   TopLayout->setRowStretch(0, 0);
84   TopLayout->setRowStretch(1, 0);
85   TopLayout->setRowStretch(2, 1);
86   TopLayout->setRowStretch(3, 0);
87
88   QHButtonGroup* aTypeBox = new QHButtonGroup("Selection", this);  
89   
90   QRadioButton* aPointBtn = new QRadioButton("Point", aTypeBox);
91   QRadioButton* aCellBtn = new QRadioButton("Cell", aTypeBox);
92   QRadioButton* aActorBtn = new QRadioButton("Actor", aTypeBox);
93   aPointBtn->setChecked(true);
94
95   connect(aTypeBox, SIGNAL(clicked(int)), this, SLOT(onSelectionChange(int)));
96   
97   TopLayout->addWidget(aTypeBox, 0, 0);
98
99   QWidget* aNamePane = new QWidget(this);
100   QGridLayout* aNameLay = new QGridLayout(aNamePane);
101
102   QLabel* aMeshLbl = new QLabel("Mesh name: ", aNamePane);
103   myMeshName = new QLabel(aNamePane);
104
105   QLabel* aFieldLbl = new QLabel("Field name: ", aNamePane);
106   myFieldName = new QLabel(aNamePane);
107
108   aNameLay->addWidget(aMeshLbl, 0, 0);
109   aNameLay->addWidget(myMeshName, 0, 1);
110   aNameLay->addWidget(aFieldLbl, 1, 0);
111   aNameLay->addWidget(myFieldName, 1, 1);
112
113   TopLayout->addWidget(aNamePane, 1, 0);
114
115   myWidgetStack = new QWidgetStack(this);
116   
117   // Create Points pane
118   myPointsPane = new QVBox(myWidgetStack);
119   myPointsPane->layout()->setSpacing(6);
120   
121   QGroupBox* aDataGrp = new QGroupBox(2, Qt::Horizontal, "Data of Point", myPointsPane);
122   aDataGrp->layout()->setSpacing(6);
123
124   QLabel* aIDLbl = new QLabel("ID:", aDataGrp);
125   myIDValLbl = new QLineEdit("", aDataGrp);
126   QIntValidator* aIntValidator = new QIntValidator(myIDValLbl);
127   aIntValidator->setBottom(0);
128   myIDValLbl->setValidator(aIntValidator);
129   connect(myIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onPointIdEdit(const QString&)));
130
131   QLabel* aValueLbl = new QLabel("Scalar Value:", aDataGrp);
132   myScalarValLbl = new QLabel("", aDataGrp);
133   QLabel* aVectorLbl = new QLabel("Vector Value:", aDataGrp); 
134   myVectorValLbl = new QLabel("", aDataGrp);
135   myVectorValLbl->setMinimumWidth(150);
136
137   QGroupBox* aCoordGrp = new QGroupBox(2, Qt::Horizontal, "Coordinates", myPointsPane);
138   aCoordGrp->layout()->setSpacing(6);
139   QLabel* aXLbl = new QLabel("X:", aCoordGrp);
140   myXValLbl = new QLabel("", aCoordGrp);
141   QLabel* aYLbl = new QLabel("Y:", aCoordGrp);
142   myYValLbl = new QLabel("", aCoordGrp);
143   QLabel* aZLbl = new QLabel("Z:",aCoordGrp );  
144   myZValLbl = new QLabel("", aCoordGrp);
145
146
147   myWidgetStack->addWidget(myPointsPane, 0);
148   
149   // Create Cells pane
150   myCellsPane = new QWidget(myWidgetStack);
151   QGridLayout* aCellLayout = new QGridLayout(myCellsPane);
152   aCellLayout->setSpacing(6);
153   aCellLayout->setRowStretch(0, 0);
154   aCellLayout->setRowStretch(1, 1);
155
156   QGroupBox* aCellGrp = new QGroupBox(2, Qt::Horizontal, "Data of Cell", myCellsPane);
157   
158   QLabel* aCellIDLbl = new QLabel("ID:", aCellGrp);
159   myCellIDValLbl = new QLineEdit("", aCellGrp);
160   myCellIDValLbl->setValidator(aIntValidator);
161   connect(myCellIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onCellIdEdit(const QString&)));
162
163   QLabel* aCellValueLbl = new QLabel("Scalar Value:", aCellGrp);
164   myCellScalarValLbl = new QLabel("", aCellGrp);
165   QLabel* aCellVectorLbl = new QLabel("Vector Value:", aCellGrp);  
166   myCellVectorValLbl = new QLabel("", aCellGrp);
167
168   aCellLayout->addWidget(aCellGrp, 0, 0);
169
170   myListPoints = new QTable(myCellsPane);
171   myListPoints->setReadOnly(true);
172   myListPoints->setNumCols(6);
173   myListPoints->setNumRows(0);
174   myListPoints->setColumnWidth(0, 40);
175   myListPoints->setColumnWidth(1, 40);
176   myListPoints->setColumnWidth(2, 40);
177   myListPoints->setColumnWidth(3, 40);
178   myListPoints->setSelectionMode(QTable::NoSelection);
179   QHeader* aHeader = myListPoints->horizontalHeader();
180   aHeader->setLabel( 0, "ID" );
181   aHeader->setLabel( 1, "X" );
182   aHeader->setLabel( 2, "Y" );
183   aHeader->setLabel( 3, "Z" );
184   aHeader->setLabel( 4, "Scalar" );
185   aHeader->setLabel( 5, "Vector" );
186
187   aCellLayout->addWidget(myListPoints, 1, 0);
188
189   myWidgetStack->addWidget(myCellsPane, 1);
190   
191   // Actor Pane
192   myActorsPane = new QVBox(myWidgetStack);
193   myActorsPane->layout()->setSpacing(6);
194
195   QGroupBox* aPosGrp = new QGroupBox(2, Qt::Horizontal, "Position", myActorsPane);
196   aPosGrp->layout()->setSpacing(6);
197   QLabel* aXPosLbl = new QLabel("X:", aPosGrp);
198   myXPosLbl = new QLabel("0", aPosGrp);
199   QLabel* aYPosLbl = new QLabel("Y:", aPosGrp);
200   myYPosLbl = new QLabel("0", aPosGrp);
201   QLabel* aZPosLbl = new QLabel("Z:", aPosGrp);  
202   myZPosLbl = new QLabel("0", aPosGrp);
203
204   QGroupBox* aSizeGrp = new QGroupBox(2, Qt::Horizontal, "Size", myActorsPane);
205   aSizeGrp->layout()->setSpacing(6);
206   QLabel* aXSizeLbl = new QLabel("dX:", aSizeGrp);
207   myDXLbl = new QLabel("0", aSizeGrp);
208   QLabel* aYSizeLbl = new QLabel("dY:", aSizeGrp);
209   myDYLbl = new QLabel("0", aSizeGrp);
210   QLabel* aZSizeLbl = new QLabel("dZ:",aSizeGrp );  
211   myDZLbl = new QLabel("0", aSizeGrp);
212
213   myWidgetStack->addWidget(myActorsPane, 2);
214
215
216   TopLayout->addWidget(myWidgetStack, 2, 0);
217
218   // Create buttons group
219   QHBox* aBtnBox = new QHBox(this);
220   QHBoxLayout* aBtnLayout = (QHBoxLayout*)aBtnBox->layout(); 
221   aBtnLayout->addStretch();
222
223   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
224   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
225   
226   TopLayout->addWidget(aBtnBox, 3, 0);
227
228   myStudy = visuGUI->GetActiveStudy();
229   mySelection = SALOME_Selection::Selection(myStudy->getSelection());
230   connect(mySelection, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionEvent()));
231
232   connect(visuGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(close()));
233
234   myFl = false;
235   onSelectionChange(0);
236
237   mySelectionDlg = this;
238 }
239
240
241 void VisuGUI_SelectionDlg::onSelectionChange(int theId) {
242   //  clearFields();
243   switch (theId) {
244   case 0: // Points
245     myWidgetStack->raiseWidget(myPointsPane);    
246     QAD_Application::getDesktop()->SetSelectionMode(NodeSelection, true);
247     onPointIdEdit(myIDValLbl->text());
248     break;
249   case 1: // Cells
250     myWidgetStack->raiseWidget(myCellsPane);
251     QAD_Application::getDesktop()->SetSelectionMode(CellSelection, true);
252     onCellIdEdit(myCellIDValLbl->text());
253     break;
254   case 2: // Actor
255     myWidgetStack->raiseWidget(myActorsPane);
256     QAD_Application::getDesktop()->SetSelectionMode(ActorSelection, true);  
257   }
258   onSelectionEvent();
259 //   if (VTKViewer_ViewFrame* vf = visuGUI->GetVtkViewFrame())
260 //     vf->Repaint();
261 }
262
263
264 void VisuGUI_SelectionDlg::closeEvent(QCloseEvent* theEvent) {
265   mySelectionDlg = NULL;
266   myStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame()->SetSelectionMode( ActorSelection );
267   QAD_Application::getDesktop()->SetSelectionMode(ActorSelection, true);
268   disconnect(mySelection,0,0,0);
269   QDialog::closeEvent(theEvent);
270 }
271
272 template<class TData> QString getValue(TData* theData, int theId){
273   if (vtkDataArray *aScalar = theData->GetScalars()){
274     float aVal = aScalar->GetTuple1(theId);
275     return QString::number(aVal);
276   } else {
277     return QString("No data");      
278   }
279 }
280
281 template<class TData> QString getVector(TData* theData, int theId){
282   if (vtkDataArray *aVector = theData->GetVectors()) {
283     float *aVal = aVector->GetTuple3(theId);
284     return QString("%1; %2; %3").arg(aVal[0]).arg(aVal[1]).arg(aVal[2]); 
285   } else {
286     return QString("No data");
287   }
288 }
289
290
291 #define ABS(a) (a>=0)?a:-a
292
293 void VisuGUI_SelectionDlg::onSelectionEvent() {
294   if (myFl) return;
295   myFl = true;  
296   Handle(SALOME_InteractiveObject) anIO;
297   int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
298   if(VISU::Prs3d_i* aPrs3d = visuGUI->GetSelectedPrs3d(&anIO)){
299     SALOMEDS::SObject_var aSObject = visuGUI->GetStudyDocument()->FindObjectID(anIO->getEntry());
300     QString aMeshName = VisuGUI::getValue(aSObject, "myMeshName");
301     QString aFieldName = VisuGUI::getValue(aSObject, "myFieldName");
302     myMeshName->setText((aMeshName == "NULL")? QString("No name") : aMeshName);
303     myFieldName->setText((aFieldName == "NULL")? QString("No name") : aFieldName);
304     
305     VISU_Actor* anVISUActor = visuGUI->GetActor(aPrs3d);
306     if (anVISUActor) {
307       float aCoord[6];
308       anVISUActor->GetBounds(aCoord);
309       myXPosLbl->setText(QString::number( aCoord[0] ));
310       myYPosLbl->setText(QString::number( aCoord[2] ));
311       myZPosLbl->setText(QString::number( aCoord[4] ));
312       
313       myDXLbl->setText(QString::number( ABS(aCoord[1]-aCoord[0]) ));
314       myDYLbl->setText(QString::number( ABS(aCoord[3]-aCoord[2]) ));
315       myDZLbl->setText(QString::number( ABS(aCoord[5]-aCoord[4]) ));
316     }
317
318     TColStd_IndexedMapOfInteger aMapIndex;
319     typedef map<int,float*> PointsMap;
320     PointsMap aPointsMap;
321     mySelection->GetIndex(anIO, aMapIndex);
322     
323     VISU_Actor* anActor = visuGUI->GetActor(aPrs3d);  
324     if(!anActor)
325       return;
326     vtkDataSet* aDataSet = anActor->GetInput();
327     vtkPointData* aPntData = aDataSet->GetPointData();
328
329     for ( int ind = 1; ind <= aMapIndex.Extent(); ind++){
330       int aID = aMapIndex( ind );
331       
332       switch (aType) {
333       case 0:
334         {
335           float aCoord[3];
336           aDataSet->GetPoint(aID, aCoord);
337           myXValLbl->setText( QString::number( aCoord[0] ) );
338           myYValLbl->setText( QString::number( aCoord[1] ) );
339           myZValLbl->setText( QString::number( aCoord[2] ) );
340           myIDValLbl->setText( QString::number(aID) );
341           myScalarValLbl->setText(getValue(aPntData, aID));
342           myVectorValLbl->setText(getVector(aPntData, aID));
343           //      adjustSize();
344           //qApp->processEvents();
345         }
346         break;
347       case 1:
348         {
349           //int aMaxId = aDataSet->GetNumberOfCells();
350           //cout<<"### MaxId="<<aMaxId<<endl;
351           //cout<<"### SelectedId="<<aID<<endl;
352           vtkCellData* aData = aDataSet->GetCellData();
353           vtkCell* aCell = aDataSet->GetCell(aID);
354           if (aCell != NULL) {
355             int aNbOfPoints = aCell->GetNumberOfPoints();
356             if (aNbOfPoints <=1 ) { // Cell is point
357               clearFields();
358             }
359             else {
360               myCellIDValLbl->setText( QString::number(aID) );
361               myCellScalarValLbl->setText(getValue(aData, aID));
362               myCellVectorValLbl->setText(getVector(aData, aID));
363           
364               float* aCoord;
365               vtkIdList *aPointList = aCell->GetPointIds();
366               QListViewItem* anItem = NULL;
367          
368               for(int i = 0; i < aNbOfPoints; i++){
369                 int idCurrent = aPointList->GetId(i);
370                 aCoord = aDataSet->GetPoint(idCurrent);
371                 aPointsMap.insert(PointsMap::value_type(idCurrent,aCoord));
372               }
373             }
374           }
375         }
376         break;
377       }
378     }
379
380     myListPoints->setNumRows(aPointsMap.size());
381     PointsMap::const_iterator It = aPointsMap.begin();
382     for(int i=0; It!=aPointsMap.end()&&i<myListPoints->numRows() ; It++,i++){
383       myListPoints->verticalHeader()->setLabel(i, QString::number( i ));
384       int id = It->first;
385       myListPoints->setText(i, 0, QString::number( id ));
386       float* aCoord = It->second;
387       myListPoints->setText(i, 1, QString::number( aCoord[0] ));
388       myListPoints->setText(i, 2, QString::number( aCoord[1] ));
389       myListPoints->setText(i, 3, QString::number( aCoord[2] ));
390       myListPoints->setText(i, 4, getValue(aPntData, id));
391       myListPoints->setText(i, 5, getVector(aPntData, id));
392     }
393     
394   } else {
395     clearFields();
396   }
397   myFl = false;
398 }
399 #undef ABS
400
401
402 void VisuGUI_SelectionDlg::clearFields() {
403   int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
404   switch (aType) {
405   case 0:
406     myXValLbl->setText( "" );
407     myYValLbl->setText( "" );
408     myZValLbl->setText( "" );
409     myIDValLbl->setText( "" );
410     myScalarValLbl->setText("");
411     myVectorValLbl->setText("");
412     break;
413   case 1:
414     myCellIDValLbl->setText( "" );
415     myCellScalarValLbl->setText("");
416     myCellVectorValLbl->setText("");
417     myListPoints->setNumRows(0);
418     break;
419   case 2:
420     myXPosLbl->setText("");
421     myYPosLbl->setText("");
422     myZPosLbl->setText("");      
423     myDXLbl->setText("");
424     myDYLbl->setText("");
425     myDZLbl->setText("");
426   }
427 }
428
429 typedef  vtkIdType (vtkDataSet::* TDataSetMethod)();
430
431 bool onIdEdit(const QString& theText, 
432               TDataSetMethod theMethod, 
433               bool theIsCell,
434               SALOME_Selection* theSelection, 
435               QLabel* theMeshName, 
436               QString theValue,
437               QLabel* theFieldName)
438 {
439   Handle(SALOME_InteractiveObject) anIO;
440   if(VISU::Prs3d_i* aPrs3d = visuGUI->GetSelectedPrs3d(&anIO)){
441     int anId = theText.toInt();
442     vtkDataSet* aDataSet = aPrs3d->GetPL()->GetMapper()->GetInput();
443     int aMaxId = (aDataSet->*theMethod)();
444     if(anId < 0) anId = 0;
445     if(anId >= aMaxId) anId = aMaxId-1;
446     theSelection->ClearIObjects();
447     theSelection->AddIObject(anIO);
448     theSelection->AddOrRemoveIndex( anIO, anId, false );
449     return true;
450   }else{
451     theMeshName->setText(theValue);
452     theFieldName->setText("");
453   }
454   return false;
455 }
456
457 void VisuGUI_SelectionDlg::onPointIdEdit(const QString& theText){
458   if (myFl) return;
459   TDataSetMethod aMethod = &vtkDataSet::GetNumberOfPoints;
460   bool anIsSelected = onIdEdit(theText,aMethod,false,mySelection,
461                                myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
462                                myFieldName);
463   if(!anIsSelected)
464     clearFields();
465 }
466
467 void VisuGUI_SelectionDlg::onCellIdEdit(const QString& theText){
468   if (myFl) return;
469   TDataSetMethod aMethod = &vtkDataSet::GetNumberOfCells;
470   bool anIsSelected = onIdEdit(theText,aMethod,true,mySelection,
471                                myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
472                                myFieldName);
473   if(!anIsSelected)
474     clearFields();
475 }