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"
33 #include "VisuGUI_ViewTools.h"
35 #include "VISU_Actor.h"
36 #include "VISU_PrsObject_i.hh"
37 #include "VISU_Prs3d_i.hh"
38 #include "VISU_PipeLine.hxx"
40 #include "SalomeApp_Study.h"
41 #include "SalomeApp_Application.h"
42 #include "LightApp_SelectionMgr.h"
43 #include "LightApp_VTKSelector.h"
45 #include "SUIT_MessageBox.h"
46 #include "SUIT_ViewWindow.h"
47 #include "SUIT_Session.h"
49 #include "SALOME_ListIO.hxx"
50 #include "SALOME_ListIteratorOfListIO.hxx"
52 #include "SVTK_ViewWindow.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>
79 #include <vtkDataSetMapper.h>
80 #include <vtkDataSet.h>
81 #include <vtkPointData.h>
82 #include <vtkCellData.h>
90 static VisuGUI_SelectionDlg* mySelectionDlg = NULL;
92 VisuGUI_SelectionDlg::VisuGUI_SelectionDlg (const SalomeApp_Module* theModule):
93 QDialog(VISU::GetDesktop(theModule),
96 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
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 =
117 new QRadioButton ("Point", aTypeBox);
118 new QRadioButton ("Cell" , aTypeBox);
119 new QRadioButton ("Actor", aTypeBox);
120 aPointBtn->setChecked(true);
122 connect(aTypeBox, SIGNAL(clicked(int)), this, SLOT(onSelectionChange(int)));
124 TopLayout->addWidget(aTypeBox, 0, 0);
126 QWidget* aNamePane = new QWidget (this);
127 QGridLayout* aNameLay = new QGridLayout (aNamePane);
129 QLabel* aMeshLbl = new QLabel ("Mesh name: ", aNamePane);
130 myMeshName = new QLabel (aNamePane);
132 QLabel* aFieldLbl = new QLabel ("Field name: ", aNamePane);
133 myFieldName = new QLabel (aNamePane);
135 aNameLay->addWidget(aMeshLbl, 0, 0);
136 aNameLay->addWidget(myMeshName, 0, 1);
137 aNameLay->addWidget(aFieldLbl, 1, 0);
138 aNameLay->addWidget(myFieldName, 1, 1);
140 TopLayout->addWidget(aNamePane, 1, 0);
142 myWidgetStack = new QWidgetStack (this);
144 // Create Points pane
145 myPointsPane = new QVBox (myWidgetStack);
146 myPointsPane->layout()->setSpacing(6);
148 QGroupBox* aDataGrp = new QGroupBox (2, Qt::Horizontal, "Data of Point", myPointsPane);
149 aDataGrp->layout()->setSpacing(6);
151 new QLabel ("ID:", aDataGrp);
152 myIDValLbl = new QLineEdit ("", aDataGrp);
153 QIntValidator* aIntValidator = new QIntValidator (myIDValLbl);
154 aIntValidator->setBottom(0);
155 myIDValLbl->setValidator(aIntValidator);
156 connect(myIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onPointIdEdit(const QString&)));
158 new QLabel ("Scalar Value:", aDataGrp);
159 myScalarValLbl = new QLabel ("", aDataGrp);
160 new QLabel ("Vector Value:", aDataGrp);
161 myVectorValLbl = new QLabel ("", aDataGrp);
162 myVectorValLbl->setMinimumWidth(150);
164 QGroupBox* aCoordGrp = new QGroupBox (2, Qt::Horizontal, "Coordinates", myPointsPane);
165 aCoordGrp->layout()->setSpacing(6);
166 new QLabel ("X:", aCoordGrp);
167 myXValLbl = new QLabel ("", aCoordGrp);
168 new QLabel ("Y:", aCoordGrp);
169 myYValLbl = new QLabel ("", aCoordGrp);
170 new QLabel ("Z:",aCoordGrp );
171 myZValLbl = new QLabel ("", aCoordGrp);
174 myWidgetStack->addWidget(myPointsPane, 0);
177 myCellsPane = new QWidget (myWidgetStack);
178 QGridLayout* aCellLayout = new QGridLayout (myCellsPane);
179 aCellLayout->setSpacing(6);
180 aCellLayout->setRowStretch(0, 0);
181 aCellLayout->setRowStretch(1, 1);
183 QGroupBox* aCellGrp = new QGroupBox(2, Qt::Horizontal, "Data of Cell", myCellsPane);
185 new QLabel ("ID:", aCellGrp);
186 myCellIDValLbl = new QLineEdit ("", aCellGrp);
187 myCellIDValLbl->setValidator(aIntValidator);
188 connect(myCellIDValLbl, SIGNAL(textChanged(const QString&)), this, SLOT(onCellIdEdit(const QString&)));
190 new QLabel ("Scalar Value:", aCellGrp);
191 myCellScalarValLbl = new QLabel ("", aCellGrp);
192 new QLabel ("Vector Value:", aCellGrp);
193 myCellVectorValLbl = new QLabel ("", aCellGrp);
195 aCellLayout->addWidget(aCellGrp, 0, 0);
197 myListPoints = new QTable (myCellsPane);
198 myListPoints->setReadOnly(true);
199 myListPoints->setNumCols(6);
200 myListPoints->setNumRows(0);
201 myListPoints->setColumnWidth(0, 40);
202 myListPoints->setColumnWidth(1, 40);
203 myListPoints->setColumnWidth(2, 40);
204 myListPoints->setColumnWidth(3, 40);
205 myListPoints->setSelectionMode(QTable::NoSelection);
206 QHeader* aHeader = myListPoints->horizontalHeader();
207 aHeader->setLabel( 0, "ID" );
208 aHeader->setLabel( 1, "X" );
209 aHeader->setLabel( 2, "Y" );
210 aHeader->setLabel( 3, "Z" );
211 aHeader->setLabel( 4, "Scalar" );
212 aHeader->setLabel( 5, "Vector" );
214 aCellLayout->addWidget(myListPoints, 1, 0);
216 myWidgetStack->addWidget(myCellsPane, 1);
219 myActorsPane = new QVBox (myWidgetStack);
220 myActorsPane->layout()->setSpacing(6);
222 QGroupBox* aPosGrp = new QGroupBox (2, Qt::Horizontal, "Position", myActorsPane);
223 aPosGrp->layout()->setSpacing(6);
224 new QLabel ("X:", aPosGrp);
225 myXPosLbl = new QLabel ("0", aPosGrp);
226 new QLabel ("Y:", aPosGrp);
227 myYPosLbl = new QLabel ("0", aPosGrp);
228 new QLabel ("Z:", aPosGrp);
229 myZPosLbl = new QLabel ("0", aPosGrp);
231 QGroupBox* aSizeGrp = new QGroupBox (2, Qt::Horizontal, "Size", myActorsPane);
232 aSizeGrp->layout()->setSpacing(6);
233 new QLabel ("dX:", aSizeGrp);
234 myDXLbl = new QLabel ("0", aSizeGrp);
235 new QLabel ("dY:", aSizeGrp);
236 myDYLbl = new QLabel ("0", aSizeGrp);
237 new QLabel ("dZ:",aSizeGrp );
238 myDZLbl = new QLabel ("0", aSizeGrp);
240 myWidgetStack->addWidget(myActorsPane, 2);
243 TopLayout->addWidget(myWidgetStack, 2, 0);
245 // Create buttons group
246 QHBox* aBtnBox = new QHBox (this);
247 QHBoxLayout* aBtnLayout = (QHBoxLayout*)aBtnBox->layout();
248 aBtnLayout->addStretch();
250 QPushButton* aCloseBtn = new QPushButton (tr("BUT_CLOSE"), aBtnBox);
251 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
253 TopLayout->addWidget(aBtnBox, 3, 0);
255 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
256 (SUIT_Session::session()->activeApplication());
257 mySelectionMgr = anApp->selectionMgr();
258 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionEvent()));
260 //connect(visuGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(close()));
264 // Activate Points pane
265 myWidgetStack->raiseWidget(myPointsPane);
266 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule))
267 aViewWindow->SetSelectionMode(NodeSelection);
270 mySelectionDlg = this;
273 VisuGUI_SelectionDlg::~VisuGUI_SelectionDlg()
277 void VisuGUI_SelectionDlg::onSelectionChange (int theId)
279 SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule);
280 if (!aViewWindow) return;
284 myWidgetStack->raiseWidget(myPointsPane);
285 aViewWindow->SetSelectionMode(NodeSelection);
286 onPointIdEdit(myIDValLbl->text());
289 myWidgetStack->raiseWidget(myCellsPane);
290 aViewWindow->SetSelectionMode(CellSelection);
291 onCellIdEdit(myCellIDValLbl->text());
294 myWidgetStack->raiseWidget(myActorsPane);
295 aViewWindow->SetSelectionMode(ActorSelection);
301 void VisuGUI_SelectionDlg::closeEvent (QCloseEvent* theEvent)
303 if (mySelectionDlg) {
304 mySelectionDlg = NULL;
305 disconnect(mySelectionMgr,0,0,0);
306 if (SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule)) {
307 switch(aViewWindow->SelectionMode()){
310 aViewWindow->SetSelectionMode(ActorSelection);
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 SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule);
340 if (!aViewWindow) return;
342 switch (aViewWindow->SelectionMode()) {
355 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
357 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
358 (SUIT_Session::session()->activeApplication());
360 SVTK_Selector* aSelector = aViewWindow->GetSelector();
362 VISU::Prs3d_i* aPrs3d = NULL;
363 _PTR(SObject) aSObject;
364 Handle(SALOME_InteractiveObject) anIO;
366 SALOME_ListIO aListIO;
367 mySelectionMgr->selectedObjects(aListIO);
369 if (aListIO.Extent() == 1) {
370 anIO = aListIO.First();
372 if (anIO->hasEntry()) {
373 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
374 _PTR(Study) aStudy = theStudy->studyDS();
375 aSObject = aStudy->FindObjectID(anIO->getEntry());
378 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
380 if (!CORBA::is_nil(anObject)) {
381 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
384 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
392 VISU::Storable::TRestoringMap aMap;
394 _PTR(GenericAttribute) anAttr;
395 if (aSObject->FindAttribute(anAttr, "AttributeComment")) {
396 _PTR(AttributeComment) aComment (anAttr);
397 std::string aString = aComment->Value();
398 QString strIn( aString.c_str() );
399 VISU::Storable::StrToMap(strIn, aMap);
403 QString aMeshName("NULL"), aFieldName("NULL");
405 aMeshName = VISU::Storable::FindValue(aMap, "myMeshName");
406 aFieldName = VISU::Storable::FindValue(aMap, "myFieldName");
409 myMeshName ->setText((aMeshName == "NULL") ? QString("No name") : aMeshName);
410 myFieldName->setText((aFieldName == "NULL") ? QString("No name") : aFieldName);
412 VISU_Actor* anVISUActor =
413 VISU::FindActor(aViewWindow, aSObject->GetID().c_str());
416 anVISUActor->GetBounds(aCoord);
417 myXPosLbl->setText(QString::number( aCoord[0] ));
418 myYPosLbl->setText(QString::number( aCoord[2] ));
419 myZPosLbl->setText(QString::number( aCoord[4] ));
421 myDXLbl->setText(QString::number( ABS(aCoord[1]-aCoord[0]) ));
422 myDYLbl->setText(QString::number( ABS(aCoord[3]-aCoord[2]) ));
423 myDZLbl->setText(QString::number( ABS(aCoord[5]-aCoord[4]) ));
425 TColStd_IndexedMapOfInteger aMapIndex;
426 typedef map<int,float*> PointsMap;
427 PointsMap aPointsMap;
429 aSelector->GetIndex(anIO, aMapIndex);
431 vtkDataSet* aDataSet = anVISUActor->GetInput();
432 vtkPointData* aPntData = aDataSet->GetPointData();
434 for (int ind = 1; ind <= aMapIndex.Extent(); ind++) {
435 int anID = aMapIndex(ind);
440 float* aCoord = anVISUActor->GetNodeCoord(anID);
441 int aVTKID = anVISUActor->GetNodeVTKID(anID);
442 myXValLbl->setText( QString::number( aCoord[0] ) );
443 myYValLbl->setText( QString::number( aCoord[1] ) );
444 myZValLbl->setText( QString::number( aCoord[2] ) );
445 myIDValLbl->setText( QString::number(anID) );
446 myScalarValLbl->setText(getValue(aPntData, aVTKID));
447 myVectorValLbl->setText(getVector(aPntData, aVTKID));
452 vtkCellData* aCellData = aDataSet->GetCellData();
453 vtkCell* aCell = anVISUActor->GetElemCell(anID);
454 int aVTKID = anVISUActor->GetElemVTKID(anID);
456 int aNbOfPoints = aCell->GetNumberOfPoints();
457 if ( aNbOfPoints <= 1 ) { // Cell is point
460 myCellIDValLbl->setText( QString::number(anID) );
461 myCellScalarValLbl->setText(getValue(aCellData, aVTKID));
462 myCellVectorValLbl->setText(getVector(aCellData, aVTKID));
465 vtkIdList *aPointList = aCell->GetPointIds();
467 for (int i = 0; i < aNbOfPoints; i++) {
468 int idCurrent = aPointList->GetId(i);
469 aCoord = aDataSet->GetPoint(idCurrent);
470 aPointsMap.insert(PointsMap::value_type(idCurrent,aCoord));
479 myListPoints->setNumRows(aPointsMap.size());
480 PointsMap::const_iterator It = aPointsMap.begin();
481 for (int i = 0; It != aPointsMap.end() && i < myListPoints->numRows(); It++, i++) {
482 myListPoints->verticalHeader()->setLabel(i, QString::number( i ));
484 myListPoints->setText(i, 0, QString::number( id ));
485 float* aCoord = It->second;
486 myListPoints->setText(i, 1, QString::number( aCoord[0] ));
487 myListPoints->setText(i, 2, QString::number( aCoord[1] ));
488 myListPoints->setText(i, 3, QString::number( aCoord[2] ));
489 myListPoints->setText(i, 4, getValue(aPntData, id));
490 myListPoints->setText(i, 5, getVector(aPntData, id));
501 void VisuGUI_SelectionDlg::clearFields() {
502 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
505 myXValLbl->setText( "" );
506 myYValLbl->setText( "" );
507 myZValLbl->setText( "" );
508 myIDValLbl->setText( "" );
509 myScalarValLbl->setText("");
510 myVectorValLbl->setText("");
513 myCellIDValLbl->setText( "" );
514 myCellScalarValLbl->setText("");
515 myCellVectorValLbl->setText("");
516 myListPoints->setNumRows(0);
519 myXPosLbl->setText("");
520 myYPosLbl->setText("");
521 myZPosLbl->setText("");
522 myDXLbl->setText("");
523 myDYLbl->setText("");
524 myDZLbl->setText("");
528 typedef vtkIdType (vtkDataSet::* TDataSetMethod)();
530 bool onIdEdit (const QString& theText,
531 TDataSetMethod theMethod,
533 const SalomeApp_Module* theModule,
534 LightApp_SelectionMgr* theSelectionMgr,
537 QLabel* theFieldName)
539 SalomeApp_Application* anApp = theModule->getApp();
540 SVTK_ViewWindow* aViewWindow = VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule);
541 if (!aViewWindow) return false;
542 SVTK_Selector* aSelector = aViewWindow->GetSelector();
544 VISU::Prs3d_i* aPrs3d = NULL;
545 Handle(SALOME_InteractiveObject) anIO;
547 SALOME_ListIO aListIO;
548 theSelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
550 if (aListIO.Extent() == 1) {
551 anIO = aListIO.First();
553 if (anIO->hasEntry()) {
554 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
555 _PTR(Study) aStudy = theStudy->studyDS();
556 _PTR(SObject) aSObject = aStudy->FindObjectID(anIO->getEntry());
559 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
561 if (!CORBA::is_nil(anObject)) {
562 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
565 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
573 int anId = theText.toInt();
574 vtkDataSet* aDataSet = aPrs3d->GetPL()->GetMapper()->GetInput();
575 int aMaxId = (aDataSet->*theMethod)();
576 if (anId < 0) anId = 0;
577 if (anId >= aMaxId) anId = aMaxId - 1;
579 TColStd_MapOfInteger newIndices;
580 newIndices.Add(anId);
581 aSelector->AddOrRemoveIndex(anIO, newIndices, false);
582 aViewWindow->highlight(anIO, true, true);
587 theMeshName->setText(theValue);
588 theFieldName->setText("");
593 void VisuGUI_SelectionDlg::onPointIdEdit (const QString& theText)
596 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfPoints;
597 bool anIsSelected = onIdEdit(theText,aMethod,false,myModule,mySelectionMgr,
598 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
601 // as selection manager doesn't send signal currentSelectionChanged()
607 void VisuGUI_SelectionDlg::onCellIdEdit (const QString& theText)
610 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfCells;
611 bool anIsSelected = onIdEdit(theText,aMethod,true,myModule,mySelectionMgr,
612 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
615 // as selection manager doesn't send signal currentSelectionChanged()