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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SMESHGUI_NodesDlg.cxx
25 // Author : Nicolas REJNERI
29 #include "SMESHGUI_NodesDlg.h"
32 #include "SMESHGUI_Utils.h"
33 #include "SMESHGUI_MeshUtils.h"
35 #include "SMESHGUI_VTKUtils.h"
36 #include "SMESH_ActorUtils.h"
38 #include "VTKViewer_ViewFrame.h"
39 #include "SALOME_Actor.h"
41 #include "SMESHGUI_SpinBox.h"
43 #include "QAD_Application.h"
44 #include "QAD_Desktop.h"
45 #include "QAD_WaitCursor.h"
46 #include "QAD_MessageBox.h"
48 #include "SMESH_Actor.h"
49 #include "SMDS_Mesh.hxx"
50 #include "SMDS_MeshNode.hxx"
54 #include <vtkIdList.h>
55 #include <vtkIntArray.h>
56 #include <vtkCellArray.h>
57 #include <vtkUnsignedCharArray.h>
58 #include <vtkUnstructuredGrid.h>
59 #include <vtkDataSetMapper.h>
60 #include <vtkActorCollection.h>
61 #include <vtkRenderer.h>
64 #include <qbuttongroup.h>
66 #include <qgroupbox.h>
68 #include <qlineedit.h>
69 #include <qpushbutton.h>
70 #include <qradiobutton.h>
74 #include <qwhatsthis.h>
77 #include <qvalidator.h>
80 #include "utilities.h"
87 void AddNode(SMESH::SMESH_Mesh_ptr theMesh, float x, float y, float z){
90 SALOMEDS::SObject_var aSobj = SMESH::FindSObject(theMesh);
91 CORBA::String_var anEntry = aSobj->GetID();
92 SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
93 aMeshEditor->AddNode(x,y,z);
94 SALOMEDS::Study_var aStudy = GetActiveStudyDocument();
95 CORBA::Long anId = aStudy->StudyId();
96 if(TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,anEntry.in())){
97 aVisualObj->Update(true);
99 }catch(SALOME::SALOME_Exception& exc) {
100 INFOS("Follow exception was cought:\n\t"<<exc.details.text);
101 }catch(const std::exception& exc){
102 INFOS("Follow exception was cought:\n\t"<<exc.what());
104 INFOS("Unknown exception was cought !!!");
109 class TNodeSimulation{
111 QAD_StudyFrame* myStudyFrame;
112 VTKViewer_ViewFrame* myViewFrame;
114 SALOME_Actor *myPreviewActor;
115 vtkDataSetMapper* myMapper;
120 TNodeSimulation(QAD_Study* theStudy):
122 myStudyFrame(theStudy->getActiveStudyFrame()),
123 myViewFrame(GetVtkViewFrame(theStudy->getActiveStudyFrame()))
125 vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
128 myPoints = vtkPoints::New();
129 myPoints->SetNumberOfPoints( 1 );
130 myPoints->SetPoint(0,0.0,0.0,0.0);
133 vtkIdList *anIdList = vtkIdList::New();
134 anIdList->SetNumberOfIds( 1 );
136 vtkCellArray *aCells = vtkCellArray::New();
137 aCells->Allocate( 2, 0 );
139 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
140 aCellTypesArray->SetNumberOfComponents( 1 );
141 aCellTypesArray->Allocate( 1 );
143 anIdList->SetId( 0, 0 );
144 aCells->InsertNextCell( anIdList );
145 aCellTypesArray->InsertNextValue( VTK_VERTEX );
147 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
148 aCellLocationsArray->SetNumberOfComponents( 1 );
149 aCellLocationsArray->SetNumberOfTuples( 1 );
151 aCells->InitTraversal();
153 aCellLocationsArray->SetValue( 0, aCells->GetTraversalLocation( npts ) );
155 aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
157 aGrid->SetPoints( myPoints );
158 aGrid->SetCells( aCellTypesArray, aCellLocationsArray,aCells );
159 aCellLocationsArray->Delete();
160 aCellTypesArray->Delete();
164 // Create and display actor
165 myMapper = vtkDataSetMapper::New();
166 myMapper->SetInput( aGrid );
169 myPreviewActor = SALOME_Actor::New();
170 myPreviewActor->SetInfinitive(true);
171 myPreviewActor->VisibilityOff();
172 myPreviewActor->PickableOff();
173 myPreviewActor->SetMapper( myMapper );
175 vtkProperty* aProp = vtkProperty::New();
176 aProp->SetRepresentationToPoints();
179 anRGB[0] = GetFloat("SMESH:SettingsNodeColorRed",0)/255.;
180 anRGB[1] = GetFloat("SMESH:SettingsNodeColorGreen",255)/255.;
181 anRGB[2] = GetFloat("SMESH:SettingsNodeColorBlue",0)/255.;
182 aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
184 float aPointSize = GetFloat("SMESH:SettingsNodesSize",3);
185 aProp->SetPointSize(aPointSize);
187 myPreviewActor->SetProperty( aProp );
190 myViewFrame->AddActor( myPreviewActor );
195 void SetPosition(float x, float y, float z){
196 myPoints->SetPoint(0,x,y,z);
197 myPoints->Modified();
202 void SetVisibility(bool theVisibility){
203 myPreviewActor->SetVisibility(theVisibility);
204 RepaintCurrentView();
209 if(FindVtkViewFrame(myStudy,myStudyFrame)){
210 myViewFrame->RemoveActor(myPreviewActor);
212 myPreviewActor->Delete();
214 myMapper->RemoveAllInputs();
225 //=================================================================================
226 // class : SMESHGUI_NodesDlg()
228 //=================================================================================
229 SMESHGUI_NodesDlg::SMESHGUI_NodesDlg( QWidget* parent,
231 SALOME_Selection* Sel,
234 : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu |
235 Qt::WDestructiveClose)
237 mySimulation = new SMESH::TNodeSimulation(SMESH::GetActiveStudy());
239 QPixmap image0(QAD_Desktop::getResourceManager()->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 buttonCancel = new QPushButton( GroupButtons, "buttonCancel" );
261 buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) );
262 buttonCancel->setAutoDefault( TRUE );
263 GroupButtonsLayout->addWidget( buttonCancel, 0, 3 );
264 buttonApply = new QPushButton( GroupButtons, "buttonApply" );
265 buttonApply->setText( tr( "SMESH_BUT_APPLY" ) );
266 buttonApply->setAutoDefault( TRUE );
267 GroupButtonsLayout->addWidget( buttonApply, 0, 1 );
268 QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
269 GroupButtonsLayout->addItem( spacer_9, 0, 2 );
270 buttonOk = new QPushButton( GroupButtons, "buttonOk" );
271 buttonOk->setText( tr( "SMESH_BUT_OK" ) );
272 buttonOk->setAutoDefault( TRUE );
273 buttonOk->setDefault( TRUE );
274 GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
275 SMESHGUI_NodesDlgLayout->addWidget( GroupButtons, 2, 0 );
277 /***************************************************************/
278 GroupConstructors = new QButtonGroup( this, "GroupConstructors" );
279 GroupConstructors->setTitle( tr( "MESH_NODE" ) );
280 GroupConstructors->setExclusive( TRUE );
281 GroupConstructors->setColumnLayout(0, Qt::Vertical );
282 GroupConstructors->layout()->setSpacing( 0 );
283 GroupConstructors->layout()->setMargin( 0 );
284 GroupConstructorsLayout = new QGridLayout( GroupConstructors->layout() );
285 GroupConstructorsLayout->setAlignment( Qt::AlignTop );
286 GroupConstructorsLayout->setSpacing( 6 );
287 GroupConstructorsLayout->setMargin( 11 );
288 Constructor1 = new QRadioButton( GroupConstructors, "Constructor1" );
289 Constructor1->setText( tr( "" ) );
290 Constructor1->setPixmap( image0 );
291 Constructor1->setChecked( TRUE );
292 GroupConstructorsLayout->addWidget( Constructor1, 0, 0 );
293 QSpacerItem* spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
294 GroupConstructorsLayout->addItem( spacer_2, 0, 1 );
295 SMESHGUI_NodesDlgLayout->addWidget( GroupConstructors, 0, 0 );
297 /***************************************************************/
298 GroupCoordinates = new QGroupBox( this, "GroupCoordinates" );
299 GroupCoordinates->setTitle( tr( "SMESH_COORDINATES" ) );
300 GroupCoordinates->setColumnLayout(0, Qt::Vertical );
301 GroupCoordinates->layout()->setSpacing( 0 );
302 GroupCoordinates->layout()->setMargin( 0 );
303 GroupCoordinatesLayout = new QGridLayout( GroupCoordinates->layout() );
304 GroupCoordinatesLayout->setAlignment( Qt::AlignTop );
305 GroupCoordinatesLayout->setSpacing( 6 );
306 GroupCoordinatesLayout->setMargin( 11 );
307 TextLabel_X = new QLabel( GroupCoordinates, "TextLabel_X" );
308 TextLabel_X->setText( tr( "SMESH_X" ) );
309 GroupCoordinatesLayout->addWidget( TextLabel_X, 0, 0 );
310 TextLabel_Y = new QLabel( GroupCoordinates, "TextLabel_Y" );
311 TextLabel_Y->setText( tr( "SMESH_Y" ) );
312 GroupCoordinatesLayout->addWidget( TextLabel_Y, 0, 2 );
314 TextLabel_Z = new QLabel( GroupCoordinates, "TextLabel_Z" );
315 TextLabel_Z->setText( tr( "SMESH_Z" ) );
316 GroupCoordinatesLayout->addWidget( TextLabel_Z, 0, 4 );
318 SpinBox_X = new SMESHGUI_SpinBox( GroupCoordinates, "SpinBox_X" ) ;
319 GroupCoordinatesLayout->addWidget( SpinBox_X, 0, 1 );
321 SpinBox_Y = new SMESHGUI_SpinBox( GroupCoordinates, "SpinBox_Y" ) ;
322 GroupCoordinatesLayout->addWidget( SpinBox_Y, 0, 3 );
324 SpinBox_Z = new SMESHGUI_SpinBox( GroupCoordinates, "SpinBox_Z" ) ;
325 GroupCoordinatesLayout->addWidget( SpinBox_Z, 0, 5 );
327 SMESHGUI_NodesDlgLayout->addWidget( GroupCoordinates, 1, 0 );
329 /* Initialisation and display */
334 //=======================================================================
335 // function : ~SMESHGUI_NodesDlg()
336 // purpose : Destructor
337 //=======================================================================
338 SMESHGUI_NodesDlg::~SMESHGUI_NodesDlg()
344 //=================================================================================
347 //=================================================================================
348 void SMESHGUI_NodesDlg::Init(SALOME_Selection* Sel)
350 /* Get setting of step value from file configuration */
352 // QString St = QAD_CONFIG->getSetting( "xxxxxxxxxxxxx" ) ; TODO
353 // step = St.toDouble() ; TODO
356 /* min, max, step and decimals for spin boxes */
357 SpinBox_X->RangeStepAndValidator( -999.999, +999.999, step, 3 ) ;
358 SpinBox_Y->RangeStepAndValidator( -999.999, +999.999, step, 3 ) ;
359 SpinBox_Z->RangeStepAndValidator( -999.999, +999.999, step, 3 ) ;
360 SpinBox_X->SetValue( 0.0 ) ;
361 SpinBox_Y->SetValue( 0.0 ) ;
362 SpinBox_Z->SetValue( 0.0 ) ;
365 myMeshGUI = SMESHGUI::GetSMESHGUI() ;
366 myMeshGUI->SetActiveDialogBox( (QDialog*)this ) ;
368 /* signals and slots connections */
369 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
370 connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) );
371 connect( buttonApply, SIGNAL( clicked() ), this, SLOT(ClickOnApply() ) );
373 connect( SpinBox_X, SIGNAL ( valueChanged(double) ), SLOT( ValueChangedInSpinBox(double) )) ;
374 connect( SpinBox_Y, SIGNAL ( valueChanged(double) ), SLOT( ValueChangedInSpinBox(double) )) ;
375 connect( SpinBox_Z, SIGNAL ( valueChanged(double) ), SLOT( ValueChangedInSpinBox(double) )) ;
377 connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( SelectionIntoArgument() ));
378 connect( myMeshGUI, SIGNAL ( SignalDeactivateActiveDialog() ), SLOT( DeactivateActiveDialog() )) ;
379 /* to close dialog if study frame change */
380 connect( myMeshGUI, SIGNAL ( SignalStudyFrameChanged() ), SLOT( ClickOnCancel() ) ) ;
382 /* Move widget on the botton right corner of main widget */
384 myMeshGUI->DefineDlgPosition( this, x, y ) ;
388 // set selection mode
389 SMESH::SetPointRepresentation(true);
390 QAD_Application::getDesktop()->SetSelectionMode( NodeSelection, true );
392 SelectionIntoArgument();
395 //=================================================================================
396 // function : ValueChangedInSpinBox()
398 //=================================================================================
399 void SMESHGUI_NodesDlg::ValueChangedInSpinBox( double newValue )
401 if(!myMesh->_is_nil()){
402 double vx = SpinBox_X->GetValue() ;
403 double vy = SpinBox_Y->GetValue() ;
404 double vz = SpinBox_Z->GetValue() ;
406 mySimulation->SetPosition(vx,vy,vz);
411 //=================================================================================
412 // function : ClickOnOk()
414 //=================================================================================
415 void SMESHGUI_NodesDlg::ClickOnOk()
417 if ( ClickOnApply() )
421 //=======================================================================
422 // function : ClickOnApply()
424 //=======================================================================
425 bool SMESHGUI_NodesDlg::ClickOnApply()
427 if (myMeshGUI->ActiveStudyLocked())
430 if ( myMesh->_is_nil() ) {
431 QAD_MessageBox::warn1(QAD_Application::getDesktop(),
432 tr("SMESH_WRN_WARNING"),
433 tr("MESH_IS_NOT_SELECTED"),
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);
447 if ( mySelection->IObjectCount() != 1 ) {
448 if(VTKViewer_ViewFrame* aViewFrame = SMESH::GetCurrentVtkView()) {
449 vtkActorCollection *aCollection = aViewFrame->getRenderer()->GetActors();
450 aCollection->InitTraversal();
451 while(vtkActor *anAct = aCollection->GetNextActor()){
452 if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct))
454 if(SMESH_MeshObj *aMeshObj = dynamic_cast<SMESH_MeshObj*>(anActor->GetObject().get()))
455 if(myMesh->_is_equivalent( aMeshObj->GetMeshServer() ))
457 mySelection->ClearIObjects();
458 mySelection->AddIObject( anActor->getIO(), false );
468 //=======================================================================
469 // function : ClickOnCancel()
471 //=======================================================================
472 void SMESHGUI_NodesDlg::ClickOnCancel()
474 mySelection->ClearIObjects();
475 mySimulation->SetVisibility(false);
476 SMESH::SetPointRepresentation(false);
477 QAD_Application::getDesktop()->SetSelectionMode( ActorSelection );
478 disconnect( mySelection, 0, this, 0 );
479 myMeshGUI->ResetState();
485 //=================================================================================
486 // function : SelectionIntoArgument()
487 // purpose : Called when selection as changed or other case
488 //=================================================================================
489 void SMESHGUI_NodesDlg::SelectionIntoArgument()
491 if ( !GroupConstructors->isEnabled() )
494 mySimulation->SetVisibility(false);
495 SMESH::SetPointRepresentation(true);
497 if(mySelection->IObjectCount() == 1){
498 Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject();
499 if(anIO->hasEntry()){
500 myMesh = SMESH::GetMeshByIO(anIO);
501 if(myMesh->_is_nil()) return;
503 if(SMESH::GetNameOfSelectedNodes( mySelection, aText ) == 1){
504 if(SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh.in())){
505 if(SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh()){
506 if(const SMDS_MeshNode* aNode = aMesh->FindNode(aText.toInt())){
507 SpinBox_X->SetValue( aNode->X() );
508 SpinBox_Y->SetValue( aNode->Y() ) ;
509 SpinBox_Z->SetValue( aNode->Z() ) ;
514 mySimulation->SetPosition(SpinBox_X->GetValue(),
515 SpinBox_Y->GetValue(),
516 SpinBox_Z->GetValue());
522 //=======================================================================
523 // function : closeEvent()
525 //=======================================================================
526 void SMESHGUI_NodesDlg::closeEvent(QCloseEvent* e)
528 this->ClickOnCancel() ; /* same than click on cancel button */
531 //=======================================================================
532 //function : hideEvent
533 //purpose : caused by ESC key
534 //=======================================================================
536 void SMESHGUI_NodesDlg::hideEvent ( QHideEvent * e )
538 if ( !isMinimized() )
542 //=================================================================================
543 // function : enterEvent()
544 // purpose : to reactivate this dialog box when mouse enter onto the window
545 //=================================================================================
546 void SMESHGUI_NodesDlg::enterEvent( QEvent* e)
548 if ( !GroupConstructors->isEnabled() )
549 ActivateThisDialog() ;
553 //=================================================================================
554 // function : DeactivateActiveDialog()
555 // purpose : public slot to deactivate if active
556 //=================================================================================
557 void SMESHGUI_NodesDlg::DeactivateActiveDialog()
559 if ( GroupConstructors->isEnabled() ) {
560 GroupConstructors->setEnabled(false) ;
561 GroupCoordinates->setEnabled(false) ;
562 GroupButtons->setEnabled(false) ;
563 mySimulation->SetVisibility(false) ;
564 myMeshGUI->ResetState() ;
565 myMeshGUI->SetActiveDialogBox(0) ;
570 //=================================================================================
571 // function : ActivateThisDialog()
573 //=================================================================================
574 void SMESHGUI_NodesDlg::ActivateThisDialog( )
576 myMeshGUI->EmitSignalDeactivateDialog() ;
577 GroupConstructors->setEnabled(true) ;
578 GroupCoordinates->setEnabled(true) ;
579 GroupButtons->setEnabled(true) ;
581 SMESH::SetPointRepresentation(true);
582 QAD_Application::getDesktop()->SetSelectionMode( NodeSelection, true );
584 SelectionIntoArgument();