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 //extern VisuGUI *visuGUI;
92 static VisuGUI_SelectionDlg* mySelectionDlg = NULL;
94 VisuGUI_SelectionDlg::VisuGUI_SelectionDlg (QWidget* parent)
95 : QDialog(parent, 0, false, WStyle_Customize | WStyle_NormalBorder |
96 WStyle_Title | WStyle_SysMenu | WDestructiveClose),
99 //MESSAGE("VisuGUI_SelectionDlg::VisuGUI_SelectionDlg()");
101 mySelectionDlg->close(true);
103 setCaption( "Data on elements" );
104 setSizeGripEnabled( TRUE );
106 QGridLayout* TopLayout = new QGridLayout(this);
107 TopLayout->setSpacing(6);
108 TopLayout->setMargin(11);
109 TopLayout->setRowStretch(0, 0);
110 TopLayout->setRowStretch(1, 0);
111 TopLayout->setRowStretch(2, 1);
112 TopLayout->setRowStretch(3, 0);
114 QHButtonGroup* aTypeBox = new QHButtonGroup("Selection", this);
116 QRadioButton* aPointBtn = new QRadioButton("Point", aTypeBox);
117 QRadioButton* aCellBtn = new QRadioButton("Cell", aTypeBox);
118 QRadioButton* aActorBtn = new QRadioButton("Actor", aTypeBox);
119 aPointBtn->setChecked(true);
121 connect(aTypeBox, SIGNAL(clicked(int)), this, SLOT(onSelectionChange(int)));
123 TopLayout->addWidget(aTypeBox, 0, 0);
125 QWidget* aNamePane = new QWidget(this);
126 QGridLayout* aNameLay = new QGridLayout(aNamePane);
128 QLabel* aMeshLbl = new QLabel("Mesh name: ", aNamePane);
129 myMeshName = new QLabel(aNamePane);
131 QLabel* aFieldLbl = new QLabel("Field name: ", aNamePane);
132 myFieldName = new QLabel(aNamePane);
134 aNameLay->addWidget(aMeshLbl, 0, 0);
135 aNameLay->addWidget(myMeshName, 0, 1);
136 aNameLay->addWidget(aFieldLbl, 1, 0);
137 aNameLay->addWidget(myFieldName, 1, 1);
139 TopLayout->addWidget(aNamePane, 1, 0);
141 myWidgetStack = new QWidgetStack(this);
143 // Create Points pane
144 myPointsPane = new QVBox(myWidgetStack);
145 myPointsPane->layout()->setSpacing(6);
147 QGroupBox* aDataGrp = new QGroupBox(2, Qt::Horizontal, "Data of Point", myPointsPane);
148 aDataGrp->layout()->setSpacing(6);
150 QLabel* aIDLbl = new QLabel("ID:", aDataGrp);
151 myIDValLbl = new QLineEdit("", aDataGrp);
152 QIntValidator* aIntValidator = new QIntValidator(myIDValLbl);
153 aIntValidator->setBottom(0);
154 myIDValLbl->setValidator(aIntValidator);
155 connect(myIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onPointIdEdit(const QString&)));
157 QLabel* aValueLbl = new QLabel("Scalar Value:", aDataGrp);
158 myScalarValLbl = new QLabel("", aDataGrp);
159 QLabel* aVectorLbl = new QLabel("Vector Value:", aDataGrp);
160 myVectorValLbl = new QLabel("", aDataGrp);
161 myVectorValLbl->setMinimumWidth(150);
163 QGroupBox* aCoordGrp = new QGroupBox(2, Qt::Horizontal, "Coordinates", myPointsPane);
164 aCoordGrp->layout()->setSpacing(6);
165 QLabel* aXLbl = new QLabel("X:", aCoordGrp);
166 myXValLbl = new QLabel("", aCoordGrp);
167 QLabel* aYLbl = new QLabel("Y:", aCoordGrp);
168 myYValLbl = new QLabel("", aCoordGrp);
169 QLabel* aZLbl = new QLabel("Z:",aCoordGrp );
170 myZValLbl = new QLabel("", aCoordGrp);
173 myWidgetStack->addWidget(myPointsPane, 0);
176 myCellsPane = new QWidget(myWidgetStack);
177 QGridLayout* aCellLayout = new QGridLayout(myCellsPane);
178 aCellLayout->setSpacing(6);
179 aCellLayout->setRowStretch(0, 0);
180 aCellLayout->setRowStretch(1, 1);
182 QGroupBox* aCellGrp = new QGroupBox(2, Qt::Horizontal, "Data of Cell", myCellsPane);
184 QLabel* aCellIDLbl = new QLabel("ID:", aCellGrp);
185 myCellIDValLbl = new QLineEdit("", aCellGrp);
186 myCellIDValLbl->setValidator(aIntValidator);
187 connect(myCellIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onCellIdEdit(const QString&)));
189 QLabel* aCellValueLbl = new QLabel("Scalar Value:", aCellGrp);
190 myCellScalarValLbl = new QLabel("", aCellGrp);
191 QLabel* aCellVectorLbl = new QLabel("Vector Value:", aCellGrp);
192 myCellVectorValLbl = new QLabel("", aCellGrp);
194 aCellLayout->addWidget(aCellGrp, 0, 0);
196 myListPoints = new QTable(myCellsPane);
197 myListPoints->setReadOnly(true);
198 myListPoints->setNumCols(6);
199 myListPoints->setNumRows(0);
200 myListPoints->setColumnWidth(0, 40);
201 myListPoints->setColumnWidth(1, 40);
202 myListPoints->setColumnWidth(2, 40);
203 myListPoints->setColumnWidth(3, 40);
204 myListPoints->setSelectionMode(QTable::NoSelection);
205 QHeader* aHeader = myListPoints->horizontalHeader();
206 aHeader->setLabel( 0, "ID" );
207 aHeader->setLabel( 1, "X" );
208 aHeader->setLabel( 2, "Y" );
209 aHeader->setLabel( 3, "Z" );
210 aHeader->setLabel( 4, "Scalar" );
211 aHeader->setLabel( 5, "Vector" );
213 aCellLayout->addWidget(myListPoints, 1, 0);
215 myWidgetStack->addWidget(myCellsPane, 1);
218 myActorsPane = new QVBox(myWidgetStack);
219 myActorsPane->layout()->setSpacing(6);
221 QGroupBox* aPosGrp = new QGroupBox(2, Qt::Horizontal, "Position", myActorsPane);
222 aPosGrp->layout()->setSpacing(6);
223 QLabel* aXPosLbl = new QLabel("X:", aPosGrp);
224 myXPosLbl = new QLabel("0", aPosGrp);
225 QLabel* aYPosLbl = new QLabel("Y:", aPosGrp);
226 myYPosLbl = new QLabel("0", aPosGrp);
227 QLabel* aZPosLbl = new QLabel("Z:", aPosGrp);
228 myZPosLbl = new QLabel("0", aPosGrp);
230 QGroupBox* aSizeGrp = new QGroupBox(2, Qt::Horizontal, "Size", myActorsPane);
231 aSizeGrp->layout()->setSpacing(6);
232 QLabel* aXSizeLbl = new QLabel("dX:", aSizeGrp);
233 myDXLbl = new QLabel("0", aSizeGrp);
234 QLabel* aYSizeLbl = new QLabel("dY:", aSizeGrp);
235 myDYLbl = new QLabel("0", aSizeGrp);
236 QLabel* aZSizeLbl = new QLabel("dZ:",aSizeGrp );
237 myDZLbl = new QLabel("0", aSizeGrp);
239 myWidgetStack->addWidget(myActorsPane, 2);
242 TopLayout->addWidget(myWidgetStack, 2, 0);
244 // Create buttons group
245 QHBox* aBtnBox = new QHBox(this);
246 QHBoxLayout* aBtnLayout = (QHBoxLayout*)aBtnBox->layout();
247 aBtnLayout->addStretch();
249 QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
250 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
252 TopLayout->addWidget(aBtnBox, 3, 0);
254 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
255 (SUIT_Session::session()->activeApplication());
256 mySelectionMgr = anApp->selectionMgr();
257 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionEvent()));
259 //connect(visuGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(close()));
263 //onSelectionChange(0);
264 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
265 // Activate Points pane
266 myWidgetStack->raiseWidget(myPointsPane);
267 aSVTKVW->SetSelectionMode(NodeSelection);
268 //onPointIdEdit(myIDValLbl->text());
271 mySelectionDlg = this;
274 VisuGUI_SelectionDlg::~VisuGUI_SelectionDlg()
276 //MESSAGE("VisuGUI_SelectionDlg::~VisuGUI_SelectionDlg()");
279 void VisuGUI_SelectionDlg::onSelectionChange (int theId)
281 //MESSAGE("VisuGUI_SelectionDlg::onSelectionChange()");
282 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
286 myWidgetStack->raiseWidget(myPointsPane);
287 //mySelectionMgr->setSelectionModes(NodeSelection);
288 aSVTKVW->SetSelectionMode(NodeSelection);
289 onPointIdEdit(myIDValLbl->text());
292 myWidgetStack->raiseWidget(myCellsPane);
293 //mySelectionMgr->setSelectionModes(CellSelection);
294 aSVTKVW->SetSelectionMode(CellSelection);
295 onCellIdEdit(myCellIDValLbl->text());
298 myWidgetStack->raiseWidget(myActorsPane);
299 //mySelectionMgr->setSelectionModes(ActorSelection);
300 aSVTKVW->SetSelectionMode(ActorSelection);
306 void VisuGUI_SelectionDlg::closeEvent (QCloseEvent* theEvent)
308 //MESSAGE("VisuGUI_SelectionDlg::closeEvent()");
309 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
311 mySelectionDlg = NULL;
312 //mySelectionMgr->setSelectionModes(ActorSelection);
313 aSVTKVW->SetSelectionMode(ActorSelection);
314 disconnect(mySelectionMgr,0,0,0);
315 QDialog::closeEvent(theEvent);
318 template<class TData> QString getValue(TData* theData, int theId){
319 if (vtkDataArray *aScalar = theData->GetScalars()){
320 float aVal = aScalar->GetTuple1(theId);
321 return QString::number(aVal);
323 return QString("No data");
327 template<class TData> QString getVector(TData* theData, int theId){
328 if (vtkDataArray *aVector = theData->GetVectors()) {
329 float *aVal = aVector->GetTuple3(theId);
330 return QString("%1; %2; %3").arg(aVal[0]).arg(aVal[1]).arg(aVal[2]);
332 return QString("No data");
336 #define ABS(a) (a>=0)?a:-a
338 void VisuGUI_SelectionDlg::onSelectionEvent() {
339 //MESSAGE("VisuGUI_SelectionDlg::onSelectionEvent()");
342 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
344 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
345 (SUIT_Session::session()->activeApplication());
347 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
348 SVTK_Selector* aSelector = aSVTKVW->GetSelector();
350 VISU::Prs3d_i* aPrs3d = NULL;
351 _PTR(SObject) aSObject;
352 Handle(SALOME_InteractiveObject) anIO;
354 //SALOME_ListIO aListIO;
355 //mySelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
357 const SALOME_ListIO& aListIO = aSelector->StoredIObjects();
359 //MESSAGE("aListIO.Extent() = " << aListIO.Extent());
360 if (aListIO.Extent() == 1) {
361 anIO = aListIO.First();
363 if (anIO->hasEntry()) {
364 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
365 _PTR(Study) aStudy = theStudy->studyDS();
366 aSObject = aStudy->FindObjectID(anIO->getEntry());
367 //MESSAGE("anIO->hasEntry(): " << anIO->getEntry());
370 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
372 if (!CORBA::is_nil(anObject)) {
373 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
376 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
384 VISU::Storable::TRestoringMap aMap;
386 _PTR(GenericAttribute) anAttr;
387 if (aSObject->FindAttribute(anAttr, "AttributeComment")) {
388 _PTR(AttributeComment) aComment (anAttr);
389 std::string aString = aComment->Value();
390 QString strIn( aString.c_str() );
391 VISU::Storable::StrToMap(strIn, aMap);
395 QString aMeshName("NULL"), aFieldName("NULL");
397 aMeshName = VISU::Storable::FindValue(aMap, "myMeshName");
398 aFieldName = VISU::Storable::FindValue(aMap, "myFieldName");
401 myMeshName ->setText((aMeshName == "NULL") ? QString("No name") : aMeshName);
402 myFieldName->setText((aFieldName == "NULL") ? QString("No name") : aFieldName);
404 VISU_Actor* anVISUActor =
405 VISU::FindActor(aSVTKVW, aSObject->GetID().c_str());
408 anVISUActor->GetBounds(aCoord);
409 myXPosLbl->setText(QString::number( aCoord[0] ));
410 myYPosLbl->setText(QString::number( aCoord[2] ));
411 myZPosLbl->setText(QString::number( aCoord[4] ));
413 myDXLbl->setText(QString::number( ABS(aCoord[1]-aCoord[0]) ));
414 myDYLbl->setText(QString::number( ABS(aCoord[3]-aCoord[2]) ));
415 myDZLbl->setText(QString::number( ABS(aCoord[5]-aCoord[4]) ));
417 TColStd_IndexedMapOfInteger aMapIndex;
418 typedef map<int,float*> PointsMap;
419 PointsMap aPointsMap;
421 aSelector->GetIndex(anIO, aMapIndex);
423 vtkDataSet* aDataSet = anVISUActor->GetInput();
424 vtkPointData* aPntData = aDataSet->GetPointData();
426 for (int ind = 1; ind <= aMapIndex.Extent(); ind++) {
427 int aID = aMapIndex(ind);
433 aDataSet->GetPoint(aID, aCoord);
434 myXValLbl->setText( QString::number( aCoord[0] ) );
435 myYValLbl->setText( QString::number( aCoord[1] ) );
436 myZValLbl->setText( QString::number( aCoord[2] ) );
437 myIDValLbl->setText( QString::number(aID) );
438 myScalarValLbl->setText(getValue(aPntData, aID));
439 myVectorValLbl->setText(getVector(aPntData, aID));
444 vtkCellData* aData = aDataSet->GetCellData();
445 vtkCell* aCell = aDataSet->GetCell(aID);
447 int aNbOfPoints = aCell->GetNumberOfPoints();
448 if (aNbOfPoints <=1 ) { // Cell is point
451 myCellIDValLbl->setText( QString::number(aID) );
452 myCellScalarValLbl->setText(getValue(aData, aID));
453 myCellVectorValLbl->setText(getVector(aData, aID));
456 vtkIdList *aPointList = aCell->GetPointIds();
457 QListViewItem* anItem = NULL;
459 for (int i = 0; i < aNbOfPoints; i++) {
460 int idCurrent = aPointList->GetId(i);
461 aCoord = aDataSet->GetPoint(idCurrent);
462 aPointsMap.insert(PointsMap::value_type(idCurrent,aCoord));
471 myListPoints->setNumRows(aPointsMap.size());
472 PointsMap::const_iterator It = aPointsMap.begin();
473 for (int i = 0; It != aPointsMap.end() && i < myListPoints->numRows(); It++, i++) {
474 myListPoints->verticalHeader()->setLabel(i, QString::number( i ));
476 myListPoints->setText(i, 0, QString::number( id ));
477 float* aCoord = It->second;
478 myListPoints->setText(i, 1, QString::number( aCoord[0] ));
479 myListPoints->setText(i, 2, QString::number( aCoord[1] ));
480 myListPoints->setText(i, 3, QString::number( aCoord[2] ));
481 myListPoints->setText(i, 4, getValue(aPntData, id));
482 myListPoints->setText(i, 5, getVector(aPntData, id));
493 void VisuGUI_SelectionDlg::clearFields() {
494 //MESSAGE("VisuGUI_SelectionDlg::clearFields()");
495 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
498 myXValLbl->setText( "" );
499 myYValLbl->setText( "" );
500 myZValLbl->setText( "" );
501 myIDValLbl->setText( "" );
502 myScalarValLbl->setText("");
503 myVectorValLbl->setText("");
506 myCellIDValLbl->setText( "" );
507 myCellScalarValLbl->setText("");
508 myCellVectorValLbl->setText("");
509 myListPoints->setNumRows(0);
512 myXPosLbl->setText("");
513 myYPosLbl->setText("");
514 myZPosLbl->setText("");
515 myDXLbl->setText("");
516 myDYLbl->setText("");
517 myDZLbl->setText("");
521 typedef vtkIdType (vtkDataSet::* TDataSetMethod)();
523 bool onIdEdit (const QString& theText,
524 TDataSetMethod theMethod,
526 SalomeApp_SelectionMgr* theSelectionMgr,
529 QLabel* theFieldName)
531 //MESSAGE("onIdEdit()");
532 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
533 (SUIT_Session::session()->activeApplication());
534 SVTK_ViewWindow* aSVTKVW = VISU::GetViewWindow();
535 SVTK_Selector* aSelector = aSVTKVW->GetSelector();
537 VISU::Prs3d_i* aPrs3d = NULL;
538 Handle(SALOME_InteractiveObject) anIO;
540 //SALOME_ListIO aListIO;
541 //theSelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
543 const SALOME_ListIO& aListIO = aSelector->StoredIObjects();
545 if (aListIO.Extent() == 1) {
546 anIO = aListIO.First();
548 if (anIO->hasEntry()) {
549 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
550 _PTR(Study) aStudy = theStudy->studyDS();
551 _PTR(SObject) aSObject = aStudy->FindObjectID(anIO->getEntry());
554 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
556 if (!CORBA::is_nil(anObject)) {
557 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
560 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
568 int anId = theText.toInt();
569 vtkDataSet* aDataSet = aPrs3d->GetPL()->GetMapper()->GetInput();
570 int aMaxId = (aDataSet->*theMethod)();
571 if (anId < 0) anId = 0;
572 if (anId >= aMaxId) anId = aMaxId - 1;
576 //theSelectionMgr->setSelectedObjects(sel);
578 TColStd_MapOfInteger newIndices;
579 newIndices.Add(anId);
580 aSelector->AddOrRemoveIndex(anIO, newIndices, false);
581 aSVTKVW->highlight(anIO, true, true);
586 theMeshName->setText(theValue);
587 theFieldName->setText("");
592 void VisuGUI_SelectionDlg::onPointIdEdit (const QString& theText)
594 //MESSAGE("onPointIdEdit()");
596 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfPoints;
597 bool anIsSelected = onIdEdit(theText,aMethod,false,mySelectionMgr,
598 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
604 void VisuGUI_SelectionDlg::onCellIdEdit (const QString& theText)
606 //MESSAGE("onCellIdEdit()");
608 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfCells;
609 bool anIsSelected = onIdEdit(theText,aMethod,true,mySelectionMgr,
610 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),