1 // VISU VISUGUI : GUI of VISU component
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : VisuGUI_Selection.cxx
25 // Author : Laurent CORNABE & Hubert ROLLAND
29 #include "VisuGUI_Selection.h"
32 #include "VisuGUI_Tools.h"
34 #include "VISU_Actor.h"
35 #include "VISU_PrsObject_i.hh"
36 #include "VISU_Prs3d_i.hh"
37 #include "VISU_PipeLine.hxx"
39 #include "SalomeApp_Study.h"
40 #include "SalomeApp_Application.h"
41 #include "SalomeApp_SelectionMgr.h"
42 #include "SalomeApp_VTKSelector.h"
44 #include "SUIT_MessageBox.h"
45 #include "SUIT_ViewWindow.h"
46 #include "SUIT_Session.h"
48 #include "SALOME_ListIO.hxx"
49 #include "SALOME_ListIteratorOfListIO.hxx"
51 #include "SVTK_ViewWindow.h"
52 #include "SVTK_ViewModel.h"
53 #include "SVTK_Selector.h"
55 #include "utilities.h"
58 #include <TColStd_IndexedMapOfInteger.hxx>
59 #include <TColStd_MapOfInteger.hxx>
67 #include <qhbuttongroup.h>
68 #include <qradiobutton.h>
69 #include <qvalidator.h>
70 #include <qpushbutton.h>
71 #include <qwidgetstack.h>
73 #include <qgroupbox.h>
74 #include <qlineedit.h>
75 #include <qvalidator.h>
77 #include <qlistview.h>
80 #include <vtkDataSetMapper.h>
81 #include <vtkDataSet.h>
82 #include <vtkPointData.h>
83 #include <vtkCellData.h>
91 static VisuGUI_SelectionDlg* mySelectionDlg = NULL;
93 VisuGUI_SelectionDlg::VisuGUI_SelectionDlg (QWidget* parent)
94 : QDialog(parent, 0, false, WStyle_Customize | WStyle_NormalBorder |
95 WStyle_Title | WStyle_SysMenu | WDestructiveClose),
99 mySelectionDlg->close(true);
101 setCaption( "Data on elements" );
102 setSizeGripEnabled( TRUE );
104 QGridLayout* TopLayout = new QGridLayout(this);
105 TopLayout->setSpacing(6);
106 TopLayout->setMargin(11);
107 TopLayout->setRowStretch(0, 0);
108 TopLayout->setRowStretch(1, 0);
109 TopLayout->setRowStretch(2, 1);
110 TopLayout->setRowStretch(3, 0);
112 QHButtonGroup* aTypeBox = new QHButtonGroup("Selection", this);
114 QRadioButton* aPointBtn = new QRadioButton("Point", aTypeBox);
115 QRadioButton* aCellBtn = new QRadioButton("Cell", aTypeBox);
116 QRadioButton* aActorBtn = new QRadioButton("Actor", aTypeBox);
117 aPointBtn->setChecked(true);
119 connect(aTypeBox, SIGNAL(clicked(int)), this, SLOT(onSelectionChange(int)));
121 TopLayout->addWidget(aTypeBox, 0, 0);
123 QWidget* aNamePane = new QWidget(this);
124 QGridLayout* aNameLay = new QGridLayout(aNamePane);
126 QLabel* aMeshLbl = new QLabel("Mesh name: ", aNamePane);
127 myMeshName = new QLabel(aNamePane);
129 QLabel* aFieldLbl = new QLabel("Field name: ", aNamePane);
130 myFieldName = new QLabel(aNamePane);
132 aNameLay->addWidget(aMeshLbl, 0, 0);
133 aNameLay->addWidget(myMeshName, 0, 1);
134 aNameLay->addWidget(aFieldLbl, 1, 0);
135 aNameLay->addWidget(myFieldName, 1, 1);
137 TopLayout->addWidget(aNamePane, 1, 0);
139 myWidgetStack = new QWidgetStack(this);
141 // Create Points pane
142 myPointsPane = new QVBox(myWidgetStack);
143 myPointsPane->layout()->setSpacing(6);
145 QGroupBox* aDataGrp = new QGroupBox(2, Qt::Horizontal, "Data of Point", myPointsPane);
146 aDataGrp->layout()->setSpacing(6);
148 QLabel* aIDLbl = new QLabel("ID:", aDataGrp);
149 myIDValLbl = new QLineEdit("", aDataGrp);
150 QIntValidator* aIntValidator = new QIntValidator(myIDValLbl);
151 aIntValidator->setBottom(0);
152 myIDValLbl->setValidator(aIntValidator);
153 connect(myIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onPointIdEdit(const QString&)));
155 QLabel* aValueLbl = new QLabel("Scalar Value:", aDataGrp);
156 myScalarValLbl = new QLabel("", aDataGrp);
157 QLabel* aVectorLbl = new QLabel("Vector Value:", aDataGrp);
158 myVectorValLbl = new QLabel("", aDataGrp);
159 myVectorValLbl->setMinimumWidth(150);
161 QGroupBox* aCoordGrp = new QGroupBox(2, Qt::Horizontal, "Coordinates", myPointsPane);
162 aCoordGrp->layout()->setSpacing(6);
163 QLabel* aXLbl = new QLabel("X:", aCoordGrp);
164 myXValLbl = new QLabel("", aCoordGrp);
165 QLabel* aYLbl = new QLabel("Y:", aCoordGrp);
166 myYValLbl = new QLabel("", aCoordGrp);
167 QLabel* aZLbl = new QLabel("Z:",aCoordGrp );
168 myZValLbl = new QLabel("", aCoordGrp);
171 myWidgetStack->addWidget(myPointsPane, 0);
174 myCellsPane = new QWidget(myWidgetStack);
175 QGridLayout* aCellLayout = new QGridLayout(myCellsPane);
176 aCellLayout->setSpacing(6);
177 aCellLayout->setRowStretch(0, 0);
178 aCellLayout->setRowStretch(1, 1);
180 QGroupBox* aCellGrp = new QGroupBox(2, Qt::Horizontal, "Data of Cell", myCellsPane);
182 QLabel* aCellIDLbl = new QLabel("ID:", aCellGrp);
183 myCellIDValLbl = new QLineEdit("", aCellGrp);
184 myCellIDValLbl->setValidator(aIntValidator);
185 connect(myCellIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onCellIdEdit(const QString&)));
187 QLabel* aCellValueLbl = new QLabel("Scalar Value:", aCellGrp);
188 myCellScalarValLbl = new QLabel("", aCellGrp);
189 QLabel* aCellVectorLbl = new QLabel("Vector Value:", aCellGrp);
190 myCellVectorValLbl = new QLabel("", aCellGrp);
192 aCellLayout->addWidget(aCellGrp, 0, 0);
194 myListPoints = new QTable(myCellsPane);
195 myListPoints->setReadOnly(true);
196 myListPoints->setNumCols(6);
197 myListPoints->setNumRows(0);
198 myListPoints->setColumnWidth(0, 40);
199 myListPoints->setColumnWidth(1, 40);
200 myListPoints->setColumnWidth(2, 40);
201 myListPoints->setColumnWidth(3, 40);
202 myListPoints->setSelectionMode(QTable::NoSelection);
203 QHeader* aHeader = myListPoints->horizontalHeader();
204 aHeader->setLabel( 0, "ID" );
205 aHeader->setLabel( 1, "X" );
206 aHeader->setLabel( 2, "Y" );
207 aHeader->setLabel( 3, "Z" );
208 aHeader->setLabel( 4, "Scalar" );
209 aHeader->setLabel( 5, "Vector" );
211 aCellLayout->addWidget(myListPoints, 1, 0);
213 myWidgetStack->addWidget(myCellsPane, 1);
216 myActorsPane = new QVBox(myWidgetStack);
217 myActorsPane->layout()->setSpacing(6);
219 QGroupBox* aPosGrp = new QGroupBox(2, Qt::Horizontal, "Position", myActorsPane);
220 aPosGrp->layout()->setSpacing(6);
221 QLabel* aXPosLbl = new QLabel("X:", aPosGrp);
222 myXPosLbl = new QLabel("0", aPosGrp);
223 QLabel* aYPosLbl = new QLabel("Y:", aPosGrp);
224 myYPosLbl = new QLabel("0", aPosGrp);
225 QLabel* aZPosLbl = new QLabel("Z:", aPosGrp);
226 myZPosLbl = new QLabel("0", aPosGrp);
228 QGroupBox* aSizeGrp = new QGroupBox(2, Qt::Horizontal, "Size", myActorsPane);
229 aSizeGrp->layout()->setSpacing(6);
230 QLabel* aXSizeLbl = new QLabel("dX:", aSizeGrp);
231 myDXLbl = new QLabel("0", aSizeGrp);
232 QLabel* aYSizeLbl = new QLabel("dY:", aSizeGrp);
233 myDYLbl = new QLabel("0", aSizeGrp);
234 QLabel* aZSizeLbl = new QLabel("dZ:",aSizeGrp );
235 myDZLbl = new QLabel("0", aSizeGrp);
237 myWidgetStack->addWidget(myActorsPane, 2);
240 TopLayout->addWidget(myWidgetStack, 2, 0);
242 // Create buttons group
243 QHBox* aBtnBox = new QHBox(this);
244 QHBoxLayout* aBtnLayout = (QHBoxLayout*)aBtnBox->layout();
245 aBtnLayout->addStretch();
247 QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
248 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
250 TopLayout->addWidget(aBtnBox, 3, 0);
252 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
253 (SUIT_Session::session()->activeApplication());
254 mySelectionMgr = anApp->selectionMgr();
255 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionEvent()));
257 //connect(visuGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(close()));
261 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
262 // Activate Points pane
263 myWidgetStack->raiseWidget(myPointsPane);
265 aSVTKVW->SetSelectionMode(NodeSelection);
268 mySelectionDlg = this;
271 VisuGUI_SelectionDlg::~VisuGUI_SelectionDlg()
275 void VisuGUI_SelectionDlg::onSelectionChange (int theId)
277 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
278 if (!aSVTKVW) return;
282 myWidgetStack->raiseWidget(myPointsPane);
283 aSVTKVW->SetSelectionMode(NodeSelection);
284 onPointIdEdit(myIDValLbl->text());
287 myWidgetStack->raiseWidget(myCellsPane);
288 aSVTKVW->SetSelectionMode(CellSelection);
289 onCellIdEdit(myCellIDValLbl->text());
292 myWidgetStack->raiseWidget(myActorsPane);
293 aSVTKVW->SetSelectionMode(ActorSelection);
299 void VisuGUI_SelectionDlg::closeEvent (QCloseEvent* theEvent)
301 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
303 mySelectionDlg = NULL;
305 aSVTKVW->SetSelectionMode(ActorSelection);
306 disconnect(mySelectionMgr,0,0,0);
307 QDialog::closeEvent(theEvent);
310 template<class TData> QString getValue(TData* theData, int theId){
311 if (vtkDataArray *aScalar = theData->GetScalars()){
312 float aVal = aScalar->GetTuple1(theId);
313 return QString::number(aVal);
315 return QString("No data");
319 template<class TData> QString getVector(TData* theData, int theId){
320 if (vtkDataArray *aVector = theData->GetVectors()) {
321 float *aVal = aVector->GetTuple3(theId);
322 return QString("%1; %2; %3").arg(aVal[0]).arg(aVal[1]).arg(aVal[2]);
324 return QString("No data");
328 #define ABS(a) (a>=0)?a:-a
330 void VisuGUI_SelectionDlg::onSelectionEvent() {
333 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
335 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
336 (SUIT_Session::session()->activeApplication());
338 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
339 if (!aSVTKVW) return;
340 SVTK_Selector* aSelector = aSVTKVW->GetSelector();
342 VISU::Prs3d_i* aPrs3d = NULL;
343 _PTR(SObject) aSObject;
344 Handle(SALOME_InteractiveObject) anIO;
346 SALOME_ListIO aListIO;
347 mySelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
349 if (aListIO.Extent() == 1) {
350 anIO = aListIO.First();
352 if (anIO->hasEntry()) {
353 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
354 _PTR(Study) aStudy = theStudy->studyDS();
355 aSObject = aStudy->FindObjectID(anIO->getEntry());
358 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
360 if (!CORBA::is_nil(anObject)) {
361 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
364 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
372 VISU::Storable::TRestoringMap aMap;
374 _PTR(GenericAttribute) anAttr;
375 if (aSObject->FindAttribute(anAttr, "AttributeComment")) {
376 _PTR(AttributeComment) aComment (anAttr);
377 std::string aString = aComment->Value();
378 QString strIn( aString.c_str() );
379 VISU::Storable::StrToMap(strIn, aMap);
383 QString aMeshName("NULL"), aFieldName("NULL");
385 aMeshName = VISU::Storable::FindValue(aMap, "myMeshName");
386 aFieldName = VISU::Storable::FindValue(aMap, "myFieldName");
389 myMeshName ->setText((aMeshName == "NULL") ? QString("No name") : aMeshName);
390 myFieldName->setText((aFieldName == "NULL") ? QString("No name") : aFieldName);
392 VISU_Actor* anVISUActor =
393 VISU::FindActor(aSVTKVW, aSObject->GetID().c_str());
396 anVISUActor->GetBounds(aCoord);
397 myXPosLbl->setText(QString::number( aCoord[0] ));
398 myYPosLbl->setText(QString::number( aCoord[2] ));
399 myZPosLbl->setText(QString::number( aCoord[4] ));
401 myDXLbl->setText(QString::number( ABS(aCoord[1]-aCoord[0]) ));
402 myDYLbl->setText(QString::number( ABS(aCoord[3]-aCoord[2]) ));
403 myDZLbl->setText(QString::number( ABS(aCoord[5]-aCoord[4]) ));
405 TColStd_IndexedMapOfInteger aMapIndex;
406 typedef map<int,float*> PointsMap;
407 PointsMap aPointsMap;
409 aSelector->GetIndex(anIO, aMapIndex);
411 vtkDataSet* aDataSet = anVISUActor->GetInput();
412 vtkPointData* aPntData = aDataSet->GetPointData();
414 for (int ind = 1; ind <= aMapIndex.Extent(); ind++) {
415 int aID = aMapIndex(ind);
421 aDataSet->GetPoint(aID, aCoord);
422 myXValLbl->setText( QString::number( aCoord[0] ) );
423 myYValLbl->setText( QString::number( aCoord[1] ) );
424 myZValLbl->setText( QString::number( aCoord[2] ) );
425 myIDValLbl->setText( QString::number(aID) );
426 myScalarValLbl->setText(getValue(aPntData, aID));
427 myVectorValLbl->setText(getVector(aPntData, aID));
432 vtkCellData* aData = aDataSet->GetCellData();
433 vtkCell* aCell = aDataSet->GetCell(aID);
435 int aNbOfPoints = aCell->GetNumberOfPoints();
436 if (aNbOfPoints <=1 ) { // Cell is point
439 myCellIDValLbl->setText( QString::number(aID) );
440 myCellScalarValLbl->setText(getValue(aData, aID));
441 myCellVectorValLbl->setText(getVector(aData, aID));
444 vtkIdList *aPointList = aCell->GetPointIds();
445 QListViewItem* anItem = NULL;
447 for (int i = 0; i < aNbOfPoints; i++) {
448 int idCurrent = aPointList->GetId(i);
449 aCoord = aDataSet->GetPoint(idCurrent);
450 aPointsMap.insert(PointsMap::value_type(idCurrent,aCoord));
459 myListPoints->setNumRows(aPointsMap.size());
460 PointsMap::const_iterator It = aPointsMap.begin();
461 for (int i = 0; It != aPointsMap.end() && i < myListPoints->numRows(); It++, i++) {
462 myListPoints->verticalHeader()->setLabel(i, QString::number( i ));
464 myListPoints->setText(i, 0, QString::number( id ));
465 float* aCoord = It->second;
466 myListPoints->setText(i, 1, QString::number( aCoord[0] ));
467 myListPoints->setText(i, 2, QString::number( aCoord[1] ));
468 myListPoints->setText(i, 3, QString::number( aCoord[2] ));
469 myListPoints->setText(i, 4, getValue(aPntData, id));
470 myListPoints->setText(i, 5, getVector(aPntData, id));
481 void VisuGUI_SelectionDlg::clearFields() {
482 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
485 myXValLbl->setText( "" );
486 myYValLbl->setText( "" );
487 myZValLbl->setText( "" );
488 myIDValLbl->setText( "" );
489 myScalarValLbl->setText("");
490 myVectorValLbl->setText("");
493 myCellIDValLbl->setText( "" );
494 myCellScalarValLbl->setText("");
495 myCellVectorValLbl->setText("");
496 myListPoints->setNumRows(0);
499 myXPosLbl->setText("");
500 myYPosLbl->setText("");
501 myZPosLbl->setText("");
502 myDXLbl->setText("");
503 myDYLbl->setText("");
504 myDZLbl->setText("");
508 typedef vtkIdType (vtkDataSet::* TDataSetMethod)();
510 bool onIdEdit (const QString& theText,
511 TDataSetMethod theMethod,
513 SalomeApp_SelectionMgr* theSelectionMgr,
516 QLabel* theFieldName)
518 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
519 (SUIT_Session::session()->activeApplication());
520 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
521 if (!aSVTKVW) return false;
522 SVTK_Selector* aSelector = aSVTKVW->GetSelector();
524 VISU::Prs3d_i* aPrs3d = NULL;
525 Handle(SALOME_InteractiveObject) anIO;
527 SALOME_ListIO aListIO;
528 theSelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
530 if (aListIO.Extent() == 1) {
531 anIO = aListIO.First();
533 if (anIO->hasEntry()) {
534 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
535 _PTR(Study) aStudy = theStudy->studyDS();
536 _PTR(SObject) aSObject = aStudy->FindObjectID(anIO->getEntry());
539 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
541 if (!CORBA::is_nil(anObject)) {
542 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
545 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
553 int anId = theText.toInt();
554 vtkDataSet* aDataSet = aPrs3d->GetPL()->GetMapper()->GetInput();
555 int aMaxId = (aDataSet->*theMethod)();
556 if (anId < 0) anId = 0;
557 if (anId >= aMaxId) anId = aMaxId - 1;
559 TColStd_MapOfInteger newIndices;
560 newIndices.Add(anId);
561 aSelector->AddOrRemoveIndex(anIO, newIndices, false);
562 aSVTKVW->highlight(anIO, true, true);
567 theMeshName->setText(theValue);
568 theFieldName->setText("");
573 void VisuGUI_SelectionDlg::onPointIdEdit (const QString& theText)
576 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfPoints;
577 bool anIsSelected = onIdEdit(theText,aMethod,false,mySelectionMgr,
578 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
584 void VisuGUI_SelectionDlg::onCellIdEdit (const QString& theText)
587 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfCells;
588 bool anIsSelected = onIdEdit(theText,aMethod,true,mySelectionMgr,
589 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),