Salome HOME
Crash after pre-viewing mesh translation
[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   // highlight 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.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   BasePointGrp->setEnabled( !ExtrMethod_RBut2->isChecked() );
1076   ScalesGrp   ->setEnabled( !ExtrMethod_RBut2->isChecked() );
1077
1078
1079   CheckIsEnable();
1080
1081   onDisplaySimulation(true);
1082   // AdjustSize
1083   qApp->processEvents();
1084   updateGeometry();
1085   resize( minimumSizeHint() );
1086 }
1087
1088 //=================================================================================
1089 // function : ClickOnApply()
1090 // purpose  : Called when user presses <Apply> button
1091 //=================================================================================
1092
1093 bool SMESHGUI_ExtrusionDlg::ClickOnApply()
1094 {
1095   if (SMESHGUI::isStudyLocked())
1096     return false;
1097
1098   if (!isValid())
1099     return false;
1100
1101   if ( SelectorWdg->IsAnythingSelected() )
1102   {
1103     SMESH::DirStruct aVector;
1104     getExtrusionVector(aVector);
1105
1106     QStringList aParameters;
1107     if ( ExtrMethod_RBut0->isChecked() )
1108     {
1109       aParameters << SpinBox_Dx->text();
1110       aParameters << SpinBox_Dy->text();
1111       aParameters << SpinBox_Dz->text();
1112     }
1113     else if ( ExtrMethod_RBut1->isChecked() )
1114     {
1115       // only 3 coords in a python dump command :(
1116       // aParameters << SpinBox_Vx->text();
1117       // aParameters << SpinBox_Vy->text();
1118       // aParameters << SpinBox_Vz->text();
1119       // aParameters << SpinBox_VDist->text();
1120     }
1121     else if ( ExtrMethod_RBut2->isChecked() )
1122     {
1123       aParameters << SpinBox_VDist->text();
1124     }
1125
1126     long aNbSteps = (long)SpinBox_NbSteps->value();
1127     aParameters << SpinBox_NbSteps->text();
1128
1129     SMESH::double_array_var scales = new SMESH::double_array;
1130     scales->length( myScalesList.count() );
1131     for (int i = 0; i < myScalesList.count(); i++)
1132     {
1133       scales[i] = myScalesList[i];
1134       aParameters << ScalesList->item(i)->text();
1135     }
1136
1137     bool meshHadNewTypeBefore = true;
1138     int  maxSelType = 0;
1139     const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
1140
1141     try
1142     {
1143       SUIT_OverrideCursor aWaitCursor;
1144
1145       SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh();
1146
1147       SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
1148       SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
1149       SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
1150       maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
1151
1152       // is it necessary to switch on the next Display Mode?
1153       SMESH::ElementType newType = (SMESH::ElementType)( maxSelType + 1 );
1154       SMESH::array_of_ElementType_var oldTypes = mesh->GetTypes();
1155       meshHadNewTypeBefore = false;
1156       for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
1157         meshHadNewTypeBefore = ( oldTypes[i] >= newType );
1158
1159       SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditor();
1160       SMESH::ListOfGroups_var groups;
1161
1162       mesh->SetParameters( aParameters.join(":").toUtf8().constData() );
1163
1164       if ( ExtrMethod_RBut2->isVisible() &&
1165            ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
1166       {
1167         double stepSize          = (double) SpinBox_VDist->value();
1168         long   nbSteps           = (long) SpinBox_NbSteps->value();
1169         bool   useInputElemsOnly = UseInputElemsOnlyCheck->isChecked();
1170         bool   byAverageNormal   = ByAverageNormalCheck->isChecked();
1171         int    dim               = (maxSelType == SMESH::FACE) ? 2 : 1;
1172
1173         groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, useInputElemsOnly,
1174                                                 byAverageNormal, makeGroups, dim );
1175       }
1176       else
1177       {
1178         SMESH::double_array_var scales, basePoint;
1179         bool linVariation = getScaleParams( scales.out(), basePoint.out() );
1180         groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
1181                                                     aVector, aNbSteps,
1182                                                     scales, linVariation, basePoint,
1183                                                     makeGroups );
1184       }
1185
1186     } catch (...) {
1187     }
1188
1189     SMESH_Actor* actor = SelectorWdg->GetActor();
1190     if ( actor && !meshHadNewTypeBefore )
1191     {
1192       unsigned int aMode = actor->GetEntityMode();
1193       switch ( maxSelType ) {
1194       case SMESH::NODE: // extrude node -> edges
1195         actor->SetRepresentation(SMESH_Actor::eEdge);
1196         actor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
1197       case SMESH::EDGE: // edge -> faces
1198         actor->SetRepresentation(SMESH_Actor::eSurface);
1199         actor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
1200       case SMESH::FACE: // faces -> volumes
1201         actor->SetRepresentation(SMESH_Actor::eSurface);
1202         actor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
1203       }
1204     }
1205     if ( actor )
1206       SMESH::Update( actor->getIO(), actor->GetVisibility() );
1207     if ( makeGroups )
1208       mySMESHGUI->updateObjBrowser(true); // new groups may appear
1209     Init(false);
1210     mySelectionMgr->clearSelected();
1211     SelectorWdg->Clear();
1212
1213     SMESHGUI::Modified();
1214   }
1215   return true;
1216 }
1217
1218 //=================================================================================
1219 // function : ClickOnOk()
1220 // purpose  : Called when user presses <OK> button
1221 //=================================================================================
1222 void SMESHGUI_ExtrusionDlg::ClickOnOk()
1223 {
1224   if (ClickOnApply())
1225     reject();
1226 }
1227
1228 //=================================================================================
1229 // function : reject()
1230 // purpose  : Called when dialog box is closed
1231 //=================================================================================
1232 void SMESHGUI_ExtrusionDlg::reject()
1233 {
1234   disconnect(mySelectionMgr, 0, this, 0);
1235   mySelectionMgr->clearFilters();
1236   //mySelectionMgr->clearSelected();
1237   if (SMESH::GetCurrentVtkView()) {
1238     SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
1239     SMESH::SetPointRepresentation(false);
1240     SMESH::SetPickable();
1241   }
1242   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1243     aViewWindow->SetSelectionMode(ActorSelection);
1244   mySMESHGUI->ResetState();
1245
1246   QDialog::reject();
1247 }
1248
1249 //=================================================================================
1250 // function : onOpenView()
1251 // purpose  :
1252 //=================================================================================
1253 void SMESHGUI_ExtrusionDlg::onOpenView()
1254 {
1255   if ( mySelector ) {
1256     SMESH::SetPointRepresentation(false);
1257   }
1258   else {
1259     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
1260     ActivateThisDialog();
1261   }
1262 }
1263
1264 //=================================================================================
1265 // function : onCloseView()
1266 // purpose  :
1267 //=================================================================================
1268 void SMESHGUI_ExtrusionDlg::onCloseView()
1269 {
1270   DeactivateActiveDialog();
1271   mySelector = 0;
1272 }
1273
1274 //=================================================================================
1275 // function : ClickOnHelp()
1276 // purpose  :
1277 //=================================================================================
1278 void SMESHGUI_ExtrusionDlg::ClickOnHelp()
1279 {
1280   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1281   if (app) 
1282     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
1283   else {
1284     QString platform;
1285 #ifdef WIN32
1286     platform = "winapplication";
1287 #else
1288     platform = "application";
1289 #endif
1290     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
1291                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1292                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
1293                                                                  platform)).
1294                              arg(myHelpFileName));
1295   }
1296 }
1297
1298 //=================================================================================
1299 // function : SelectionIntoArgument()
1300 // purpose  : Called when selection has changed or other case
1301 //=================================================================================
1302 void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
1303 {
1304   // return if dialog box is inactive
1305   if (!GroupButtons->isEnabled())
1306     return;
1307
1308   SALOME_ListIO aList;
1309   mySelectionMgr->selectedObjects(aList);
1310   if ( aList.IsEmpty() || aList.Extent() > 1 )
1311     return;
1312
1313   if ( SelectVectorButton->isChecked() )
1314   {
1315     Handle(SALOME_InteractiveObject) IO = aList.First();
1316     TColStd_IndexedMapOfInteger aMapIndex;
1317     mySelector->GetIndex(IO,aMapIndex);
1318     if ( aMapIndex.Extent() != 1 )
1319       return;
1320     SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() );
1321     SMDS_Mesh*     aMesh = anActor ? anActor->GetObject()->GetMesh() : 0;
1322     if ( !aMesh )
1323       return;
1324
1325     const SMDS_MeshFace* face =
1326       aMesh->DownCast< SMDS_MeshFace >(aMesh->FindElement(aMapIndex(1)));
1327     if (!face)
1328       return;
1329
1330     gp_XYZ aNormale = SMESH::getNormale(face);
1331     SpinBox_Vx->SetValue(aNormale.X());
1332     SpinBox_Vy->SetValue(aNormale.Y());
1333     SpinBox_Vz->SetValue(aNormale.Z());
1334   }
1335   else if ( SelectBasePointButton->isChecked() )
1336   {
1337     if (!BasePointGrp->isChecked())
1338       return;
1339
1340     // try to get shape from selection
1341     Handle(SALOME_InteractiveObject) IO = aList.First();
1342
1343     // check if geom vertex is selected
1344     GEOM::GEOM_Object_var aGeomObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(IO);
1345     TopoDS_Vertex aVertex;
1346     if (!aGeomObj->_is_nil()) {
1347       if (aGeomObj->IsShape() && GEOMBase::GetShape(aGeomObj, aVertex) && !aVertex.IsNull()) {
1348         gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
1349         BasePoint_XSpin->SetValue(aPnt.X());
1350         BasePoint_YSpin->SetValue(aPnt.Y());
1351         BasePoint_ZSpin->SetValue(aPnt.Z());
1352       }
1353     }
1354
1355     if ( aVertex.IsNull() )
1356     {
1357       // check if smesh node is selected
1358       SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(IO);
1359       if (aMesh->_is_nil())
1360         return;
1361
1362       QString aString;
1363       int aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
1364       // return if more than one node is selected
1365       if (aNbUnits != 1)
1366         return;
1367
1368       SMESH_Actor* aMeshActor = SMESH::FindActorByObject(aMesh);
1369       if (!aMeshActor)
1370         return;
1371
1372       SMDS_Mesh* mesh = aMeshActor->GetObject()->GetMesh();
1373       if (!mesh)
1374         return;
1375
1376       const SMDS_MeshNode* n = mesh->FindNode(aString.toLong());
1377       if (!n)
1378         return;
1379
1380       BasePoint_XSpin->SetValue(n->X());
1381       BasePoint_YSpin->SetValue(n->Y());
1382       BasePoint_ZSpin->SetValue(n->Z());
1383     }
1384   }
1385
1386   onDisplaySimulation(true);
1387   CheckIsEnable();
1388 }
1389
1390 //=================================================================================
1391 // function : SetEditCurrentArgument()
1392 // purpose  :
1393 //=================================================================================
1394 void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
1395 {
1396   QPushButton* send = (QPushButton*)sender();
1397
1398   disconnect(mySelectionMgr, 0, this, 0);
1399   mySelectionMgr->clearSelected();
1400   mySelectionMgr->clearFilters();
1401
1402   if (send == SelectVectorButton)
1403   {
1404     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1405       aViewWindow->SetSelectionMode(FaceSelection);
1406   }
1407   else if ( send == SelectBasePointButton )
1408   {
1409     SMESH::SetPointRepresentation(true);
1410     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1411       aViewWindow->SetSelectionMode(NodeSelection);
1412
1413     SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter(SMESH::IDSOURCE);
1414     SMESH_NumberFilter* aVertexFilter      = new SMESH_NumberFilter ("GEOM", TopAbs_VERTEX,
1415                                                                      1, TopAbs_VERTEX);
1416     QList<SUIT_SelectionFilter*> aListOfFilters;
1417     aListOfFilters << aMeshOrSubMeshFilter << aVertexFilter;
1418
1419     mySelectionMgr->installFilter(new SMESH_LogicalFilter
1420                                   (aListOfFilters, SMESH_LogicalFilter::LO_OR, true));
1421   }
1422   
1423   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
1424   SelectionIntoArgument();
1425 }
1426
1427 //=================================================================================
1428 // function : DeactivateActiveDialog()
1429 // purpose  : Deactivates this dialog
1430 //=================================================================================
1431 void SMESHGUI_ExtrusionDlg::DeactivateActiveDialog()
1432 {
1433   if (GroupButtons->isEnabled())
1434   {
1435     GroupArguments->setEnabled(false);
1436     GroupButtons->setEnabled(false);
1437     SelectorWdg->setEnabled(false);
1438     mySMESHGUI->ResetState();
1439     mySMESHGUI->SetActiveDialogBox(0);
1440   }
1441 }
1442
1443 //=================================================================================
1444 // function : ActivateThisDialog()
1445 // purpose  : Activates this dialog
1446 //=================================================================================
1447 void SMESHGUI_ExtrusionDlg::ActivateThisDialog()
1448 {
1449   // Emit a signal to deactivate the active dialog
1450   mySMESHGUI->EmitSignalDeactivateDialog();
1451   GroupArguments->setEnabled(true);
1452   GroupButtons->setEnabled(true);
1453   SelectorWdg->setEnabled(true);
1454
1455   mySMESHGUI->SetActiveDialogBox(this);
1456 }
1457
1458 //=================================================================================
1459 // function : enterEvent()
1460 // purpose  :
1461 //=================================================================================
1462 void SMESHGUI_ExtrusionDlg::enterEvent (QEvent*)
1463 {
1464   if ( !GroupButtons->isEnabled() ) {
1465     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
1466     if ( aViewWindow && !mySelector) {
1467       mySelector = aViewWindow->GetSelector();
1468     }
1469     ActivateThisDialog();
1470   }
1471 }
1472
1473 //=================================================================================
1474 // function : keyPressEvent()
1475 // purpose  :
1476 //=================================================================================
1477 void SMESHGUI_ExtrusionDlg::keyPressEvent( QKeyEvent* e )
1478 {
1479   QDialog::keyPressEvent( e );
1480   if ( e->isAccepted() )
1481     return;
1482
1483   if ( e->key() == Qt::Key_F1 ) {
1484     e->accept();
1485     ClickOnHelp();
1486   }
1487 }
1488
1489 //=================================================================================
1490 // function : isValid
1491 // purpose  :
1492 //=================================================================================
1493 bool SMESHGUI_ExtrusionDlg::isValid()
1494 {
1495   QString msg;
1496   bool ok = true;
1497   if ( ExtrMethod_RBut0->isChecked() ) {
1498     ok = SpinBox_Dx->isValid( msg, true ) && ok;
1499     ok = SpinBox_Dy->isValid( msg, true ) && ok;
1500     ok = SpinBox_Dz->isValid( msg, true ) && ok;
1501   } else if ( ExtrMethod_RBut1->isChecked() ) {
1502     ok = SpinBox_Vx->isValid( msg, true ) && ok;
1503     ok = SpinBox_Vy->isValid( msg, true ) && ok;
1504     ok = SpinBox_Vz->isValid( msg, true ) && ok;
1505     ok = SpinBox_VDist->isValid( msg, true ) && ok;
1506   }
1507   ok = SpinBox_NbSteps->isValid( msg, true ) && ok;
1508
1509   if ( BasePointGrp->isChecked()) {
1510     ok = BasePoint_XSpin->isValid( msg, true ) && ok;
1511     ok = BasePoint_YSpin->isValid( msg, true ) && ok;
1512     ok = BasePoint_ZSpin->isValid( msg, true ) && ok;
1513   }
1514
1515   if( !ok ) {
1516     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
1517     if ( !msg.isEmpty() )
1518       str += "\n" + msg;
1519     SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
1520     return false;
1521   }
1522   return true;
1523 }
1524
1525 //=================================================================================
1526 // function : onDisplaySimulation
1527 // purpose  : Show/Hide preview
1528 //=================================================================================
1529 void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview )
1530 {
1531   if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
1532     if ( SelectorWdg->IsAnythingSelected() && isValid() && isValuesValid())
1533     {
1534       //Get input vector
1535       SMESH::DirStruct aVector;
1536       getExtrusionVector(aVector);
1537
1538       //Get Number of the steps
1539       long aNbSteps = (long)SpinBox_NbSteps->value();
1540       try
1541       {
1542         SUIT_OverrideCursor aWaitCursor;
1543
1544         SMESH::SMESH_Mesh_var             mesh = SelectorWdg->GetMesh();
1545         SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditPreviewer();
1546         SMESH::ListOfGroups_var         groups;
1547
1548         SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
1549         SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
1550         SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
1551         const int  maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
1552         const bool makeGroups = false;
1553
1554         if ( ExtrMethod_RBut2->isVisible() &&
1555              ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
1556         {
1557           double stepSize          = (double) SpinBox_VDist->value();
1558           long   nbSteps           = (long) SpinBox_NbSteps->value();
1559           bool   useInputElemsOnly = UseInputElemsOnlyCheck->isChecked();
1560           bool   byAverageNormal   = ByAverageNormalCheck->isChecked();
1561           int    dim               = (maxSelType == SMESH::FACE) ? 2 : 1;
1562
1563           groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, useInputElemsOnly,
1564                                                   byAverageNormal, makeGroups, dim );
1565         }
1566         else
1567         {
1568           SMESH::double_array_var scales, basePoint;
1569           bool linVariation = getScaleParams( scales.out(), basePoint.out() );
1570           groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
1571                                                       aVector, aNbSteps,
1572                                                       scales, linVariation, basePoint,
1573                                                       makeGroups );
1574         }
1575         SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
1576         mySimulation->SetData(aMeshPreviewStruct);
1577
1578       } catch (...) {
1579         hidePreview();
1580       }
1581     } else {
1582       hidePreview();
1583     }
1584   } else {
1585     hidePreview();
1586   }
1587 }
1588
1589 //=================================================================================
1590 // function : getExtrusionVector()
1591 // purpose  : get direction of the extrusion
1592 //=================================================================================
1593 void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector)
1594 {
1595   if ( ExtrMethod_RBut0->isChecked() )
1596   {
1597     aVector.PS.x = SpinBox_Dx->GetValue();
1598     aVector.PS.y = SpinBox_Dy->GetValue();
1599     aVector.PS.z = SpinBox_Dz->GetValue();
1600   }
1601   else if ( ExtrMethod_RBut1->isChecked() )
1602   {
1603     gp_XYZ aNormale(SpinBox_Vx->GetValue(),
1604                     SpinBox_Vy->GetValue(),
1605                     SpinBox_Vz->GetValue());
1606     aNormale /= aNormale.Modulus();
1607     double aVDist = (double)SpinBox_VDist->value();
1608
1609     aVector.PS.x = aNormale.X()*aVDist;
1610     aVector.PS.y = aNormale.Y()*aVDist;
1611     aVector.PS.z = aNormale.Z()*aVDist;
1612   }
1613 }
1614
1615 //=======================================================================
1616 // function : OnScaleAdded()
1617 // purpose  : Called when user adds Scale to the list
1618 //=======================================================================
1619 void SMESHGUI_ExtrusionDlg::OnScaleAdded()
1620 {
1621   QString msg;
1622   if( !ScaleSpin->isValid( msg, true ) ) {
1623     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
1624     if ( !msg.isEmpty() )
1625       str += "\n" + msg;
1626     SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
1627     return;
1628   }
1629   ScalesList->addItem(ScaleSpin->text());
1630   myScalesList.append(ScaleSpin->GetValue());
1631 }
1632
1633 //=======================================================================
1634 // function : OnScaleRemoved()
1635 // purpose  : Called when user removes Scale(s) from the list
1636 //=======================================================================
1637 void SMESHGUI_ExtrusionDlg::OnScaleRemoved()
1638 {
1639   QList<QListWidgetItem*> aList = ScalesList->selectedItems();
1640   QListWidgetItem* anItem;
1641   int row = 0;
1642   foreach(anItem, aList) {
1643     row = ScalesList->row(anItem);
1644     myScalesList.removeAt(row);
1645     delete anItem;
1646   }
1647   ScalesList->setCurrentRow( row, QItemSelectionModel::Select );
1648 }