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 "LightApp_SelectionMgr.h"
42 #include "LightApp_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>
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::GetViewWindow(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::GetViewWindow(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)
305 mySelectionDlg = NULL;
306 disconnect(mySelectionMgr,0,0,0);
307 if(SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myModule)){
308 switch(aViewWindow->SelectionMode()){
311 aViewWindow->SetSelectionMode(ActorSelection);
316 QDialog::closeEvent(theEvent);
319 template<class TData> QString getValue(TData* theData, int theId){
320 if (vtkDataArray *aScalar = theData->GetScalars()){
321 float aVal = aScalar->GetTuple1(theId);
322 return QString::number(aVal);
324 return QString("No data");
328 template<class TData> QString getVector(TData* theData, int theId){
329 if (vtkDataArray *aVector = theData->GetVectors()) {
330 float *aVal = aVector->GetTuple3(theId);
331 return QString("%1; %2; %3").arg(aVal[0]).arg(aVal[1]).arg(aVal[2]);
333 return QString("No data");
337 #define ABS(a) (a>=0)?a:-a
339 void VisuGUI_SelectionDlg::onSelectionEvent() {
340 SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(myModule);
341 if (!aViewWindow) return;
343 switch(aViewWindow->SelectionMode()){
356 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
358 SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
359 (SUIT_Session::session()->activeApplication());
361 SVTK_Selector* aSelector = aViewWindow->GetSelector();
363 VISU::Prs3d_i* aPrs3d = NULL;
364 _PTR(SObject) aSObject;
365 Handle(SALOME_InteractiveObject) anIO;
367 SALOME_ListIO aListIO;
368 mySelectionMgr->selectedObjects(aListIO);
370 if (aListIO.Extent() == 1) {
371 anIO = aListIO.First();
373 if (anIO->hasEntry()) {
374 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
375 _PTR(Study) aStudy = theStudy->studyDS();
376 aSObject = aStudy->FindObjectID(anIO->getEntry());
379 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
381 if (!CORBA::is_nil(anObject)) {
382 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
385 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
393 VISU::Storable::TRestoringMap aMap;
395 _PTR(GenericAttribute) anAttr;
396 if (aSObject->FindAttribute(anAttr, "AttributeComment")) {
397 _PTR(AttributeComment) aComment (anAttr);
398 std::string aString = aComment->Value();
399 QString strIn( aString.c_str() );
400 VISU::Storable::StrToMap(strIn, aMap);
404 QString aMeshName("NULL"), aFieldName("NULL");
406 aMeshName = VISU::Storable::FindValue(aMap, "myMeshName");
407 aFieldName = VISU::Storable::FindValue(aMap, "myFieldName");
410 myMeshName ->setText((aMeshName == "NULL") ? QString("No name") : aMeshName);
411 myFieldName->setText((aFieldName == "NULL") ? QString("No name") : aFieldName);
413 VISU_Actor* anVISUActor =
414 VISU::FindActor(aViewWindow, aSObject->GetID().c_str());
417 anVISUActor->GetBounds(aCoord);
418 myXPosLbl->setText(QString::number( aCoord[0] ));
419 myYPosLbl->setText(QString::number( aCoord[2] ));
420 myZPosLbl->setText(QString::number( aCoord[4] ));
422 myDXLbl->setText(QString::number( ABS(aCoord[1]-aCoord[0]) ));
423 myDYLbl->setText(QString::number( ABS(aCoord[3]-aCoord[2]) ));
424 myDZLbl->setText(QString::number( ABS(aCoord[5]-aCoord[4]) ));
426 TColStd_IndexedMapOfInteger aMapIndex;
427 typedef map<int,float*> PointsMap;
428 PointsMap aPointsMap;
430 aSelector->GetIndex(anIO, aMapIndex);
432 vtkDataSet* aDataSet = anVISUActor->GetInput();
433 vtkPointData* aPntData = aDataSet->GetPointData();
435 for (int ind = 1; ind <= aMapIndex.Extent(); ind++) {
436 int anID = aMapIndex(ind);
441 float* aCoord = anVISUActor->GetNodeCoord(anID);
442 int aVTKID = anVISUActor->GetNodeVTKID(anID);
443 myXValLbl->setText( QString::number( aCoord[0] ) );
444 myYValLbl->setText( QString::number( aCoord[1] ) );
445 myZValLbl->setText( QString::number( aCoord[2] ) );
446 myIDValLbl->setText( QString::number(anID) );
447 myScalarValLbl->setText(getValue(aPntData, aVTKID));
448 myVectorValLbl->setText(getVector(aPntData, aVTKID));
453 vtkCellData* aCellData = aDataSet->GetCellData();
454 vtkCell* aCell = anVISUActor->GetElemCell(anID);
455 int aVTKID = anVISUActor->GetElemVTKID(anID);
457 int aNbOfPoints = aCell->GetNumberOfPoints();
458 if ( aNbOfPoints <= 1 ) { // Cell is point
461 myCellIDValLbl->setText( QString::number(anID) );
462 myCellScalarValLbl->setText(getValue(aCellData, aVTKID));
463 myCellVectorValLbl->setText(getVector(aCellData, aVTKID));
466 vtkIdList *aPointList = aCell->GetPointIds();
468 for (int i = 0; i < aNbOfPoints; i++) {
469 int idCurrent = aPointList->GetId(i);
470 aCoord = aDataSet->GetPoint(idCurrent);
471 aPointsMap.insert(PointsMap::value_type(idCurrent,aCoord));
480 myListPoints->setNumRows(aPointsMap.size());
481 PointsMap::const_iterator It = aPointsMap.begin();
482 for (int i = 0; It != aPointsMap.end() && i < myListPoints->numRows(); It++, i++) {
483 myListPoints->verticalHeader()->setLabel(i, QString::number( i ));
485 myListPoints->setText(i, 0, QString::number( id ));
486 float* aCoord = It->second;
487 myListPoints->setText(i, 1, QString::number( aCoord[0] ));
488 myListPoints->setText(i, 2, QString::number( aCoord[1] ));
489 myListPoints->setText(i, 3, QString::number( aCoord[2] ));
490 myListPoints->setText(i, 4, getValue(aPntData, id));
491 myListPoints->setText(i, 5, getVector(aPntData, id));
502 void VisuGUI_SelectionDlg::clearFields() {
503 int aType = myWidgetStack->id(myWidgetStack->visibleWidget());
506 myXValLbl->setText( "" );
507 myYValLbl->setText( "" );
508 myZValLbl->setText( "" );
509 myIDValLbl->setText( "" );
510 myScalarValLbl->setText("");
511 myVectorValLbl->setText("");
514 myCellIDValLbl->setText( "" );
515 myCellScalarValLbl->setText("");
516 myCellVectorValLbl->setText("");
517 myListPoints->setNumRows(0);
520 myXPosLbl->setText("");
521 myYPosLbl->setText("");
522 myZPosLbl->setText("");
523 myDXLbl->setText("");
524 myDYLbl->setText("");
525 myDZLbl->setText("");
529 typedef vtkIdType (vtkDataSet::* TDataSetMethod)();
531 bool onIdEdit (const QString& theText,
532 TDataSetMethod theMethod,
534 const SalomeApp_Module* theModule,
535 LightApp_SelectionMgr* theSelectionMgr,
538 QLabel* theFieldName)
540 SalomeApp_Application* anApp = theModule->getApp();
541 SVTK_ViewWindow* aViewWindow = VISU::GetViewWindow(theModule);
542 if (!aViewWindow) return false;
543 SVTK_Selector* aSelector = aViewWindow->GetSelector();
545 VISU::Prs3d_i* aPrs3d = NULL;
546 Handle(SALOME_InteractiveObject) anIO;
548 SALOME_ListIO aListIO;
549 theSelectionMgr->selectedObjects(aListIO, SVTK_Viewer::Type());
551 if (aListIO.Extent() == 1) {
552 anIO = aListIO.First();
554 if (anIO->hasEntry()) {
555 SalomeApp_Study* theStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy());
556 _PTR(Study) aStudy = theStudy->studyDS();
557 _PTR(SObject) aSObject = aStudy->FindObjectID(anIO->getEntry());
560 CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
562 if (!CORBA::is_nil(anObject)) {
563 PortableServer::ServantBase_var aServant = VISU::GetServant(anObject);
566 aPrs3d = dynamic_cast<VISU::Prs3d_i*>(aServant.in());
574 int anId = theText.toInt();
575 vtkDataSet* aDataSet = aPrs3d->GetPL()->GetMapper()->GetInput();
576 int aMaxId = (aDataSet->*theMethod)();
577 if (anId < 0) anId = 0;
578 if (anId >= aMaxId) anId = aMaxId - 1;
580 TColStd_MapOfInteger newIndices;
581 newIndices.Add(anId);
582 aSelector->AddOrRemoveIndex(anIO, newIndices, false);
583 aViewWindow->highlight(anIO, true, true);
588 theMeshName->setText(theValue);
589 theFieldName->setText("");
594 void VisuGUI_SelectionDlg::onPointIdEdit (const QString& theText)
597 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfPoints;
598 bool anIsSelected = onIdEdit(theText,aMethod,false,myModule,mySelectionMgr,
599 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
602 // as selection manager doesn't send signal currentSelectionChanged()
608 void VisuGUI_SelectionDlg::onCellIdEdit (const QString& theText)
611 TDataSetMethod aMethod = &vtkDataSet::GetNumberOfCells;
612 bool anIsSelected = onIdEdit(theText,aMethod,true,myModule,mySelectionMgr,
613 myMeshName,tr("WRN_NO_AVAILABLE_DATA"),
616 // as selection manager doesn't send signal currentSelectionChanged()