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