1 // SMESH SMESHGUI : GUI for SMESH 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.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File : SMESHGUI_NodesDlg.cxx
25 // Author : Nicolas REJNERI
29 #include "SMESHGUI_NodesDlg.h"
32 #include "SMESHGUI_SpinBox.h"
33 #include "SMESHGUI_Utils.h"
34 #include "SMESHGUI_VTKUtils.h"
35 #include "SMESHGUI_MeshUtils.h"
37 #include "SMESH_Actor.h"
38 #include "SMESH_ActorUtils.h"
39 #include "SMESH_ObjectDef.h"
41 #include "SMDS_Mesh.hxx"
42 #include "SMDS_MeshNode.hxx"
44 #include "SUIT_Session.h"
45 #include "SUIT_OverrideCursor.h"
46 #include "SUIT_ViewWindow.h"
47 #include "SUIT_ViewManager.h"
48 #include "SUIT_MessageBox.h"
49 #include "SUIT_Desktop.h"
51 #include "SalomeApp_Study.h"
52 #include "LightApp_Application.h"
53 #include "LightApp_SelectionMgr.h"
55 #include "SVTK_Selector.h"
56 #include "SVTK_ViewWindow.h"
57 #include "VTKViewer_CellLocationsArray.h"
59 #include "SALOME_Actor.h"
60 #include "SALOME_ListIO.hxx"
62 #include "utilities.h"
66 #include <vtkIdList.h>
67 #include <vtkCellArray.h>
68 #include <vtkUnsignedCharArray.h>
69 #include <vtkUnstructuredGrid.h>
70 #include <vtkDataSetMapper.h>
71 #include <vtkActorCollection.h>
72 #include <vtkRenderer.h>
73 #include <vtkProperty.h>
76 #include <qbuttongroup.h>
78 #include <qgroupbox.h>
80 #include <qlineedit.h>
81 #include <qpushbutton.h>
82 #include <qradiobutton.h>
86 #include <qwhatsthis.h>
89 #include <qvalidator.h>
97 void AddNode (SMESH::SMESH_Mesh_ptr theMesh, float x, float y, float z)
99 SUIT_OverrideCursor wc;
101 _PTR(SObject) aSobj = SMESH::FindSObject(theMesh);
102 SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
103 aMeshEditor->AddNode(x,y,z);
104 _PTR(Study) aStudy = GetActiveStudyDocument();
105 CORBA::Long anId = aStudy->StudyId();
106 if (TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, aSobj->GetID().c_str())) {
107 aVisualObj->Update(true);
109 } catch (SALOME::SALOME_Exception& exc) {
110 INFOS("Follow exception was cought:\n\t" << exc.details.text);
111 } catch (const std::exception& exc) {
112 INFOS("Follow exception was cought:\n\t" << exc.what());
114 INFOS("Unknown exception was cought !!!");
118 class TNodeSimulation {
119 SVTK_ViewWindow* myViewWindow;
121 SALOME_Actor *myPreviewActor;
122 vtkDataSetMapper* myMapper;
126 TNodeSimulation(SVTK_ViewWindow* theViewWindow):
127 myViewWindow(theViewWindow)
129 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
132 myPoints = vtkPoints::New();
133 myPoints->SetNumberOfPoints(1);
134 myPoints->SetPoint(0,0.0,0.0,0.0);
137 vtkIdList *anIdList = vtkIdList::New();
138 anIdList->SetNumberOfIds(1);
140 vtkCellArray *aCells = vtkCellArray::New();
141 aCells->Allocate(2, 0);
143 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
144 aCellTypesArray->SetNumberOfComponents(1);
145 aCellTypesArray->Allocate(1);
147 anIdList->SetId(0, 0);
148 aCells->InsertNextCell(anIdList);
149 aCellTypesArray->InsertNextValue(VTK_VERTEX);
151 VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
152 aCellLocationsArray->SetNumberOfComponents(1);
153 aCellLocationsArray->SetNumberOfTuples(1);
155 aCells->InitTraversal();
157 aCellLocationsArray->SetValue(0, aCells->GetTraversalLocation(npts));
159 aGrid->SetCells(aCellTypesArray, aCellLocationsArray, aCells);
161 aGrid->SetPoints(myPoints);
162 aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aCells);
163 aCellLocationsArray->Delete();
164 aCellTypesArray->Delete();
168 // Create and display actor
169 myMapper = vtkDataSetMapper::New();
170 myMapper->SetInput(aGrid);
173 myPreviewActor = SALOME_Actor::New();
174 myPreviewActor->SetInfinitive(true);
175 myPreviewActor->VisibilityOff();
176 myPreviewActor->PickableOff();
177 myPreviewActor->SetMapper(myMapper);
179 vtkProperty* aProp = vtkProperty::New();
180 aProp->SetRepresentationToPoints();
182 vtkFloatingPointType anRGB[3];
183 GetColor( "SMESH", "node_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 255, 0 ) );
184 aProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
186 vtkFloatingPointType aPointSize = GetFloat( "SMESH:node_size", 3 );
187 aProp->SetPointSize( aPointSize );
189 myPreviewActor->SetProperty( aProp );
192 myViewWindow->AddActor(myPreviewActor);
195 void SetPosition (float x, float y, float z)
197 myPoints->SetPoint(0,x,y,z);
198 myPoints->Modified();
202 void SetVisibility (bool theVisibility)
204 myPreviewActor->SetVisibility(theVisibility);
205 RepaintCurrentView();
210 myViewWindow->RemoveActor(myPreviewActor);
211 myPreviewActor->Delete();
213 myMapper->RemoveAllInputs();
221 //=================================================================================
222 // class : SMESHGUI_NodesDlg()
224 //=================================================================================
225 SMESHGUI_NodesDlg::SMESHGUI_NodesDlg (SMESHGUI* theModule,
229 QDialog(SMESH::GetDesktop(theModule),
232 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
233 mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
234 mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
235 mySMESHGUI(theModule)
237 mySimulation = new SMESH::TNodeSimulation(SMESH::GetViewWindow( mySMESHGUI ));
239 QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_NODE")));
241 setName("SMESHGUI_NodesDlg");
243 setCaption(tr("MESH_NODE_TITLE"));
244 setSizeGripEnabled(TRUE);
245 SMESHGUI_NodesDlgLayout = new QGridLayout(this);
246 SMESHGUI_NodesDlgLayout->setSpacing(6);
247 SMESHGUI_NodesDlgLayout->setMargin(11);
249 /***************************************************************/
250 GroupButtons = new QGroupBox(this, "GroupButtons");
251 GroupButtons->setGeometry(QRect(10, 10, 281, 48));
252 GroupButtons->setTitle(tr("" ));
253 GroupButtons->setColumnLayout(0, Qt::Vertical);
254 GroupButtons->layout()->setSpacing(0);
255 GroupButtons->layout()->setMargin(0);
256 GroupButtonsLayout = new QGridLayout(GroupButtons->layout());
257 GroupButtonsLayout->setAlignment(Qt::AlignTop);
258 GroupButtonsLayout->setSpacing(6);
259 GroupButtonsLayout->setMargin(11);
260 buttonHelp = new QPushButton(GroupButtons, "buttonHelp");
261 buttonHelp->setText(tr("SMESH_BUT_HELP" ));
262 buttonHelp->setAutoDefault(TRUE);
263 GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
264 buttonCancel = new QPushButton(GroupButtons, "buttonCancel");
265 buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
266 buttonCancel->setAutoDefault(TRUE);
267 GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
268 buttonApply = new QPushButton(GroupButtons, "buttonApply");
269 buttonApply->setText(tr("SMESH_BUT_APPLY" ));
270 buttonApply->setAutoDefault(TRUE);
271 GroupButtonsLayout->addWidget(buttonApply, 0, 1);
272 QSpacerItem* spacer_9 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
273 GroupButtonsLayout->addItem(spacer_9, 0, 2);
274 buttonOk = new QPushButton(GroupButtons, "buttonOk");
275 buttonOk->setText(tr("SMESH_BUT_OK" ));
276 buttonOk->setAutoDefault(TRUE);
277 buttonOk->setDefault(TRUE);
278 GroupButtonsLayout->addWidget(buttonOk, 0, 0);
279 SMESHGUI_NodesDlgLayout->addWidget(GroupButtons, 2, 0);
281 /***************************************************************/
282 GroupConstructors = new QButtonGroup(this, "GroupConstructors");
283 GroupConstructors->setTitle(tr("MESH_NODE" ));
284 GroupConstructors->setExclusive(TRUE);
285 GroupConstructors->setColumnLayout(0, Qt::Vertical);
286 GroupConstructors->layout()->setSpacing(0);
287 GroupConstructors->layout()->setMargin(0);
288 GroupConstructorsLayout = new QGridLayout(GroupConstructors->layout());
289 GroupConstructorsLayout->setAlignment(Qt::AlignTop);
290 GroupConstructorsLayout->setSpacing(6);
291 GroupConstructorsLayout->setMargin(11);
292 Constructor1 = new QRadioButton(GroupConstructors, "Constructor1");
293 Constructor1->setText(tr("" ));
294 Constructor1->setPixmap(image0);
295 Constructor1->setChecked(TRUE);
296 GroupConstructorsLayout->addWidget(Constructor1, 0, 0);
297 QSpacerItem* spacer_2 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
298 GroupConstructorsLayout->addItem(spacer_2, 0, 1);
299 SMESHGUI_NodesDlgLayout->addWidget(GroupConstructors, 0, 0);
301 /***************************************************************/
302 GroupCoordinates = new QGroupBox(this, "GroupCoordinates");
303 GroupCoordinates->setTitle(tr("SMESH_COORDINATES" ));
304 GroupCoordinates->setColumnLayout(0, Qt::Vertical);
305 GroupCoordinates->layout()->setSpacing(0);
306 GroupCoordinates->layout()->setMargin(0);
307 GroupCoordinatesLayout = new QGridLayout(GroupCoordinates->layout());
308 GroupCoordinatesLayout->setAlignment(Qt::AlignTop);
309 GroupCoordinatesLayout->setSpacing(6);
310 GroupCoordinatesLayout->setMargin(11);
311 TextLabel_X = new QLabel(GroupCoordinates, "TextLabel_X");
312 TextLabel_X->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
313 TextLabel_X->setText(tr("SMESH_X" ));
314 GroupCoordinatesLayout->addWidget(TextLabel_X, 0, 0);
315 TextLabel_Y = new QLabel(GroupCoordinates, "TextLabel_Y");
316 TextLabel_Y->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
317 TextLabel_Y->setText(tr("SMESH_Y" ));
318 GroupCoordinatesLayout->addWidget(TextLabel_Y, 0, 2);
320 TextLabel_Z = new QLabel(GroupCoordinates, "TextLabel_Z");
321 TextLabel_Z->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
322 TextLabel_Z->setText(tr("SMESH_Z" ));
323 GroupCoordinatesLayout->addWidget(TextLabel_Z, 0, 4);
325 SpinBox_X = new SMESHGUI_SpinBox(GroupCoordinates, "SpinBox_X");
326 GroupCoordinatesLayout->addWidget(SpinBox_X, 0, 1);
328 SpinBox_Y = new SMESHGUI_SpinBox(GroupCoordinates, "SpinBox_Y");
329 GroupCoordinatesLayout->addWidget(SpinBox_Y, 0, 3);
331 SpinBox_Z = new SMESHGUI_SpinBox(GroupCoordinates, "SpinBox_Z");
332 GroupCoordinatesLayout->addWidget(SpinBox_Z, 0, 5);
334 SMESHGUI_NodesDlgLayout->addWidget(GroupCoordinates, 1, 0);
336 myHelpFileName = "/files/adding_nodes_and_elements.htm#Adding_nodes";
338 /* Initialisation and display */
342 //=======================================================================
343 // function : ~SMESHGUI_NodesDlg()
344 // purpose : Destructor
345 //=======================================================================
346 SMESHGUI_NodesDlg::~SMESHGUI_NodesDlg()
351 //=================================================================================
354 //=================================================================================
355 void SMESHGUI_NodesDlg::Init ()
357 /* Get setting of step value from file configuration */
359 // QString St = SUIT_CONFIG->getSetting("xxxxxxxxxxxxx"); TODO
360 // step = St.toDouble(); TODO
363 /* min, max, step and decimals for spin boxes */
364 SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, 3);
365 SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, 3);
366 SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, step, 3);
367 SpinBox_X->SetValue(0.0);
368 SpinBox_Y->SetValue(0.0);
369 SpinBox_Z->SetValue(0.0);
371 mySMESHGUI->SetActiveDialogBox((QDialog*)this);
373 /* signals and slots connections */
374 connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
375 connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
376 connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
377 connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
379 connect(SpinBox_X, SIGNAL (valueChanged(double)), SLOT(ValueChangedInSpinBox(double)));
380 connect(SpinBox_Y, SIGNAL (valueChanged(double)), SLOT(ValueChangedInSpinBox(double)));
381 connect(SpinBox_Z, SIGNAL (valueChanged(double)), SLOT(ValueChangedInSpinBox(double)));
383 connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
384 connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
385 /* to close dialog if study frame change */
386 connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
390 // set selection mode
391 SMESH::SetPointRepresentation(true);
392 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
393 aViewWindow->SetSelectionMode(NodeSelection);
395 SelectionIntoArgument();
398 //=================================================================================
399 // function : ValueChangedInSpinBox()
401 //=================================================================================
402 void SMESHGUI_NodesDlg::ValueChangedInSpinBox (double newValue)
404 if (!myMesh->_is_nil()) {
405 double vx = SpinBox_X->GetValue();
406 double vy = SpinBox_Y->GetValue();
407 double vz = SpinBox_Z->GetValue();
409 mySimulation->SetPosition(vx,vy,vz);
413 //=================================================================================
414 // function : ClickOnOk()
416 //=================================================================================
417 void SMESHGUI_NodesDlg::ClickOnOk()
423 //=================================================================================
424 // function : ClickOnApply()
426 //=================================================================================
427 bool SMESHGUI_NodesDlg::ClickOnApply()
429 if (mySMESHGUI->isActiveStudyLocked())
432 if (myMesh->_is_nil()) {
433 SUIT_MessageBox::warn1(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
434 tr("MESH_IS_NOT_SELECTED"), tr("SMESH_BUT_OK"));
438 /* Recup args and call method */
439 double x = SpinBox_X->GetValue();
440 double y = SpinBox_Y->GetValue();
441 double z = SpinBox_Z->GetValue();
442 mySimulation->SetVisibility(false);
443 SMESH::AddNode(myMesh,x,y,z);
444 SMESH::SetPointRepresentation(true);
448 mySelectionMgr->selectedObjects(aList);
449 if (aList.Extent() != 1) {
450 if (SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView()) {
451 vtkActorCollection *aCollection = aViewWindow->getRenderer()->GetActors();
452 aCollection->InitTraversal();
453 while (vtkActor *anAct = aCollection->GetNextActor()) {
454 if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
455 if (anActor->hasIO()) {
456 if (SMESH_MeshObj *aMeshObj = dynamic_cast<SMESH_MeshObj*>(anActor->GetObject().get())) {
457 if (myMesh->_is_equivalent(aMeshObj->GetMeshServer())) {
459 aList.Append(anActor->getIO());
460 mySelectionMgr->setSelectedObjects(aList, false);
472 //=================================================================================
473 // function : ClickOnCancel()
475 //=================================================================================
476 void SMESHGUI_NodesDlg::ClickOnCancel()
478 disconnect(mySelectionMgr, 0, this, 0);
479 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
480 aViewWindow->SetSelectionMode(ActorSelection);
482 mySimulation->SetVisibility(false);
483 SMESH::SetPointRepresentation(false);
484 mySMESHGUI->ResetState();
489 //=================================================================================
490 // function : ClickOnHelp()
492 //=================================================================================
493 void SMESHGUI_NodesDlg::ClickOnHelp()
495 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
497 app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
499 SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
500 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
501 arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(myHelpFileName),
502 QObject::tr("BUT_OK"));
506 //=================================================================================
507 // function : SelectionIntoArgument()
508 // purpose : Called when selection as changed or other case
509 //=================================================================================
510 void SMESHGUI_NodesDlg::SelectionIntoArgument()
512 if (!GroupConstructors->isEnabled())
515 mySimulation->SetVisibility(false);
516 SMESH::SetPointRepresentation(true);
518 const SALOME_ListIO& aList = mySelector->StoredIObjects();
519 if (aList.Extent() == 1) {
520 Handle(SALOME_InteractiveObject) anIO = aList.First();
521 if (anIO->hasEntry()) {
522 myMesh = SMESH::GetMeshByIO(anIO);
523 if (myMesh->_is_nil()) return;
525 if (SMESH::GetNameOfSelectedNodes(mySelector,anIO,aText) == 1) {
526 if (SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh.in())) {
527 if (SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh()) {
528 if (const SMDS_MeshNode* aNode = aMesh->FindNode(aText.toInt())) {
529 SpinBox_X->SetValue(aNode->X());
530 SpinBox_Y->SetValue(aNode->Y());
531 SpinBox_Z->SetValue(aNode->Z());
536 mySimulation->SetPosition(SpinBox_X->GetValue(),
537 SpinBox_Y->GetValue(),
538 SpinBox_Z->GetValue());
543 //=================================================================================
544 // function : closeEvent()
546 //=================================================================================
547 void SMESHGUI_NodesDlg::closeEvent (QCloseEvent*)
549 this->ClickOnCancel(); /* same than click on cancel button */
552 //=================================================================================
553 // function : hideEvent()
554 // purpose : caused by ESC key
555 //=================================================================================
556 void SMESHGUI_NodesDlg::hideEvent (QHideEvent*)
562 //=================================================================================
563 // function : enterEvent()
564 // purpose : to reactivate this dialog box when mouse enter onto the window
565 //=================================================================================
566 void SMESHGUI_NodesDlg::enterEvent(QEvent*)
568 if (!GroupConstructors->isEnabled())
569 ActivateThisDialog();
572 //=================================================================================
573 // function : DeactivateActiveDialog()
574 // purpose : public slot to deactivate if active
575 //=================================================================================
576 void SMESHGUI_NodesDlg::DeactivateActiveDialog()
578 if (GroupConstructors->isEnabled()) {
579 GroupConstructors->setEnabled(false);
580 GroupCoordinates->setEnabled(false);
581 GroupButtons->setEnabled(false);
582 mySimulation->SetVisibility(false);
583 mySMESHGUI->ResetState();
584 mySMESHGUI->SetActiveDialogBox(0);
588 //=================================================================================
589 // function : ActivateThisDialog()
591 //=================================================================================
592 void SMESHGUI_NodesDlg::ActivateThisDialog()
594 mySMESHGUI->EmitSignalDeactivateDialog();
595 GroupConstructors->setEnabled(true);
596 GroupCoordinates->setEnabled(true);
597 GroupButtons->setEnabled(true);
599 SMESH::SetPointRepresentation(true);
600 if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
601 aViewWindow->SetSelectionMode(NodeSelection);
603 SelectionIntoArgument();
606 //=================================================================================
607 // function : keyPressEvent()
609 //=================================================================================
610 void SMESHGUI_NodesDlg::keyPressEvent( QKeyEvent* e )
612 QDialog::keyPressEvent( e );
613 if ( e->isAccepted() )
616 if ( e->key() == Key_F1 )