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 //onSelectionChange(0);
262 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
263 // Activate Points pane
264 myWidgetStack->raiseWidget(myPointsPane);
265 aSVTKVW->SetSelectionMode(NodeSelection);
266 //onPointIdEdit(myIDValLbl->text());
269 mySelectionDlg = this;
272 VisuGUI_SelectionDlg::~VisuGUI_SelectionDlg()
276 void VisuGUI_SelectionDlg::onSelectionChange (int theId)
278 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
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;
304 aSVTKVW->SetSelectionMode(ActorSelection);
305 disconnect(mySelectionMgr,0,0,0);
306 QDialog::closeEvent(theEvent);
309 template<class TData> QString getValue(TData* theData, int theId){
310 if (vtkDataArray *aScalar = theData->GetScalars()){
311 float aVal = aScalar->GetTuple1(theId);
312 return QString::number(aVal);
314 return QString("No data");
318 template<class TData> QString getVector(TData* theData, int theId){
319 if (vtkDataArray *aVector = theData->GetVectors()) {
320 float *aVal = aVector->GetTuple3(theId);
321 return QString("%1; %2; %3").arg(aVal[0]).arg(aVal[1]).arg(aVal[2]);
323 return QString("No data");
327 #define ABS(a) (a>=0)?a:-a
329 void VisuGUI_SelectionDlg::onSelectionEvent() {
332 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
334 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
335 (SUIT_Session::session()->activeApplication());
337 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
338 SVTK_Selector* aSelector = aSVTKVW->GetSelector();
340 VISU::Prs3d_i* aPrs3d = NULL;
341 _PTR(SObject) aSObject;
342 Handle(SALOME_InteractiveObject) anIO;
344 SALOME_ListIO aListIO;
345 mySelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
347 if (aListIO.Extent() == 1) {
348 anIO = aListIO.First();
350 if (anIO->hasEntry()) {
351 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
352 _PTR(Study) aStudy = theStudy->studyDS();
353 aSObject = aStudy->FindObjectID(anIO->getEntry());
356 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
358 if (!CORBA::is_nil(anObject)) {
359 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
362 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
370 VISU::Storable::TRestoringMap aMap;
372 _PTR(GenericAttribute) anAttr;
373 if (aSObject->FindAttribute(anAttr, "AttributeComment")) {
374 _PTR(AttributeComment) aComment (anAttr);
375 std::string aString = aComment->Value();
376 QString strIn( aString.c_str() );
377 VISU::Storable::StrToMap(strIn, aMap);
381 QString aMeshName("NULL"), aFieldName("NULL");
383 aMeshName = VISU::Storable::FindValue(aMap, "myMeshName");
384 aFieldName = VISU::Storable::FindValue(aMap, "myFieldName");
387 myMeshName ->setText((aMeshName == "NULL") ? QString("No name") : aMeshName);
388 myFieldName->setText((aFieldName == "NULL") ? QString("No name") : aFieldName);
390 VISU_Actor* anVISUActor =
391 VISU::FindActor(aSVTKVW, aSObject->GetID().c_str());
394 anVISUActor->GetBounds(aCoord);
395 myXPosLbl->setText(QString::number( aCoord[0] ));
396 myYPosLbl->setText(QString::number( aCoord[2] ));
397 myZPosLbl->setText(QString::number( aCoord[4] ));
399 myDXLbl->setText(QString::number( ABS(aCoord[1]-aCoord[0]) ));
400 myDYLbl->setText(QString::number( ABS(aCoord[3]-aCoord[2]) ));
401 myDZLbl->setText(QString::number( ABS(aCoord[5]-aCoord[4]) ));
403 TColStd_IndexedMapOfInteger aMapIndex;
404 typedef map<int,float*> PointsMap;
405 PointsMap aPointsMap;
407 aSelector->GetIndex(anIO, aMapIndex);
409 vtkDataSet* aDataSet = anVISUActor->GetInput();
410 vtkPointData* aPntData = aDataSet->GetPointData();
412 for (int ind = 1; ind <= aMapIndex.Extent(); ind++) {
413 int aID = aMapIndex(ind);
419 aDataSet->GetPoint(aID, aCoord);
420 myXValLbl->setText( QString::number( aCoord[0] ) );
421 myYValLbl->setText( QString::number( aCoord[1] ) );
422 myZValLbl->setText( QString::number( aCoord[2] ) );
423 myIDValLbl->setText( QString::number(aID) );
424 myScalarValLbl->setText(getValue(aPntData, aID));
425 myVectorValLbl->setText(getVector(aPntData, aID));
430 vtkCellData* aData = aDataSet->GetCellData();
431 vtkCell* aCell = aDataSet->GetCell(aID);
433 int aNbOfPoints = aCell->GetNumberOfPoints();
434 if (aNbOfPoints <=1 ) { // Cell is point
437 myCellIDValLbl->setText( QString::number(aID) );
438 myCellScalarValLbl->setText(getValue(aData, aID));
439 myCellVectorValLbl->setText(getVector(aData, aID));
442 vtkIdList *aPointList = aCell->GetPointIds();
443 QListViewItem* anItem = NULL;
445 for (int i = 0; i < aNbOfPoints; i++) {
446 int idCurrent = aPointList->GetId(i);
447 aCoord = aDataSet->GetPoint(idCurrent);
448 aPointsMap.insert(PointsMap::value_type(idCurrent,aCoord));
457 myListPoints->setNumRows(aPointsMap.size());
458 PointsMap::const_iterator It = aPointsMap.begin();
459 for (int i = 0; It != aPointsMap.end() && i < myListPoints->numRows(); It++, i++) {
460 myListPoints->verticalHeader()->setLabel(i, QString::number( i ));
462 myListPoints->setText(i, 0, QString::number( id ));
463 float* aCoord = It->second;
464 myListPoints->setText(i, 1, QString::number( aCoord[0] ));
465 myListPoints->setText(i, 2, QString::number( aCoord[1] ));
466 myListPoints->setText(i, 3, QString::number( aCoord[2] ));
467 myListPoints->setText(i, 4, getValue(aPntData, id));
468 myListPoints->setText(i, 5, getVector(aPntData, id));
479 void VisuGUI_SelectionDlg::clearFields() {
480 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
483 myXValLbl->setText( "" );
484 myYValLbl->setText( "" );
485 myZValLbl->setText( "" );
486 myIDValLbl->setText( "" );
487 myScalarValLbl->setText("");
488 myVectorValLbl->setText("");
491 myCellIDValLbl->setText( "" );
492 myCellScalarValLbl->setText("");
493 myCellVectorValLbl->setText("");
494 myListPoints->setNumRows(0);
497 myXPosLbl->setText("");
498 myYPosLbl->setText("");
499 myZPosLbl->setText("");
500 myDXLbl->setText("");
501 myDYLbl->setText("");
502 myDZLbl->setText("");
506 typedef vtkIdType (vtkDataSet::* TDataSetMethod)();
508 bool onIdEdit (const QString& theText,
509 TDataSetMethod theMethod,
511 SalomeApp_SelectionMgr* theSelectionMgr,
514 QLabel* theFieldName)
516 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
517 (SUIT_Session::session()->activeApplication());
518 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
519 SVTK_Selector* aSelector = aSVTKVW->GetSelector();
521 VISU::Prs3d_i* aPrs3d = NULL;
522 Handle(SALOME_InteractiveObject) anIO;
524 SALOME_ListIO aListIO;
525 theSelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
527 if (aListIO.Extent() == 1) {
528 anIO = aListIO.First();
530 if (anIO->hasEntry()) {
531 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
532 _PTR(Study) aStudy = theStudy->studyDS();
533 _PTR(SObject) aSObject = aStudy->FindObjectID(anIO->getEntry());
536 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
538 if (!CORBA::is_nil(anObject)) {
539 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
542 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
550 int anId = theText.toInt();
551 vtkDataSet* aDataSet = aPrs3d->GetPL()->GetMapper()->GetInput();
552 int aMaxId = (aDataSet->*theMethod)();
553 if (anId < 0) anId = 0;
554 if (anId >= aMaxId) anId = aMaxId - 1;
556 TColStd_MapOfInteger newIndices;
557 newIndices.Add(anId);
558 aSelector->AddOrRemoveIndex(anIO, newIndices, false);
559 aSVTKVW->highlight(anIO, true, true);
564 theMeshName->setText(theValue);
565 theFieldName->setText("");
570 void VisuGUI_SelectionDlg::onPointIdEdit (const QString& theText)
573 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfPoints;
574 bool anIsSelected = onIdEdit(theText,aMethod,false,mySelectionMgr,
575 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
581 void VisuGUI_SelectionDlg::onCellIdEdit (const QString& theText)
584 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfCells;
585 bool anIsSelected = onIdEdit(theText,aMethod,true,mySelectionMgr,
586 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),