Salome HOME
6f944e520fc656221fe7b7e7f6d469053df3e72b
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_ExtrusionDlg.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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, or (at your option) any later version.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File   : SMESHGUI_ExtrusionDlg.cxx
25 // Author : Michael ZORIN, Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_ExtrusionDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_FilterDlg.h"
32 #include "SMESHGUI_IdValidator.h"
33 #include "SMESHGUI_MeshEditPreview.h"
34 #include "SMESHGUI_MeshUtils.h"
35 #include "SMESHGUI_SpinBox.h"
36 #include "SMESHGUI_Utils.h"
37 #include "SMESHGUI_VTKUtils.h"
38 #include <GEOMBase.h>
39 #include <SMDS_Mesh.hxx>
40 #include <SMESH_Actor.h>
41 #include <SMESH_LogicalFilter.hxx>
42 #include <SMESH_TypeFilter.hxx>
43
44 // SALOME GUI includes
45 #include <LightApp_Application.h>
46 #include <LightApp_SelectionMgr.h>
47 #include <SUIT_Desktop.h>
48 #include <SUIT_MessageBox.h>
49 #include <SUIT_OverrideCursor.h>
50 #include <SUIT_ResourceMgr.h>
51 #include <SUIT_Session.h>
52 #include <SVTK_ViewModel.h>
53 #include <SVTK_ViewWindow.h>
54 #include <SalomeApp_IntSpinBox.h>
55
56 // OCCT includes
57 #include <BRep_Tool.hxx>
58 #include <TColStd_IndexedMapOfInteger.hxx>
59 #include <TColStd_MapOfInteger.hxx>
60 #include <TopoDS_Vertex.hxx>
61 #include <gp_XYZ.hxx>
62
63 // Qt includes
64 #include <QApplication>
65 #include <QButtonGroup>
66 #include <QCheckBox>
67 #include <QGridLayout>
68 #include <QGroupBox>
69 #include <QHBoxLayout>
70 #include <QKeyEvent>
71 #include <QLabel>
72 #include <QLineEdit>
73 #include <QListWidget>
74 #include <QPushButton>
75 #include <QRadioButton>
76 #include <QToolButton>
77 #include <QVBoxLayout>
78
79 // IDL includes
80 #include <SALOMEconfig.h>
81 #include CORBA_SERVER_HEADER(SMESH_Group)
82 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
83 #include <SMESH_NumberFilter.hxx>
84
85 #define SPACING 6
86 #define MARGIN  11
87
88 namespace
89 {
90   const char* getLabelText( int typeIndex, bool objSelection )
91   {
92     const char* typeLbl[3] = { "SMESH_ID_NODES", "SMESH_ID_EDGES", "SMESH_ID_FACES" };
93     const char* obj = "SMESH_OBJECTS";
94     return objSelection ? obj : typeLbl[ typeIndex ];
95   }
96 }
97
98 //================================================================================
99 /*!
100  * \brief Constructor
101  */
102 //================================================================================
103
104 SMESHGUI_3TypesSelector::SMESHGUI_3TypesSelector( QWidget * parent ):
105   QWidget( parent )
106 {
107   SMESHGUI*  gui = SMESHGUI::GetSMESHGUI();
108   mySelectionMgr = SMESH::GetSelectionMgr( gui );
109   mySelector     = SMESH::GetViewWindow( gui )->GetSelector();
110   myFilterDlg    = 0;
111   myIdValidator  = new SMESHGUI_IdValidator(this);
112
113   QPixmap image( SMESH::GetResourceMgr( gui )->loadPixmap("SMESH", tr("ICON_SELECT")));
114
115   mySelectBtnGrp = new QButtonGroup( this );
116   mySelectBtnGrp->setExclusive( true );
117
118   QVBoxLayout* mainLayout = new QVBoxLayout( this );
119   mainLayout->setSpacing( SPACING );
120   mainLayout->setMargin( 0 );
121
122   const char* groupLbl[3] = { "SMESH_NODES", "SMESH_EDGES", "SMESH_FACES" };
123
124   for ( int i = 0; i < 3; ++i )
125   {
126     myGroups[i] = new QGroupBox( tr( groupLbl[i] ), this );
127     mainLayout->addWidget( myGroups[i] );
128     QGridLayout* layout = new QGridLayout( myGroups[i] );
129     layout->setSpacing( SPACING );
130     layout->setMargin( MARGIN );
131
132     QPushButton* selBtn = new QPushButton( myGroups[i] );
133     selBtn->setIcon( image );
134     selBtn->setCheckable( true );
135     mySelectBtnGrp->addButton( selBtn, i );
136     myLabel    [i] = new QLabel( myGroups[i] );
137     myLineEdit [i] = new QLineEdit( myGroups[i] );
138     myMeshChk  [i] = new QCheckBox( tr("SMESH_SELECT_WHOLE_MESH"), myGroups[i] );
139     myFilterBtn[i] = new QPushButton( tr( "SMESH_BUT_FILTER" ), myGroups[i] );
140
141     myLineEdit[i]->setMaxLength(-1);
142     myLabel   [i]->setText( tr( getLabelText( i, true )));
143
144     layout->addWidget(myLabel    [i], 0, 0);
145     layout->addWidget(selBtn,         0, 1);
146     layout->addWidget(myLineEdit [i], 0, 2, 1, 2);
147     layout->addWidget(myFilterBtn[i], 0, 4);
148     layout->addWidget(myMeshChk  [i], 1, 0, 1, 5);
149     layout->setColumnStretch( 2, 10 );
150
151     connect( myMeshChk  [i], SIGNAL(toggled(bool)),               SLOT(onSelectMesh(bool)));
152     connect( myFilterBtn[i], SIGNAL(clicked()),                   SLOT(setFilters()));
153     connect( myLineEdit [i], SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
154     myIDSource[i] = new SMESH::ListOfIDSources;
155   }
156   connect( mySelectBtnGrp, SIGNAL(buttonClicked (int)),           SLOT(onSelectType(int)));
157   connect(mySelectionMgr, SIGNAL( currentSelectionChanged()),     SLOT(selectionIntoArgument()));
158
159   // Costruction of the logical filter for the elements: mesh/sub-mesh/group
160   QList<SUIT_SelectionFilter*> aListOfFilters;
161   aListOfFilters.append(new SMESH_TypeFilter (SMESH::MESH));
162   aListOfFilters.append(new SMESH_TypeFilter (SMESH::SUBMESH_VERTEX));
163   aListOfFilters.append(new SMESH_TypeFilter (SMESH::GROUP_NODE));
164   myFilter[0] = 
165     new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
166   aListOfFilters.append(0);
167   aListOfFilters[0] = new SMESH_TypeFilter (SMESH::MESH);
168   aListOfFilters[1] = new SMESH_TypeFilter (SMESH::SUBMESH_EDGE);
169   aListOfFilters[2] = new SMESH_TypeFilter (SMESH::GROUP_EDGE);
170   aListOfFilters[3] = new SMESH_TypeFilter (SMESH::IDSOURCE_EDGE); // for sub-mesh on group of EDGEs
171   myFilter[1] = 
172     new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
173   aListOfFilters[0] = new SMESH_TypeFilter (SMESH::MESH);
174   aListOfFilters[1] = new SMESH_TypeFilter (SMESH::SUBMESH_FACE);
175   aListOfFilters[2] = new SMESH_TypeFilter (SMESH::GROUP_FACE);
176   aListOfFilters[3] = new SMESH_TypeFilter (SMESH::IDSOURCE_FACE); // for sub-mesh on group of FACEs
177   myFilter[2] = 
178     new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
179
180   myBusy = false;
181
182   myMeshChk[0]->setChecked( true );
183   myMeshChk[1]->setChecked( true );
184   myMeshChk[2]->setChecked( true );
185   mySelectBtnGrp->button(0)->click();
186 }
187
188 //================================================================================
189 /*!
190  * \brief Destructor
191  */
192 //================================================================================
193
194 SMESHGUI_3TypesSelector::~SMESHGUI_3TypesSelector()
195 {
196   myIDSource[0].out();
197   myIDSource[1].out();
198   myIDSource[2].out();
199
200   delete myFilter[0];
201   delete myFilter[1];
202   delete myFilter[2];
203
204   if ( myFilterDlg )
205   {
206     myFilterDlg->setParent( 0 );
207     delete myFilterDlg;
208     myFilterDlg = 0;
209   }
210   disconnect(mySelectionMgr, 0, this, 0);
211 }
212
213 //================================================================================
214 /*!
215  * \brief Slot called when selection changes
216  */
217 //================================================================================
218
219 void SMESHGUI_3TypesSelector::selectionIntoArgument()
220 {
221   if (myBusy) return;
222
223   // return if dialog box is inactive
224   if ( !isEnabled() )
225     return;
226
227   // get a current element type
228   int iType = mySelectBtnGrp->checkedId();
229   if ( iType < 0 || iType > 2 )
230     return;
231
232   QString aString = "";
233   int nbObjects = 0;
234
235   // clear
236   myBusy = true;
237   myLineEdit[ iType ]->setText(aString);
238   myIDSource[ iType ]->length (nbObjects);
239   myBusy = false;
240   if ( !myGroups[ iType ]->isEnabled() )
241     return;
242
243   SMESH::SetPointRepresentation(false);
244
245   SALOME_ListIO selected;
246   mySelectionMgr->selectedObjects( selected );
247
248   if ( myMeshChk[ iType ]->isChecked() ) // objects selection
249     myIDSource[ iType ]->length( selected.Extent() ); // reserve
250   myIDSource[ iType ]->length(0);
251
252   SALOME_ListIteratorOfListIO It( selected );
253   for ( ; It.More(); It.Next() )
254   {
255     Handle(SALOME_InteractiveObject) IO = It.Value();
256
257     // get selected mesh
258     SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(IO);
259     if ( mesh->_is_nil() )
260       continue;
261     if ( !myMesh->_is_nil() &&
262          IsAnythingSelected() &&
263          myMesh->GetId() != mesh->GetId() )
264       continue; // other mesh
265     myMesh  = mesh;
266     myIO    = IO;
267     myActor = SMESH::FindActorByEntry( IO->getEntry() );
268
269     if ( myMeshChk[ iType ]->isChecked() ) // objects selection
270     {
271       SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
272       if ( idSrc->_is_nil() )
273         continue;
274       mesh = SMESH::SMESH_Mesh::_narrow( idSrc );
275       if ( !mesh->_is_nil() ) // if a mesh is selected, stop iteration
276       {
277         nbObjects = 1;
278         myIDSource[ iType ]->length( nbObjects );
279         myIDSource[ iType ][ 0 ] = idSrc;
280         aString = IO->getName();
281         break;
282       }
283       else // several groups can be selected
284       {
285         myIDSource[ iType ]->length( nbObjects + 1 );
286         myIDSource[ iType ][ nbObjects++ ] = idSrc;
287         aString += " " + QString( IO->getName() ) + " ";
288       }
289     }
290     else // get indices of selected elements
291     {
292       TColStd_IndexedMapOfInteger aMapIndex;
293       mySelector->GetIndex(IO,aMapIndex);
294       int nbElements = aMapIndex.Extent();
295       if ( nbElements > 0 )
296       {
297         SMESH::long_array_var ids = new SMESH::long_array;
298         ids->length( nbElements );
299         for ( int i = 0; i < nbElements; ++i )
300           aString += QString(" %1").arg( ids[ i ] = aMapIndex( i+1 ));
301         addTmpIdSource( ids, iType, nbObjects++ );
302       }
303       break;
304     }
305   }
306
307   myIDSource[ iType ]->length( nbObjects );
308
309   myBusy = true;
310   myLineEdit[ iType ]->setText(aString);
311   myBusy = false;
312
313   emit selectionChanged();
314 }
315
316 //================================================================================
317 /*!
318  * \brief Slot called when text changes in myLineEdit
319  */
320 //================================================================================
321
322 void SMESHGUI_3TypesSelector::onTextChange( const QString& theNewText )
323 {
324   // return if busy
325   if (myBusy) return;
326
327   // get a current element type
328   int iType = 0;
329   QLineEdit* le = (QLineEdit*) sender();
330   for ( ; iType < 3; ++iType )
331     if ( myLineEdit[ iType ] == le )
332       break;
333   if ( iType < 0 || iType > 2 )
334     return;
335   if ( !myGroups[ iType ]->isEnabled() )
336     return;
337
338   myBusy = true;
339
340   // hilight entered elements/nodes
341
342   myIDSource[ iType ]->length( 0 );
343
344   if ( !myMesh->_is_nil() )
345   {
346     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
347     if ( aListId.count() > 0 )
348     {
349       SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0;
350
351       SMESH::ElementType SMESHType = SMESH::ElementType ( iType+1 );
352       SMDSAbs_ElementType SMDSType = SMDSAbs_ElementType( iType+1 );
353       const bool isNode = ( SMDSType == SMDSAbs_Node );
354
355       SMESH::long_array_var ids = new SMESH::long_array;
356       ids->length( aListId.count() );
357       TColStd_MapOfInteger newIndices;
358       for (int i = 0; i < aListId.count(); i++) {
359         int id = aListId[ i ].toInt();
360         bool validId = false;
361         if ( id > 0 ) {
362           if ( aMesh ) {
363             const SMDS_MeshElement * e;
364             if ( isNode ) e = aMesh->FindNode( id );
365             else          e = aMesh->FindElement( id );
366             validId = ( e && e->GetType() == SMDSType );
367           } else {
368             validId = ( myMesh->GetElementType( id, !isNode ) == SMESHType );
369           }
370         }
371         if ( validId && newIndices.Add( id ))
372           ids[ newIndices.Extent()-1 ] = id;
373       }
374       if ( !newIndices.IsEmpty() ) {
375         ids->length( newIndices.Extent() );
376         addTmpIdSource( ids, iType, 0 );
377       }
378       mySelector->AddOrRemoveIndex(myIO, newIndices, false);
379       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() )
380         aViewWindow->highlight( myIO, true, true );
381     }
382   }
383
384   emit selectionChanged();
385
386   myBusy = false;
387 }
388
389 //================================================================================
390 /*!
391  * \brief Creates from ids and stores a temporary IDSource
392  */
393 //================================================================================
394
395 void SMESHGUI_3TypesSelector::addTmpIdSource( SMESH::long_array_var& ids, int iType, int index )
396 {
397   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
398   SMESH::SMESH_IDSource_var idSrc =
399     aMeshEditor->MakeIDSource( ids, SMESH::ElementType( iType+1 ));
400
401   if ( (int) myIDSource[ iType ]->length() <= index )
402     myIDSource[ iType ]->length( index + 1 );
403   myIDSource[ iType ][ index ] = idSrc;
404
405   myTmpIDSourceList.push_back( idSrc );
406 }
407
408 //================================================================================
409 /*!
410  * \brief Slot called when myMeshChk is checked
411  */
412 //================================================================================
413
414 void SMESHGUI_3TypesSelector::onSelectMesh( bool on )
415 {
416   QCheckBox* send = (QCheckBox*)sender();
417   for ( int iType = 0; iType < 3; ++iType )
418     if ( send == myMeshChk[ iType ])
419     {
420       myLabel[ iType ]->setText( tr( getLabelText( iType, on )));
421       myFilterBtn[ iType ]->setEnabled( !on );
422       myIDSource [ iType ]->length(0);
423       myBusy = true; 
424       myLineEdit [ iType ]->setText("");
425       myBusy = false; 
426       myLineEdit [ iType ]->setReadOnly( on );
427       myLineEdit [ iType ]->setValidator( on ? 0 : myIdValidator );
428       mySelectBtnGrp->button(iType)->click();
429       break;
430     }
431     else
432     {
433       
434     }
435 }
436
437 //================================================================================
438 /*!
439  * \brief Slot called when a selection button is clicked
440  */
441 //================================================================================
442
443 void SMESHGUI_3TypesSelector::onSelectType(int iType)
444 {
445   if ( iType < 0 || iType > 2 )
446     return;
447
448   myIDSource[ iType ]->length(0);
449   myLineEdit[ iType ]->setText("");
450
451   disconnect(mySelectionMgr, 0, this, 0);
452   mySelectionMgr->clearFilters();
453
454   SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
455   if ( myMeshChk[ iType ]->isChecked() )
456   {
457     if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
458     mySelectionMgr->installFilter( myFilter[ iType ]);
459   }
460   else if ( aViewWindow )
461   {
462     switch ( iType+1 ) {
463     case SMESH::NODE: aViewWindow->SetSelectionMode(NodeSelection); break;
464     case SMESH::EDGE: aViewWindow->SetSelectionMode(EdgeSelection); break;
465     case SMESH::FACE: aViewWindow->SetSelectionMode(FaceSelection); break;
466     }
467   }
468
469   myLineEdit[ iType ]->setFocus();
470
471   connect(mySelectionMgr, SIGNAL( currentSelectionChanged()), SLOT( selectionIntoArgument()));
472   selectionIntoArgument();
473 }
474
475 //================================================================================
476 /*!
477  * \brief Slot called when "Set filter" is clicked
478  */
479 //================================================================================
480
481 void SMESHGUI_3TypesSelector::setFilters()
482 {
483   if ( myMesh->_is_nil() ) {
484     SUIT_MessageBox::critical(this,
485                               tr("SMESH_ERROR"),
486                               tr("NO_MESH_SELECTED"));
487     return;
488   }
489   if ( !myFilterDlg )
490   {
491     QList<int> types;
492     types.append( SMESH::NODE );
493     types.append( SMESH::EDGE );
494     types.append( SMESH::FACE );
495     myFilterDlg = new SMESHGUI_FilterDlg( SMESHGUI::GetSMESHGUI(), types );
496   }
497
498   QPushButton* send = (QPushButton*)sender();
499   for ( int iType = 0; iType < 3; ++iType )
500     if ( send == myFilterBtn[ iType ])
501     {
502       mySelectBtnGrp->button(iType)->click();
503
504       myFilterDlg->Init( SMESH::ElementType( iType+1 ) );
505       myFilterDlg->SetSelection();
506       myFilterDlg->SetMesh( myMesh );
507       myFilterDlg->SetSourceWg( myLineEdit[ iType ]);
508       myFilterDlg->show();
509       break;
510     }
511 }
512
513 //================================================================================
514 /*!
515  * \brief Clear selection
516  */
517 //================================================================================
518
519 void SMESHGUI_3TypesSelector::Clear()
520 {
521   myBusy = true;
522   for ( int iType = 0; iType < 3; ++iType )
523   {
524     myIDSource[ iType ]->length(0);
525     myLineEdit[ iType ]->setText("");
526   }
527   myBusy = false;
528   selectionIntoArgument();
529 }
530
531 //================================================================================
532 /*!
533  * \brief Enable/disable controls of a type
534  */
535 //================================================================================
536
537 void SMESHGUI_3TypesSelector::SetEnabled( bool enable, SMESH::ElementType type )
538 {
539   myBusy = true; 
540   for ( int iType = 0; iType < 3; ++iType )
541     if ( iType+1 == type || type == SMESH::ALL )
542     {
543       myGroups[ iType ]->setEnabled( enable );
544       if ( !enable ) {
545         myIDSource[ iType ]->length(0);
546         myLineEdit[ iType ]->setText("");
547       }
548     }
549   myBusy = false;
550   selectionIntoArgument();
551 }
552
553 //================================================================================
554 /*!
555  * \brief Checks if anything is selected
556  */
557 //================================================================================
558
559 bool SMESHGUI_3TypesSelector::IsAnythingSelected( SMESH::ElementType type )
560 {
561   int nbSel = 0;
562
563   for ( int iType = 0; iType < 3; ++iType )
564     if ( iType+1 == type || type == SMESH::ALL )
565       nbSel += myIDSource[ iType ]->length();
566
567   return nbSel;
568 }
569
570 //================================================================================
571 /*!
572  * \brief Returns selected elements and most complex type of selected elements
573  */
574 //================================================================================
575
576 SMESH::ElementType SMESHGUI_3TypesSelector::GetSelected( SMESH::ListOfIDSources & nodes,
577                                                          SMESH::ListOfIDSources & edges,
578                                                          SMESH::ListOfIDSources & faces )
579 {
580   nodes = myIDSource[0];
581   edges = myIDSource[1];
582   faces = myIDSource[2];
583
584   if ( myIDSource[2]->length() > 0 ) return SMESH::FACE;
585   if ( myIDSource[1]->length() > 0 ) return SMESH::EDGE;
586   if ( myIDSource[0]->length() > 0 ) return SMESH::NODE;
587   return SMESH::ALL;
588 }
589
590 //=================================================================================
591 // function : SMESHGUI_ExtrusionDlg()
592 // purpose  : constructor
593 //=================================================================================
594
595 SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
596   : SMESHGUI_PreviewDlg( theModule ),
597     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
598 {
599   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
600   QPixmap selectImage ( mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
601   QPixmap addImage    ( mgr->loadPixmap("SMESH", tr("ICON_APPEND")));
602   QPixmap removeImage ( mgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
603
604   setModal( false );
605   setAttribute( Qt::WA_DeleteOnClose, true );
606   setWindowTitle(tr("EXTRUSION_ALONG_LINE"));
607   setSizeGripEnabled(true);
608
609   QVBoxLayout* SMESHGUI_ExtrusionDlgLayout = new QVBoxLayout(this);
610   SMESHGUI_ExtrusionDlgLayout->setSpacing(SPACING);
611   SMESHGUI_ExtrusionDlgLayout->setMargin(MARGIN);
612
613   /***************************************************************/
614   GroupArguments = new QGroupBox(tr("SMESH_EXTRUSION"), this);
615   QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
616   GroupArgumentsLayout->setSpacing(SPACING);
617   GroupArgumentsLayout->setMargin(MARGIN);
618
619   // Controls for elements selection
620   SelectorWdg = new SMESHGUI_3TypesSelector( GroupArguments );
621
622   ExtrMethod_RBut0 = new QRadioButton(GroupArguments);
623   ExtrMethod_RBut0->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") );
624   ExtrMethod_RBut1 = new QRadioButton(GroupArguments);
625   ExtrMethod_RBut1->setText( tr("SMESH_EXTRUSION_ALONG_VECTOR") );
626   ExtrMethod_RBut2 = new QRadioButton(GroupArguments);
627   ExtrMethod_RBut2->setText( tr("SMESH_EXTRUSION_BY_NORMAL") );
628
629   //Control for the Distance selection
630   TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupArguments);
631   
632   TextLabelDx = new QLabel(tr("SMESH_X"), GroupArguments);
633   SpinBox_Dx = new SMESHGUI_SpinBox(GroupArguments);
634   
635   TextLabelDy = new QLabel(tr("SMESH_Y"), GroupArguments);
636   SpinBox_Dy = new SMESHGUI_SpinBox(GroupArguments);
637
638   TextLabelDz = new QLabel(tr("SMESH_Z"), GroupArguments);
639   SpinBox_Dz = new SMESHGUI_SpinBox(GroupArguments);
640
641   // Controls for vector selection
642
643   TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments);
644
645   SelectVectorButton = new QPushButton( GroupArguments );
646   SelectVectorButton->setIcon( selectImage );
647   SelectVectorButton->setCheckable( true );
648   SelectorWdg->GetButtonGroup()->addButton( SelectVectorButton );
649
650   TextLabelVx = new QLabel(tr("SMESH_DX"), GroupArguments);
651   SpinBox_Vx = new SMESHGUI_SpinBox(GroupArguments);
652
653   TextLabelVy = new QLabel(tr("SMESH_DY"), GroupArguments);
654   SpinBox_Vy = new SMESHGUI_SpinBox(GroupArguments);
655
656   TextLabelVz = new QLabel(tr("SMESH_DZ"), GroupArguments);
657   SpinBox_Vz = new SMESHGUI_SpinBox(GroupArguments);
658
659   TextLabelDist = new QLabel(tr("SMESH_DISTANCE"), GroupArguments);
660   SpinBox_VDist = new SMESHGUI_SpinBox(GroupArguments);
661
662   // Controls for nb. steps defining
663   TextLabelNbSteps = new QLabel(tr("SMESH_NUMBEROFSTEPS"), GroupArguments);
664   SpinBox_NbSteps = new SalomeApp_IntSpinBox(GroupArguments);
665
666   // CheckBox for groups generation
667   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
668
669   // CheckBox for ByAverageNormal arg of ExtrusionByNormal()
670   ByAverageNormalCheck = new QCheckBox(tr("BY_AVERAGE_NORMAL"), GroupArguments);
671
672   // CheckBox for UseInputElemsOnly arg of ExtrusionByNormal()
673   UseInputElemsOnlyCheck = new QCheckBox(tr("USE_INPUT_ELEMS_ONLY"), GroupArguments);
674
675   //Preview check box
676   myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
677
678   // Base point
679
680   BasePointGrp = new QGroupBox(tr("BASE_POINT"), GroupArguments);
681   BasePointGrp->setCheckable(true);
682   BasePointGrp->setChecked(false);
683   QHBoxLayout* BasePointGrpLayout = new QHBoxLayout(BasePointGrp);
684   BasePointGrpLayout->setSpacing(SPACING); BasePointGrpLayout->setMargin(MARGIN);
685
686   SelectBasePointButton = new QPushButton(BasePointGrp);
687   SelectBasePointButton->setIcon(selectImage);
688   SelectBasePointButton->setCheckable(true);
689   SelectorWdg->GetButtonGroup()->addButton( SelectBasePointButton );
690
691   QLabel* XLab  = new QLabel(tr("SMESH_X"), BasePointGrp);
692   BasePoint_XSpin = new SMESHGUI_SpinBox(BasePointGrp);
693   BasePoint_XSpin->SetValue(0.);
694   QLabel* YLab  = new QLabel(tr("SMESH_Y"), BasePointGrp);
695   BasePoint_YSpin = new SMESHGUI_SpinBox(BasePointGrp);
696   BasePoint_YSpin->SetValue(0.);
697   QLabel* ZLab  = new QLabel(tr("SMESH_Z"), BasePointGrp);
698   BasePoint_ZSpin = new SMESHGUI_SpinBox(BasePointGrp);
699   BasePoint_ZSpin->SetValue(0.);
700
701   BasePointGrpLayout->addWidget(SelectBasePointButton);
702   BasePointGrpLayout->addWidget(XLab);
703   BasePointGrpLayout->addWidget(BasePoint_XSpin, 1);
704   BasePointGrpLayout->addWidget(YLab);
705   BasePointGrpLayout->addWidget(BasePoint_YSpin, 1);
706   BasePointGrpLayout->addWidget(ZLab);
707   BasePointGrpLayout->addWidget(BasePoint_ZSpin, 1);
708
709   // Scales
710
711   ScalesGrp = new QGroupBox(tr("SMESH_SCALES"), GroupArguments);
712   QGridLayout* ScalesGrpLayout = new QGridLayout( ScalesGrp );
713   ScalesGrpLayout->setSpacing(SPACING); ScalesGrpLayout->setMargin(MARGIN);
714
715   ScalesList = new QListWidget( ScalesGrp );
716   ScalesList->setSelectionMode(QListWidget::ExtendedSelection);
717
718   AddScaleButton = new QToolButton( ScalesGrp );
719   AddScaleButton->setIcon( addImage );
720
721   RemoveScaleButton = new QToolButton( ScalesGrp );
722   RemoveScaleButton->setIcon( removeImage );
723
724   ScaleSpin = new SMESHGUI_SpinBox( ScalesGrp );
725   ScaleSpin->SetValue(2);
726
727   LinearScalesCheck = new QCheckBox(tr("LINEAR_SCALES"), ScalesGrp );
728
729   ScalesGrpLayout->addWidget(ScalesList,        0, 0, 4, 1);
730   ScalesGrpLayout->addWidget(AddScaleButton,    0, 1);
731   ScalesGrpLayout->addWidget(RemoveScaleButton, 2, 1);
732   ScalesGrpLayout->addWidget(ScaleSpin,         0, 2);
733   ScalesGrpLayout->addWidget(LinearScalesCheck, 4, 0);
734   ScalesGrpLayout->setRowMinimumHeight(1, 10);
735   ScalesGrpLayout->setRowStretch(3, 10);
736
737   // layouting
738   GroupArgumentsLayout->addWidget(SelectorWdg,            0, 0, 1, 9);
739   GroupArgumentsLayout->addWidget(ExtrMethod_RBut0,       1, 0, 1, 3);
740   GroupArgumentsLayout->addWidget(ExtrMethod_RBut1,       1, 3, 1, 3);
741   GroupArgumentsLayout->addWidget(ExtrMethod_RBut2,       1, 6, 1, 3);
742   GroupArgumentsLayout->addWidget(TextLabelDistance,      2, 0);
743   GroupArgumentsLayout->addWidget(TextLabelDx,            2, 2);
744   GroupArgumentsLayout->addWidget(SpinBox_Dx,             2, 3);
745   GroupArgumentsLayout->addWidget(TextLabelDy,            2, 4);
746   GroupArgumentsLayout->addWidget(SpinBox_Dy,             2, 5);
747   GroupArgumentsLayout->addWidget(TextLabelDz,            2, 6);
748   GroupArgumentsLayout->addWidget(SpinBox_Dz,             2, 7);
749   GroupArgumentsLayout->addWidget(TextLabelVector,        3, 0);
750   GroupArgumentsLayout->addWidget(SelectVectorButton,     3, 1);
751   GroupArgumentsLayout->addWidget(TextLabelVx,            3, 2);
752   GroupArgumentsLayout->addWidget(SpinBox_Vx,             3, 3);
753   GroupArgumentsLayout->addWidget(TextLabelVy,            3, 4);
754   GroupArgumentsLayout->addWidget(SpinBox_Vy,             3, 5);
755   GroupArgumentsLayout->addWidget(TextLabelVz,            3, 6);
756   GroupArgumentsLayout->addWidget(SpinBox_Vz,             3, 7);
757   GroupArgumentsLayout->addWidget(TextLabelDist,          4, 0);
758   GroupArgumentsLayout->addWidget(SpinBox_VDist,          4, 3);
759   GroupArgumentsLayout->addWidget(TextLabelNbSteps,       5, 0, 1, 3);
760   GroupArgumentsLayout->addWidget(SpinBox_NbSteps,        5, 3);
761   GroupArgumentsLayout->addWidget(ByAverageNormalCheck,   6, 0, 1, 4);
762   GroupArgumentsLayout->addWidget(UseInputElemsOnlyCheck, 6, 4, 1, 4);
763   GroupArgumentsLayout->addWidget(BasePointGrp,           7, 0, 1, 9);
764   GroupArgumentsLayout->addWidget(ScalesGrp,              8, 0, 1, 9);
765   GroupArgumentsLayout->addWidget(myPreviewCheckBox,      9, 0, 1, 8);
766   GroupArgumentsLayout->addWidget(MakeGroupsCheck,        10,0, 1, 8);
767   GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 10, 0);
768
769   /***************************************************************/
770   GroupButtons = new QGroupBox(this);
771   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
772   GroupButtonsLayout->setSpacing(SPACING);
773   GroupButtonsLayout->setMargin(MARGIN);
774
775   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
776   buttonOk->setAutoDefault(true);
777   buttonOk->setDefault(true);
778   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
779   buttonApply->setAutoDefault(true);
780   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
781   buttonCancel->setAutoDefault(true);
782   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
783   buttonHelp->setAutoDefault(true);
784
785   GroupButtonsLayout->addWidget(buttonOk);
786   GroupButtonsLayout->addSpacing(10);
787   GroupButtonsLayout->addWidget(buttonApply);
788   GroupButtonsLayout->addSpacing(10);
789   GroupButtonsLayout->addStretch();
790   GroupButtonsLayout->addWidget(buttonCancel);
791   GroupButtonsLayout->addWidget(buttonHelp);
792
793   /***************************************************************/
794   SMESHGUI_ExtrusionDlgLayout->addWidget(GroupArguments);
795   SMESHGUI_ExtrusionDlgLayout->addWidget(GroupButtons);
796
797   /* Initialisations */
798   SpinBox_Vx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
799   SpinBox_Vy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
800   SpinBox_Vz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
801
802   SpinBox_Dx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
803   SpinBox_Dy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
804   SpinBox_Dz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
805   
806   SpinBox_NbSteps->setRange(1, 999999);
807   SpinBox_VDist->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
808
809   BasePoint_XSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
810   BasePoint_YSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
811   BasePoint_ZSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
812   ScaleSpin->RangeStepAndValidator      (COORD_MIN, COORD_MAX, 1.0, "length_precision");
813
814   ExtrMethod_RBut0->setChecked(true);
815   UseInputElemsOnlyCheck->setChecked(true);
816   MakeGroupsCheck->setChecked(true);
817
818   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
819
820   mySMESHGUI->SetActiveDialogBox(this);
821
822   myHelpFileName = "extrusion_page.html";
823
824   Init();
825
826   /***************************************************************/
827   // signals and slots connections
828   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
829   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
830   connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
831   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
832
833   connect(ExtrMethod_RBut0, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
834   connect(ExtrMethod_RBut1, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
835   connect(ExtrMethod_RBut2, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
836
837   // to update state of the Ok & Apply buttons
838   connect(SpinBox_Vx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
839   connect(SpinBox_Vy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
840   connect(SpinBox_Vz, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
841   connect(SpinBox_Dx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
842   connect(SpinBox_Dy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
843   connect(SpinBox_Dz, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
844
845   connect(AddScaleButton,    SIGNAL(clicked()), this, SLOT(OnScaleAdded()));
846   connect(RemoveScaleButton, SIGNAL(clicked()), this, SLOT(OnScaleRemoved()));
847
848   connect(SelectVectorButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
849   connect(SelectBasePointButton,SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
850   connect(BasePointGrp,         SIGNAL(toggled(bool)), this, SLOT(SetEditCurrentArgument()));
851   connect(BasePointGrp,         SIGNAL(toggled(bool)), SelectBasePointButton, SLOT(click()));
852   connect(mySMESHGUI,           SIGNAL(SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
853   connect(mySelectionMgr,       SIGNAL(currentSelectionChanged()), SLOT(toDisplaySimulation()));
854   connect(SelectorWdg,          SIGNAL(selectionChanged()), this, SLOT(toDisplaySimulation()));
855   connect(SelectorWdg,          SIGNAL(selectionChanged()), this, SLOT(CheckIsEnable()));
856   /* to close dialog if study change */
857   connect(mySMESHGUI,           SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
858   connect(mySMESHGUI,           SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
859   connect(mySMESHGUI,           SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
860
861   connect(SpinBox_Dx,      SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
862   connect(SpinBox_Dy,      SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
863   connect(SpinBox_Dz,      SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
864   connect(SpinBox_Vx,      SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
865   connect(SpinBox_Vy,      SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
866   connect(SpinBox_Vz,      SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
867   connect(SpinBox_VDist,   SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
868   connect(SpinBox_NbSteps, SIGNAL(valueChanged(int)),    this, SLOT(toDisplaySimulation()));
869   connect(ByAverageNormalCheck,   SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
870   connect(UseInputElemsOnlyCheck, SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
871   connect(AddScaleButton,         SIGNAL(clicked()),     this, SLOT(toDisplaySimulation()));
872   connect(RemoveScaleButton,      SIGNAL(clicked()),     this, SLOT(toDisplaySimulation()));
873   connect(LinearScalesCheck,      SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
874   connect(BasePointGrp,           SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
875   connect(BasePoint_XSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
876   connect(BasePoint_YSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
877   connect(BasePoint_ZSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
878
879   //To Connect preview check box
880   connectPreviewControl();
881
882   /***************************************************************/
883   
884   ClickOnRadio();
885 }
886
887 //=================================================================================
888 // function : ~SMESHGUI_ExtrusionDlg()
889 // purpose  : destructor
890 //=================================================================================
891 SMESHGUI_ExtrusionDlg::~SMESHGUI_ExtrusionDlg()
892 {
893 }
894
895 //=================================================================================
896 // function : Init()
897 // purpose  : initialization
898 //=================================================================================
899 void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
900 {
901   if (ResetControls)
902   {
903     SpinBox_NbSteps->setValue(1);
904     SpinBox_VDist->setValue(10);
905     SpinBox_Dx->SetValue(0);
906     SpinBox_Dy->SetValue(0);
907     SpinBox_Dz->SetValue(0);
908     SpinBox_Vx->SetValue(0);
909     SpinBox_Vy->SetValue(0);
910     SpinBox_Vz->SetValue(0);
911
912     myPreviewCheckBox->setChecked(false);
913     onDisplaySimulation(false);
914   }
915   SelectorWdg->Clear();
916   CheckIsEnable();
917 }
918
919 //=================================================================================
920 // function : CheckIsEnable()
921 // purpose  : Check whether the Ok and Apply buttons should be enabled or not
922 //=================================================================================
923 void SMESHGUI_ExtrusionDlg::CheckIsEnable()
924 {  
925   bool anIsEnable = SelectorWdg->IsAnythingSelected() && isValuesValid();
926
927   buttonOk->setEnabled(anIsEnable);
928   buttonApply->setEnabled(anIsEnable);
929 }
930
931 //=================================================================================
932 // function : isValuesValid()
933 // purpose  : Return true in case if values entered into dialog are valid
934 //=================================================================================
935 bool SMESHGUI_ExtrusionDlg::isValuesValid()
936 {
937   double aX, aY, aZ, aModule = 0;
938   if ( ExtrMethod_RBut0->isChecked() )
939   {
940     aX = SpinBox_Dx->GetValue();
941     aY = SpinBox_Dy->GetValue();
942     aZ = SpinBox_Dz->GetValue();
943     aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
944   }
945   else if ( ExtrMethod_RBut1->isChecked() )
946   {
947     aX = SpinBox_Vx->GetValue();
948     aY = SpinBox_Vy->GetValue();
949     aZ = SpinBox_Vz->GetValue();
950     aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
951     double aVDist = (double)SpinBox_VDist->value();
952     aModule *= aVDist;
953   }
954   else if ( ExtrMethod_RBut2->isChecked() )
955   {
956     aModule = Abs((double)SpinBox_VDist->value());
957   }
958   
959   return aModule > 1.0E-38;
960 }
961
962 //=======================================================================
963 //function : getScaleParams
964 //purpose  : return 3 scaling parameters
965 //=======================================================================
966
967 bool SMESHGUI_ExtrusionDlg::getScaleParams( SMESH::double_array*& scales,
968                                             SMESH::double_array*& basePoint )
969 {
970   scales = new SMESH::double_array;
971   scales->length( myScalesList.count() );
972   for ( int i = 0; i < myScalesList.count(); ++i )
973     (*scales)[i] = myScalesList[i];
974
975   basePoint = new SMESH::double_array;
976   if ( BasePointGrp->isChecked() )
977   {
978     basePoint->length( 3 );
979     (*basePoint)[0] = BasePoint_XSpin->GetValue();
980     (*basePoint)[1] = BasePoint_YSpin->GetValue();
981     (*basePoint)[2] = BasePoint_ZSpin->GetValue();
982   }
983
984   return ( scales->length() > 0 && LinearScalesCheck->isChecked() );
985 }
986
987 //=================================================================================
988 // function : ClickOnRadio()
989 // purpose  : Radio button management
990 //=================================================================================
991
992 void SMESHGUI_ExtrusionDlg::ClickOnRadio()
993 {
994   if ( ExtrMethod_RBut0->isChecked() )
995   {
996     TextLabelDistance->show();
997     TextLabelDx->show();
998     SpinBox_Dx->show();
999     TextLabelDy->show();
1000     SpinBox_Dy->show();
1001     TextLabelDz->show();
1002     SpinBox_Dz->show();
1003
1004     TextLabelVector->hide();
1005     TextLabelVx->hide();
1006     SpinBox_Vx->hide();
1007     TextLabelVy->hide();
1008     SpinBox_Vy->hide();
1009     TextLabelVz->hide();
1010     SpinBox_Vz->hide();
1011     TextLabelDist->hide();
1012     SpinBox_VDist->hide();
1013     SelectVectorButton->hide();
1014
1015     ByAverageNormalCheck->hide();
1016     UseInputElemsOnlyCheck->hide();
1017
1018     SelectorWdg->SetEnabled( true, SMESH::ALL );
1019   }
1020   else if ( ExtrMethod_RBut1->isChecked() )
1021   {
1022     TextLabelDistance->hide();
1023     TextLabelDx->hide();
1024     SpinBox_Dx->hide();
1025     TextLabelDy->hide();
1026     SpinBox_Dy->hide();
1027     TextLabelDz->hide();
1028     SpinBox_Dz->hide();
1029
1030     TextLabelVector->show();
1031     TextLabelVx->show();
1032     SpinBox_Vx->show();
1033     TextLabelVy->show();
1034     SpinBox_Vy->show();
1035     TextLabelVz->show();
1036     SpinBox_Vz->show();
1037     TextLabelDist->show();
1038     SpinBox_VDist->show();
1039     SelectVectorButton->show();
1040
1041     ByAverageNormalCheck->hide();
1042     UseInputElemsOnlyCheck->hide();
1043
1044     SelectorWdg->SetEnabled( true, SMESH::ALL );
1045   }
1046   else if ( ExtrMethod_RBut2->isChecked() )
1047   {
1048     TextLabelDistance->hide();
1049     TextLabelDx->hide();
1050     SpinBox_Dx->hide();
1051     TextLabelDy->hide();
1052     SpinBox_Dy->hide();
1053     TextLabelDz->hide();
1054     SpinBox_Dz->hide();
1055
1056     TextLabelVector->hide();
1057     TextLabelVx->hide();
1058     SpinBox_Vx->hide();
1059     TextLabelVy->hide();
1060     SpinBox_Vy->hide();
1061     TextLabelVz->hide();
1062     SpinBox_Vz->hide();
1063
1064     TextLabelDist->show();
1065     SpinBox_VDist->show();
1066     SelectVectorButton->hide();
1067
1068     ByAverageNormalCheck->show();
1069     UseInputElemsOnlyCheck->show();
1070
1071     SelectorWdg->SetEnabled( false, SMESH::NODE );
1072     SelectorWdg->SetEnabled( false, SMESH::EDGE );
1073   }
1074
1075   CheckIsEnable();
1076
1077   onDisplaySimulation(true);
1078   // AdjustSize
1079   qApp->processEvents();
1080   updateGeometry();
1081   resize( minimumSizeHint() );
1082 }
1083
1084 //=================================================================================
1085 // function : ClickOnApply()
1086 // purpose  : Called when user presses <Apply> button
1087 //=================================================================================
1088
1089 bool SMESHGUI_ExtrusionDlg::ClickOnApply()
1090 {
1091   if (mySMESHGUI->isActiveStudyLocked())
1092     return false;
1093
1094   if (!isValid())
1095     return false;
1096
1097   if ( SelectorWdg->IsAnythingSelected() )
1098   {
1099     SMESH::DirStruct aVector;
1100     getExtrusionVector(aVector);
1101
1102     QStringList aParameters;
1103     if ( ExtrMethod_RBut0->isChecked() )
1104     {
1105       aParameters << SpinBox_Dx->text();
1106       aParameters << SpinBox_Dy->text();
1107       aParameters << SpinBox_Dz->text();
1108     }
1109     else if ( ExtrMethod_RBut1->isChecked() )
1110     {
1111       // only 3 coords in a python dump command :(
1112       // aParameters << SpinBox_Vx->text();
1113       // aParameters << SpinBox_Vy->text();
1114       // aParameters << SpinBox_Vz->text();
1115       // aParameters << SpinBox_VDist->text();
1116     }
1117     else if ( ExtrMethod_RBut2->isChecked() )
1118     {
1119       aParameters << SpinBox_VDist->text();
1120     }
1121
1122     long aNbSteps = (long)SpinBox_NbSteps->value();
1123     aParameters << SpinBox_NbSteps->text();
1124
1125     SMESH::double_array_var scales = new SMESH::double_array;
1126     scales->length( myScalesList.count() );
1127     for (int i = 0; i < myScalesList.count(); i++)
1128     {
1129       scales[i] = myScalesList[i];
1130       aParameters << ScalesList->item(i)->text();
1131     }
1132
1133     bool meshHadNewTypeBefore = true;
1134     int  maxSelType = 0;
1135     const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
1136
1137     try
1138     {
1139       SUIT_OverrideCursor aWaitCursor;
1140
1141       SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh();
1142
1143       SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
1144       SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
1145       SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
1146       maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
1147
1148       // is it necessary to switch on the next Display Mode?
1149       SMESH::ElementType newType = (SMESH::ElementType)( maxSelType + 1 );
1150       SMESH::array_of_ElementType_var oldTypes = mesh->GetTypes();
1151       meshHadNewTypeBefore = false;
1152       for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
1153         meshHadNewTypeBefore = ( oldTypes[i] >= newType );
1154
1155       SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditor();
1156       SMESH::ListOfGroups_var groups;
1157
1158       mesh->SetParameters( aParameters.join(":").toLatin1().constData() );
1159
1160       if ( ExtrMethod_RBut2->isVisible() &&
1161            ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
1162       {
1163         double stepSize          = (double) SpinBox_VDist->value();
1164         long   nbSteps           = (long) SpinBox_NbSteps->value();
1165         bool   useInputElemsOnly = UseInputElemsOnlyCheck->isChecked();
1166         bool   byAverageNormal   = ByAverageNormalCheck->isChecked();
1167         int    dim               = (maxSelType == SMESH::FACE) ? 2 : 1;
1168
1169         groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, useInputElemsOnly,
1170                                                 byAverageNormal, makeGroups, dim );
1171       }
1172       else
1173       {
1174         SMESH::double_array_var scales, basePoint;
1175         bool linVariation = getScaleParams( scales.out(), basePoint.out() );
1176         groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
1177                                                     aVector, aNbSteps,
1178                                                     scales, linVariation, basePoint,
1179                                                     makeGroups );
1180       }
1181
1182     } catch (...) {
1183     }
1184
1185     SMESH_Actor* actor = SelectorWdg->GetActor();
1186     if ( actor && !meshHadNewTypeBefore )
1187     {
1188       unsigned int aMode = actor->GetEntityMode();
1189       switch ( maxSelType ) {
1190       case SMESH::NODE: // extrude node -> edges
1191         actor->SetRepresentation(SMESH_Actor::eEdge);
1192         actor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
1193       case SMESH::EDGE: // edge -> faces
1194         actor->SetRepresentation(SMESH_Actor::eSurface);
1195         actor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
1196       case SMESH::FACE: // faces -> volumes
1197         actor->SetRepresentation(SMESH_Actor::eSurface);
1198         actor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
1199       }
1200     }
1201     if ( actor )
1202       SMESH::Update( actor->getIO(), actor->GetVisibility() );
1203     if ( makeGroups )
1204       mySMESHGUI->updateObjBrowser(true); // new groups may appear
1205     Init(false);
1206     mySelectionMgr->clearSelected();
1207     SelectorWdg->Clear();
1208
1209     SMESHGUI::Modified();
1210   }
1211   return true;
1212 }
1213
1214 //=================================================================================
1215 // function : ClickOnOk()
1216 // purpose  : Called when user presses <OK> button
1217 //=================================================================================
1218 void SMESHGUI_ExtrusionDlg::ClickOnOk()
1219 {
1220   if (ClickOnApply())
1221     reject();
1222 }
1223
1224 //=================================================================================
1225 // function : reject()
1226 // purpose  : Called when dialog box is closed
1227 //=================================================================================
1228 void SMESHGUI_ExtrusionDlg::reject()
1229 {
1230   disconnect(mySelectionMgr, 0, this, 0);
1231   mySelectionMgr->clearFilters();
1232   //mySelectionMgr->clearSelected();
1233   if (SMESH::GetCurrentVtkView()) {
1234     SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
1235     SMESH::SetPointRepresentation(false);
1236     SMESH::SetPickable();
1237   }
1238   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1239     aViewWindow->SetSelectionMode(ActorSelection);
1240   mySMESHGUI->ResetState();
1241
1242   QDialog::reject();
1243 }
1244
1245 //=================================================================================
1246 // function : onOpenView()
1247 // purpose  :
1248 //=================================================================================
1249 void SMESHGUI_ExtrusionDlg::onOpenView()
1250 {
1251   if ( mySelector ) {
1252     SMESH::SetPointRepresentation(false);
1253   }
1254   else {
1255     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
1256     ActivateThisDialog();
1257   }
1258 }
1259
1260 //=================================================================================
1261 // function : onCloseView()
1262 // purpose  :
1263 //=================================================================================
1264 void SMESHGUI_ExtrusionDlg::onCloseView()
1265 {
1266   DeactivateActiveDialog();
1267   mySelector = 0;
1268 }
1269
1270 //=================================================================================
1271 // function : ClickOnHelp()
1272 // purpose  :
1273 //=================================================================================
1274 void SMESHGUI_ExtrusionDlg::ClickOnHelp()
1275 {
1276   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1277   if (app) 
1278     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
1279   else {
1280     QString platform;
1281 #ifdef WIN32
1282     platform = "winapplication";
1283 #else
1284     platform = "application";
1285 #endif
1286     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
1287                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1288                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
1289                                                                  platform)).
1290                              arg(myHelpFileName));
1291   }
1292 }
1293
1294 //=================================================================================
1295 // function : SelectionIntoArgument()
1296 // purpose  : Called when selection has changed or other case
1297 //=================================================================================
1298 void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
1299 {
1300   // return if dialog box is inactive
1301   if (!GroupButtons->isEnabled())
1302     return;
1303
1304   SALOME_ListIO aList;
1305   mySelectionMgr->selectedObjects(aList);
1306   if ( aList.IsEmpty() || aList.Extent() > 1 )
1307     return;
1308
1309   if ( SelectVectorButton->isChecked() )
1310   {
1311     Handle(SALOME_InteractiveObject) IO = aList.First();
1312     TColStd_IndexedMapOfInteger aMapIndex;
1313     mySelector->GetIndex(IO,aMapIndex);
1314     if ( aMapIndex.Extent() != 1 )
1315       return;
1316     SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() );
1317     SMDS_Mesh*     aMesh = anActor ? anActor->GetObject()->GetMesh() : 0;
1318     if ( !aMesh )
1319       return;
1320
1321     const SMDS_MeshFace* face =
1322       dynamic_cast<const SMDS_MeshFace*>(aMesh->FindElement(aMapIndex(1)));
1323     if (!face)
1324       return;
1325
1326     gp_XYZ aNormale = SMESH::getNormale(face);
1327     SpinBox_Vx->SetValue(aNormale.X());
1328     SpinBox_Vy->SetValue(aNormale.Y());
1329     SpinBox_Vz->SetValue(aNormale.Z());
1330   }
1331   else if ( SelectBasePointButton->isChecked() )
1332   {
1333     if (!BasePointGrp->isChecked())
1334       return;
1335
1336     // try to get shape from selection
1337     Handle(SALOME_InteractiveObject) IO = aList.First();
1338
1339     // check if geom vertex is selected
1340     GEOM::GEOM_Object_var aGeomObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(IO);
1341     TopoDS_Vertex aVertex;
1342     if (!aGeomObj->_is_nil()) {
1343       if (aGeomObj->IsShape() && GEOMBase::GetShape(aGeomObj, aVertex) && !aVertex.IsNull()) {
1344         gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
1345         BasePoint_XSpin->SetValue(aPnt.X());
1346         BasePoint_YSpin->SetValue(aPnt.Y());
1347         BasePoint_ZSpin->SetValue(aPnt.Z());
1348       }
1349     }
1350
1351     if ( aVertex.IsNull() )
1352     {
1353       // check if smesh node is selected
1354       SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(IO);
1355       if (aMesh->_is_nil())
1356         return;
1357
1358       QString aString;
1359       int aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
1360       // return if more than one node is selected
1361       if (aNbUnits != 1)
1362         return;
1363
1364       SMESH_Actor* aMeshActor = SMESH::FindActorByObject(aMesh);
1365       if (!aMeshActor)
1366         return;
1367
1368       SMDS_Mesh* mesh = aMeshActor->GetObject()->GetMesh();
1369       if (!mesh)
1370         return;
1371
1372       const SMDS_MeshNode* n = mesh->FindNode(aString.toLong());
1373       if (!n)
1374         return;
1375
1376       BasePoint_XSpin->SetValue(n->X());
1377       BasePoint_YSpin->SetValue(n->Y());
1378       BasePoint_ZSpin->SetValue(n->Z());
1379     }
1380   }
1381
1382   onDisplaySimulation(true);
1383   CheckIsEnable();
1384 }
1385
1386 //=================================================================================
1387 // function : SetEditCurrentArgument()
1388 // purpose  :
1389 //=================================================================================
1390 void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
1391 {
1392   QPushButton* send = (QPushButton*)sender();
1393
1394   disconnect(mySelectionMgr, 0, this, 0);
1395   mySelectionMgr->clearSelected();
1396   mySelectionMgr->clearFilters();
1397
1398   if (send == SelectVectorButton)
1399   {
1400     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1401       aViewWindow->SetSelectionMode(FaceSelection);
1402   }
1403   else if ( send == SelectBasePointButton )
1404   {
1405     SMESH::SetPointRepresentation(true);
1406     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1407       aViewWindow->SetSelectionMode(NodeSelection);
1408
1409     SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter(SMESH::IDSOURCE);
1410     SMESH_NumberFilter* aVertexFilter      = new SMESH_NumberFilter ("GEOM", TopAbs_VERTEX,
1411                                                                      1, TopAbs_VERTEX);
1412     QList<SUIT_SelectionFilter*> aListOfFilters;
1413     aListOfFilters << aMeshOrSubMeshFilter << aVertexFilter;
1414
1415     mySelectionMgr->installFilter(new SMESH_LogicalFilter
1416                                   (aListOfFilters, SMESH_LogicalFilter::LO_OR, true));
1417   }
1418   
1419   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
1420   SelectionIntoArgument();
1421 }
1422
1423 //=================================================================================
1424 // function : DeactivateActiveDialog()
1425 // purpose  : Deactivates this dialog
1426 //=================================================================================
1427 void SMESHGUI_ExtrusionDlg::DeactivateActiveDialog()
1428 {
1429   if (GroupButtons->isEnabled())
1430   {
1431     GroupArguments->setEnabled(false);
1432     GroupButtons->setEnabled(false);
1433     SelectorWdg->setEnabled(false);
1434     mySMESHGUI->ResetState();
1435     mySMESHGUI->SetActiveDialogBox(0);
1436   }
1437 }
1438
1439 //=================================================================================
1440 // function : ActivateThisDialog()
1441 // purpose  : Activates this dialog
1442 //=================================================================================
1443 void SMESHGUI_ExtrusionDlg::ActivateThisDialog()
1444 {
1445   // Emit a signal to deactivate the active dialog
1446   mySMESHGUI->EmitSignalDeactivateDialog();
1447   GroupArguments->setEnabled(true);
1448   GroupButtons->setEnabled(true);
1449   SelectorWdg->setEnabled(true);
1450
1451   mySMESHGUI->SetActiveDialogBox(this);
1452 }
1453
1454 //=================================================================================
1455 // function : enterEvent()
1456 // purpose  :
1457 //=================================================================================
1458 void SMESHGUI_ExtrusionDlg::enterEvent (QEvent*)
1459 {
1460   if ( !GroupButtons->isEnabled() ) {
1461     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
1462     if ( aViewWindow && !mySelector) {
1463       mySelector = aViewWindow->GetSelector();
1464     }
1465     ActivateThisDialog();
1466   }
1467 }
1468
1469 //=================================================================================
1470 // function : keyPressEvent()
1471 // purpose  :
1472 //=================================================================================
1473 void SMESHGUI_ExtrusionDlg::keyPressEvent( QKeyEvent* e )
1474 {
1475   QDialog::keyPressEvent( e );
1476   if ( e->isAccepted() )
1477     return;
1478
1479   if ( e->key() == Qt::Key_F1 ) {
1480     e->accept();
1481     ClickOnHelp();
1482   }
1483 }
1484
1485 //=================================================================================
1486 // function : isValid
1487 // purpose  :
1488 //=================================================================================
1489 bool SMESHGUI_ExtrusionDlg::isValid()
1490 {
1491   QString msg;
1492   bool ok = true;
1493   if ( ExtrMethod_RBut0->isChecked() ) {
1494     ok = SpinBox_Dx->isValid( msg, true ) && ok;
1495     ok = SpinBox_Dy->isValid( msg, true ) && ok;
1496     ok = SpinBox_Dz->isValid( msg, true ) && ok;
1497   } else if ( ExtrMethod_RBut1->isChecked() ) {
1498     ok = SpinBox_Vx->isValid( msg, true ) && ok;
1499     ok = SpinBox_Vy->isValid( msg, true ) && ok;
1500     ok = SpinBox_Vz->isValid( msg, true ) && ok;
1501     ok = SpinBox_VDist->isValid( msg, true ) && ok;
1502   }
1503   ok = SpinBox_NbSteps->isValid( msg, true ) && ok;
1504
1505   if ( BasePointGrp->isChecked()) {
1506     ok = BasePoint_XSpin->isValid( msg, true ) && ok;
1507     ok = BasePoint_YSpin->isValid( msg, true ) && ok;
1508     ok = BasePoint_ZSpin->isValid( msg, true ) && ok;
1509   }
1510
1511   if( !ok ) {
1512     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
1513     if ( !msg.isEmpty() )
1514       str += "\n" + msg;
1515     SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
1516     return false;
1517   }
1518   return true;
1519 }
1520
1521 //=================================================================================
1522 // function : onDisplaySimulation
1523 // purpose  : Show/Hide preview
1524 //=================================================================================
1525 void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview )
1526 {
1527   if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
1528     if ( SelectorWdg->IsAnythingSelected() && isValid() && isValuesValid())
1529     {
1530       //Get input vector
1531       SMESH::DirStruct aVector;
1532       getExtrusionVector(aVector);
1533
1534       //Get Number of the steps
1535       long aNbSteps = (long)SpinBox_NbSteps->value();
1536       try
1537       {
1538         SUIT_OverrideCursor aWaitCursor;
1539
1540         SMESH::SMESH_Mesh_var             mesh = SelectorWdg->GetMesh();
1541         SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditPreviewer();
1542         SMESH::ListOfGroups_var         groups;
1543
1544         SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
1545         SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
1546         SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
1547         const int  maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
1548         const bool makeGroups = false;
1549
1550         if ( ExtrMethod_RBut2->isVisible() &&
1551              ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
1552         {
1553           double stepSize          = (double) SpinBox_VDist->value();
1554           long   nbSteps           = (long) SpinBox_NbSteps->value();
1555           bool   useInputElemsOnly = UseInputElemsOnlyCheck->isChecked();
1556           bool   byAverageNormal   = ByAverageNormalCheck->isChecked();
1557           int    dim               = (maxSelType == SMESH::FACE) ? 2 : 1;
1558
1559           groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, useInputElemsOnly,
1560                                                   byAverageNormal, makeGroups, dim );
1561         }
1562         else
1563         {
1564           SMESH::double_array_var scales, basePoint;
1565           bool linVariation = getScaleParams( scales.out(), basePoint.out() );
1566           groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
1567                                                       aVector, aNbSteps,
1568                                                       scales, linVariation, basePoint,
1569                                                       makeGroups );
1570         }
1571         SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
1572         mySimulation->SetData(aMeshPreviewStruct._retn());
1573
1574       } catch (...) {
1575         hidePreview();
1576       }
1577     } else {
1578       hidePreview();
1579     }
1580   } else {
1581     hidePreview();
1582   }
1583 }
1584
1585 //=================================================================================
1586 // function : getExtrusionVector()
1587 // purpose  : get direction of the extrusion
1588 //=================================================================================
1589 void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector)
1590 {
1591   if ( ExtrMethod_RBut0->isChecked() )
1592   {
1593     aVector.PS.x = SpinBox_Dx->GetValue();
1594     aVector.PS.y = SpinBox_Dy->GetValue();
1595     aVector.PS.z = SpinBox_Dz->GetValue();
1596   }
1597   else if ( ExtrMethod_RBut1->isChecked() )
1598   {
1599     gp_XYZ aNormale(SpinBox_Vx->GetValue(),
1600                     SpinBox_Vy->GetValue(),
1601                     SpinBox_Vz->GetValue());
1602     aNormale /= aNormale.Modulus();
1603     double aVDist = (double)SpinBox_VDist->value();
1604
1605     aVector.PS.x = aNormale.X()*aVDist;
1606     aVector.PS.y = aNormale.Y()*aVDist;
1607     aVector.PS.z = aNormale.Z()*aVDist;
1608   }
1609 }
1610
1611 //=======================================================================
1612 // function : OnScaleAdded()
1613 // purpose  : Called when user adds Scale to the list
1614 //=======================================================================
1615 void SMESHGUI_ExtrusionDlg::OnScaleAdded()
1616 {
1617   QString msg;
1618   if( !ScaleSpin->isValid( msg, true ) ) {
1619     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
1620     if ( !msg.isEmpty() )
1621       str += "\n" + msg;
1622     SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
1623     return;
1624   }
1625   ScalesList->addItem(ScaleSpin->text());
1626   myScalesList.append(ScaleSpin->GetValue());
1627 }
1628
1629 //=======================================================================
1630 // function : OnScaleRemoved()
1631 // purpose  : Called when user removes Scale(s) from the list
1632 //=======================================================================
1633 void SMESHGUI_ExtrusionDlg::OnScaleRemoved()
1634 {
1635   QList<QListWidgetItem*> aList = ScalesList->selectedItems();
1636   QListWidgetItem* anItem;
1637   int row = 0;
1638   foreach(anItem, aList) {
1639     row = ScalesList->row(anItem);
1640     myScalesList.removeAt(row);
1641     delete anItem;
1642   }
1643   ScalesList->setCurrentRow( row, QItemSelectionModel::Select );
1644 }