Salome HOME
23173: EDF 11552 - Problem using Add 0D element function
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_ExtrusionAlongPathDlg.cxx
1 // Copyright (C) 2007-2015  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_ExtrusionAlongPathDlg.cxx
25 // Author : Vadim SANDLER, Open CASCADE S.A.S.
26 // SMESH includes
27
28 #include "SMESHGUI_ExtrusionAlongPathDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_ExtrusionDlg.h" // for SMESHGUI_3TypesSelector
32 #include "SMESHGUI_FilterDlg.h"
33 #include "SMESHGUI_IdValidator.h"
34 #include "SMESHGUI_MeshEditPreview.h"
35 #include "SMESHGUI_MeshUtils.h"
36 #include "SMESHGUI_SpinBox.h"
37 #include "SMESHGUI_Utils.h"
38 #include "SMESHGUI_VTKUtils.h"
39
40 #include <SMESH_Actor.h>
41 #include <SMESH_TypeFilter.hxx>
42 #include <SMESH_NumberFilter.hxx>
43 #include <SMESH_LogicalFilter.hxx>
44
45 #include <SMDS_Mesh.hxx>
46
47 // SALOME GEOM includes
48 #include <GEOMBase.h>
49
50 // SALOME GUI includes
51 #include <SUIT_ResourceMgr.h>
52 #include <SUIT_OverrideCursor.h>
53 #include <SUIT_Desktop.h>
54 #include <SUIT_MessageBox.h>
55 #include <SUIT_Session.h>
56 #include <LightApp_Application.h>
57 #include <LightApp_SelectionMgr.h>
58 #include <SVTK_ViewWindow.h>
59
60 // OCCT includes
61 #include <BRep_Tool.hxx>
62 #include <TopoDS_Vertex.hxx>
63 #include <gp_Pnt.hxx>
64 #include <TColStd_MapOfInteger.hxx>
65
66 // Qt includes
67 #include <QButtonGroup>
68 #include <QGroupBox>
69 #include <QLabel>
70 #include <QLineEdit>
71 #include <QPushButton>
72 #include <QToolButton>
73 #include <QRadioButton>
74 #include <QCheckBox>
75 #include <QListWidget>
76 #include <QVBoxLayout>
77 #include <QHBoxLayout>
78 #include <QGridLayout>
79 #include <QKeyEvent>
80
81 // IDL includes
82 #include <SALOMEconfig.h>
83 #include CORBA_SERVER_HEADER(SMESH_Group)
84 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
85
86 #define SPACING 6
87 #define MARGIN  11
88
89 class SMESHGUI_ExtrusionAlongPathDlg::SetBusy
90 {
91 public:
92   SetBusy( SMESHGUI_ExtrusionAlongPathDlg* _dlg )
93   {
94     myDlg = _dlg; 
95     myDlg->myBusy = true;
96   }
97   
98   ~SetBusy()
99   { 
100     myDlg->myBusy = false;
101   }
102   
103 private:
104   SMESHGUI_ExtrusionAlongPathDlg* myDlg;
105 };
106
107 //=================================================================================
108 // function : SMESHGUI_ExtrusionAlongPathDlg()
109 // purpose  : constructor
110 //=================================================================================
111 SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theModule )
112   : SMESHGUI_PreviewDlg( theModule ),
113     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
114 {
115   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
116   QPixmap selectImage ( mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
117   QPixmap addImage    ( mgr->loadPixmap("SMESH", tr("ICON_APPEND")));
118   QPixmap removeImage ( mgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
119
120   setModal( false );
121   setAttribute( Qt::WA_DeleteOnClose, true );
122   setWindowTitle(tr("EXTRUSION_ALONG_PATH"));
123   setSizeGripEnabled(true);
124
125   QVBoxLayout* topLayout = new QVBoxLayout(this);
126   topLayout->setSpacing(SPACING);
127   topLayout->setMargin(MARGIN);
128
129   /***************************************************************/
130   // Arguments group box
131   GroupArguments = new QGroupBox(tr("SMESH_EXTRUSION"), this);
132   QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
133   GroupArgumentsLayout->setSpacing(SPACING); GroupArgumentsLayout->setMargin(MARGIN);
134
135   myIdValidator = new SMESHGUI_IdValidator(this);
136
137   // Controls for elements selection
138   SelectorWdg = new SMESHGUI_3TypesSelector( GroupArguments );
139   
140   // Controls for path selection
141   PathGrp = new QGroupBox(tr("SMESH_PATH"), GroupArguments);
142   QGridLayout* PathGrpLayout = new QGridLayout(PathGrp);
143   PathGrpLayout->setSpacing(SPACING); PathGrpLayout->setMargin(MARGIN);
144
145   // Controls for path mesh selection
146   QLabel* PathMeshLab = new QLabel(tr("SMESH_PATH_MESH"), PathGrp);
147
148   SelectPathMeshButton = new QPushButton(PathGrp);
149   SelectPathMeshButton->setIcon(selectImage);
150   SelectPathMeshButton->setCheckable(true);
151
152   PathMeshLineEdit = new QLineEdit(PathGrp);
153   PathMeshLineEdit->setReadOnly(true);
154
155   // Controls for path starting point selection
156   QLabel* StartPointLab = new QLabel(tr("SMESH_PATH_START"), PathGrp);
157
158   SelectStartPointButton = new QPushButton(PathGrp);
159   SelectStartPointButton->setIcon(selectImage);
160   SelectStartPointButton->setCheckable(true);
161
162   StartPointLineEdit = new QLineEdit(PathGrp);
163   StartPointLineEdit->setValidator(new QIntValidator(this));
164
165   // layouting
166   PathGrpLayout->addWidget(PathMeshLab,            0, 0);
167   PathGrpLayout->addWidget(SelectPathMeshButton,   0, 1);
168   PathGrpLayout->addWidget(PathMeshLineEdit,       0, 2);
169   PathGrpLayout->addWidget(StartPointLab,          1, 0);
170   PathGrpLayout->addWidget(SelectStartPointButton, 1, 1);
171   PathGrpLayout->addWidget(StartPointLineEdit,     1, 2);
172
173   BasePointGrp = new QGroupBox(tr("SMESH_BASE_POINT"), GroupArguments);
174   BasePointGrp->setCheckable(true);
175   BasePointGrp->setChecked(false);
176   QHBoxLayout* BasePointGrpLayout = new QHBoxLayout(BasePointGrp);
177   BasePointGrpLayout->setSpacing(SPACING); BasePointGrpLayout->setMargin(MARGIN);
178
179   SelectBasePointButton = new QPushButton(BasePointGrp);
180   SelectBasePointButton->setIcon(selectImage);
181   SelectBasePointButton->setCheckable(true);
182
183   SelectorWdg->GetButtonGroup()->addButton( SelectPathMeshButton );
184   SelectorWdg->GetButtonGroup()->addButton( SelectStartPointButton );
185   SelectorWdg->GetButtonGroup()->addButton( SelectBasePointButton );
186
187   QLabel* XLab  = new QLabel(tr("SMESH_X"), BasePointGrp);
188   XSpin = new SMESHGUI_SpinBox(BasePointGrp);
189   QLabel* YLab  = new QLabel(tr("SMESH_Y"), BasePointGrp);
190   YSpin = new SMESHGUI_SpinBox(BasePointGrp);
191   QLabel* ZLab  = new QLabel(tr("SMESH_Z"), BasePointGrp);
192   ZSpin = new SMESHGUI_SpinBox(BasePointGrp);
193
194   // layouting
195   BasePointGrpLayout->addWidget(SelectBasePointButton);
196   BasePointGrpLayout->addWidget(XLab);
197   BasePointGrpLayout->addWidget(XSpin);
198   BasePointGrpLayout->addWidget(YLab);
199   BasePointGrpLayout->addWidget(YSpin);
200   BasePointGrpLayout->addWidget(ZLab);
201   BasePointGrpLayout->addWidget(ZSpin);
202
203   AnglesGrp = new QGroupBox(tr("SMESH_ANGLES"), GroupArguments);
204   AnglesGrp->setCheckable(true);
205   AnglesGrp->setChecked(false);
206   QGridLayout* AnglesGrpLayout = new QGridLayout(AnglesGrp);
207   AnglesGrpLayout->setSpacing(SPACING); AnglesGrpLayout->setMargin(MARGIN);
208
209   AnglesList = new QListWidget(AnglesGrp);
210   AnglesList->setSelectionMode(QListWidget::ExtendedSelection);
211
212   AddAngleButton = new QToolButton(AnglesGrp);
213   AddAngleButton->setIcon(addImage);
214
215   RemoveAngleButton = new QToolButton(AnglesGrp);
216   RemoveAngleButton->setIcon(removeImage);
217
218   AngleSpin = new SMESHGUI_SpinBox(AnglesGrp);
219
220   LinearAnglesCheck = new QCheckBox(tr("LINEAR_ANGLES"), AnglesGrp);
221
222   // layouting
223   AnglesGrpLayout->addWidget(AnglesList,        0, 0, 4, 1);
224   AnglesGrpLayout->addWidget(AddAngleButton,    0, 1);
225   AnglesGrpLayout->addWidget(RemoveAngleButton, 2, 1);
226   AnglesGrpLayout->addWidget(AngleSpin,         0, 2);
227   AnglesGrpLayout->addWidget(LinearAnglesCheck, 4, 0);
228   AnglesGrpLayout->setRowMinimumHeight(1, 10);
229   AnglesGrpLayout->setRowStretch(3, 10);
230
231   // CheckBox for groups generation
232   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
233   MakeGroupsCheck->setChecked(true);
234
235   //Preview check box
236   myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
237
238   // layouting
239   GroupArgumentsLayout->addWidget(SelectorWdg,          0, 0);
240   GroupArgumentsLayout->addWidget(PathGrp,              1, 0);
241   GroupArgumentsLayout->addWidget(BasePointGrp,         2, 0);
242   GroupArgumentsLayout->addWidget(AnglesGrp,            3, 0);
243   GroupArgumentsLayout->addWidget(myPreviewCheckBox,    4, 0);
244   GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 0);
245
246   /***************************************************************/
247   // common buttons group box
248   GroupButtons = new QGroupBox(this);
249   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
250   GroupButtonsLayout->setSpacing(SPACING); GroupButtonsLayout->setMargin(MARGIN);
251
252   OkButton = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
253   OkButton->setAutoDefault(true);
254   OkButton->setDefault(true);
255
256   ApplyButton = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons); 
257   ApplyButton->setAutoDefault(true);
258
259   CloseButton = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
260   CloseButton->setAutoDefault(true);
261
262   HelpButton = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
263   HelpButton->setAutoDefault(true);
264
265   // layouting
266   GroupButtonsLayout->addWidget(OkButton);
267   GroupButtonsLayout->addSpacing(10);
268   GroupButtonsLayout->addWidget(ApplyButton);
269   GroupButtonsLayout->addSpacing(10);
270   GroupButtonsLayout->addStretch();
271   GroupButtonsLayout->addWidget(CloseButton);
272   GroupButtonsLayout->addWidget(HelpButton);
273
274   /***************************************************************/
275   // layouting
276   topLayout->addWidget(GroupArguments);
277   topLayout->addWidget(GroupButtons);
278
279   /***************************************************************/
280   // Initialisations
281   XSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
282   YSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
283   ZSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
284   AngleSpin->RangeStepAndValidator(-180.0, 180.0, 5.0, "angle_precision");
285
286   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
287
288   mySMESHGUI->SetActiveDialogBox(this);
289
290   myPathMeshFilter = new SMESH_TypeFilter(SMESH::MESHorSUBMESH);
291
292   myHelpFileName = "extrusion_along_path_page.html";
293
294   Init();
295
296   /***************************************************************/
297   // signals-slots connections
298   connect(OkButton,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
299   connect(CloseButton,  SIGNAL(clicked()), this, SLOT(reject()));
300   connect(ApplyButton,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
301   connect(HelpButton,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
302
303   connect(AddAngleButton,    SIGNAL(clicked()), this, SLOT(OnAngleAdded()));
304   connect(RemoveAngleButton, SIGNAL(clicked()), this, SLOT(OnAngleRemoved()));
305
306   connect(SelectPathMeshButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
307   connect(SelectStartPointButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
308   connect(SelectBasePointButton,  SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
309   connect(BasePointGrp,       SIGNAL(toggled(bool)), this, SLOT(SetEditCurrentArgument()));
310
311   connect(mySMESHGUI,  SIGNAL(SignalCloseAllDialogs()),        SLOT(reject()));
312   connect(mySMESHGUI,  SIGNAL(SignalActivatedViewManager()),   SLOT(onOpenView()));
313   connect(mySMESHGUI,  SIGNAL(SignalCloseView()),              SLOT(onCloseView()));
314   connect(mySMESHGUI,  SIGNAL(SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
315   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),   SLOT(SelectionIntoArgument()));
316   connect(SelectorWdg,    SIGNAL(selectionChanged()), this,    SLOT(toDisplaySimulation()));
317   connect(SelectorWdg,    SIGNAL(selectionChanged()), this,    SLOT(CheckIsEnable()));
318
319   connect(StartPointLineEdit, SIGNAL(textChanged(const QString&)),
320           SLOT(onTextChange(const QString&)));
321
322   connect(XSpin,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
323   connect(YSpin,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
324   connect(ZSpin,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
325   connect(AddAngleButton,    SIGNAL(clicked()), this, SLOT(toDisplaySimulation()));
326   connect(RemoveAngleButton, SIGNAL(clicked()), this, SLOT(toDisplaySimulation()));
327   //connect(LinearAnglesCheck, SIGNAL(toggled(bool)), SLOT(onSelectMesh()));
328
329
330   //To Connect preview check box
331   connectPreviewControl();
332
333   AnglesList        ->installEventFilter(this);
334   StartPointLineEdit->installEventFilter(this);
335   XSpin->editor()   ->installEventFilter(this);
336   YSpin->editor()   ->installEventFilter(this);
337   ZSpin->editor()   ->installEventFilter(this);
338
339   CheckIsEnable();
340 }
341
342 //=================================================================================
343 // function : ~SMESHGUI_ExtrusionAlongPathDlg()
344 // purpose  : destructor
345 //=================================================================================
346 SMESHGUI_ExtrusionAlongPathDlg::~SMESHGUI_ExtrusionAlongPathDlg()
347 {
348   // no need to delete child widgets, Qt does it all for us
349 }
350
351 //=================================================================================
352 // function : Init()
353 // purpose  : initialization
354 //=================================================================================
355 void SMESHGUI_ExtrusionAlongPathDlg::Init (bool ResetControls)
356 {
357   myBusy = false;
358   myEditCurrentArgument = 0;
359
360   myPath = SMESH::SMESH_IDSource::_nil();
361
362   SelectorWdg->Clear();
363   PathMeshLineEdit->clear();
364   StartPointLineEdit->clear();
365
366   if (ResetControls) {
367     XSpin->SetValue(0.0);
368     YSpin->SetValue(0.0);
369     ZSpin->SetValue(0.0);
370
371     AngleSpin->SetValue(45);
372     myPreviewCheckBox->setChecked(false);
373     onDisplaySimulation(false);
374   }
375   SetEditCurrentArgument(0);
376 }
377
378 //=================================================================================
379 // function : CheckIsEnable()
380 // purpose  : Check whether the Ok and Apply buttons should be enabled or not
381 //=================================================================================
382
383 void SMESHGUI_ExtrusionAlongPathDlg::CheckIsEnable()
384 {  
385   bool anIsEnable = SelectorWdg->IsAnythingSelected() && isValuesValid();
386
387   OkButton->setEnabled(anIsEnable);
388   ApplyButton->setEnabled(anIsEnable);
389 }
390
391 //=================================================================================
392 // function : ClickOnApply()
393 // purpose  : Called when user presses <Apply> button
394 //=================================================================================
395 bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
396 {
397   if (mySMESHGUI->isActiveStudyLocked())
398     return false;
399
400   if ( !SelectorWdg->IsAnythingSelected() || myPath->_is_nil() )
401     return false;
402
403   if (!isValid())
404     return false;
405
406   if (StartPointLineEdit->text().trimmed().isEmpty()) {
407     return false;
408   }
409   
410   bool bOk;
411   long aNodeStart = StartPointLineEdit->text().toLong(&bOk);
412   if (!bOk) {
413     return false;
414   }
415
416   QStringList aParameters;
417   
418   //get angles
419   SMESH::double_array_var anAngles = getAngles();
420   
421   for (int i = 0; i < myAnglesList.count(); i++)
422     aParameters << AnglesList->item(i)->text();
423
424
425   // get base point
426   SMESH::PointStruct aBasePoint;
427   if (BasePointGrp->isChecked()) {
428     aBasePoint.x = XSpin->GetValue();
429     aBasePoint.y = YSpin->GetValue();
430     aBasePoint.z = ZSpin->GetValue();
431   }
432   aParameters << XSpin->text();
433   aParameters << YSpin->text();
434   aParameters << ZSpin->text();
435
436   bool meshHadNewTypeBefore = true;
437   int  maxSelType = 0;
438   const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
439
440   try {
441     SUIT_OverrideCursor wc;
442
443     SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh();
444
445     mesh->SetParameters( aParameters.join(":").toLatin1().constData() );
446
447     SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
448     SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
449     SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
450     maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
451
452     // is it necessary to switch on the next Display Mode?
453     SMESH::ElementType newType = (SMESH::ElementType)( maxSelType + 1 );
454     SMESH::array_of_ElementType_var oldTypes = mesh->GetTypes();
455     meshHadNewTypeBefore = false;
456     for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
457       meshHadNewTypeBefore = ( oldTypes[i] >= newType );
458
459     SMESH::SMESH_MeshEditor_var aMeshEditor = mesh->GetMeshEditor();
460     SMESH::SMESH_MeshEditor::Extrusion_Error retVal;
461
462     SMESH::ListOfGroups_var groups =
463       aMeshEditor->ExtrusionAlongPathObjects( nodes, edges, faces, myPath,
464                                               GEOM::GEOM_Object::_nil(),
465                                               aNodeStart, AnglesGrp->isChecked(),
466                                               anAngles, LinearAnglesCheck->isChecked(),
467                                               BasePointGrp->isChecked(), aBasePoint,
468                                               makeGroups, retVal );
469
470     wc.suspend();
471     switch (retVal) {
472     case SMESH::SMESH_MeshEditor::EXTR_NO_ELEMENTS:
473       SUIT_MessageBox::warning(this,
474                                tr("SMESH_ERROR"),
475                                tr("NO_ELEMENTS_SELECTED"));
476       return false; break;
477     case SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE:
478       SUIT_MessageBox::warning(this,
479                                tr("SMESH_ERROR"),
480                                tr("SELECTED_PATH_IS_NOT_EDGE"));
481       return false; break;
482     case SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE:
483       SUIT_MessageBox::warning(this,
484                                tr("SMESH_ERROR"),
485                                tr("BAD_SHAPE_TYPE"));
486       return false; break;
487     case SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE:
488       SUIT_MessageBox::warning(this,
489                                tr("SMESH_ERROR"),
490                                tr("EXTR_BAD_STARTING_NODE"));
491       return false; break;
492     case SMESH::SMESH_MeshEditor::EXTR_BAD_ANGLES_NUMBER:
493       SUIT_MessageBox::warning(this,
494                                tr("SMESH_ERROR"),
495                                tr("WRONG_ANGLES_NUMBER"));
496       return false; break;
497     case SMESH::SMESH_MeshEditor::EXTR_CANT_GET_TANGENT:
498       SUIT_MessageBox::warning(this,
499                                tr("SMESH_ERROR"),
500                                tr("CANT_GET_TANGENT"));
501       return false; break;
502     case SMESH::SMESH_MeshEditor::EXTR_OK:
503       break;
504     }
505   } catch (...) {
506     return false;
507   }
508
509   SMESH_Actor* actor = SelectorWdg->GetActor();
510   if ( actor && !meshHadNewTypeBefore )
511   {
512     unsigned int aMode = actor->GetEntityMode();
513     switch ( maxSelType ) {
514     case SMESH::NODE: // extrude node -> edges
515       actor->SetRepresentation(SMESH_Actor::eEdge);
516       actor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
517     case SMESH::EDGE: // edge -> faces
518       actor->SetRepresentation(SMESH_Actor::eSurface);
519       actor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
520     case SMESH::FACE: // faces -> volumes
521       actor->SetRepresentation(SMESH_Actor::eSurface);
522       actor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
523     }
524   }
525   if ( actor )
526     SMESH::Update( actor->getIO(), actor->GetVisibility() );
527   if ( makeGroups )
528     mySMESHGUI->updateObjBrowser(true); // new groups may appear
529   Init(false);
530   mySelectionMgr->clearSelected();
531   SelectorWdg->Clear();
532
533   SMESHGUI::Modified();
534   return true;
535 }
536
537 //=================================================================================
538 // function : ClickOnOk()
539 // purpose  : Called when user presses <OK> button
540 //=================================================================================
541 void SMESHGUI_ExtrusionAlongPathDlg::ClickOnOk()
542 {
543   if (ClickOnApply())
544     reject();
545 }
546
547 //=================================================================================
548 // function : ClickOnHelp()
549 // purpose  :
550 //=================================================================================
551 void SMESHGUI_ExtrusionAlongPathDlg::ClickOnHelp()
552 {
553   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
554   if (app) 
555     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
556   else {
557     QString platform;
558 #ifdef WIN32
559     platform = "winapplication";
560 #else
561     platform = "application";
562 #endif
563     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
564                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
565                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
566                                                                  platform)).
567                              arg(myHelpFileName));
568   }
569 }
570
571 //=================================================================================
572 // function : reject()
573 // purpose  : Called when dialog box is closed
574 //=================================================================================
575 void SMESHGUI_ExtrusionAlongPathDlg::reject()
576 {
577   disconnect(mySelectionMgr, 0, this, 0);
578   mySelectionMgr->clearFilters();
579   //mySelectionMgr->clearSelected();
580   if (SMESH::GetCurrentVtkView()) {
581     SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
582     SMESH::SetPointRepresentation(false);
583     SMESH::SetPickable();
584   }
585   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
586     aViewWindow->SetSelectionMode(ActorSelection);
587   mySMESHGUI->ResetState();
588
589   QDialog::reject();
590 }
591
592 //=================================================================================
593 // function : onOpenView()
594 // purpose  :
595 //=================================================================================
596 void SMESHGUI_ExtrusionAlongPathDlg::onOpenView()
597 {
598   if ( mySelector ) {
599     SMESH::SetPointRepresentation(false);
600   }
601   else {
602     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
603     ActivateThisDialog();
604   }
605 }
606
607 //=================================================================================
608 // function : onCloseView()
609 // purpose  :
610 //=================================================================================
611 void SMESHGUI_ExtrusionAlongPathDlg::onCloseView()
612 {
613   DeactivateActiveDialog();
614   mySelector = 0;
615 }
616
617 //=======================================================================
618 // function : onTextChange()
619 // purpose  :
620 //=======================================================================
621 void SMESHGUI_ExtrusionAlongPathDlg::onTextChange (const QString& theNewText)
622 {
623   QLineEdit* send = (QLineEdit*)sender();
624
625   // return if busy
626   if (myBusy) return;
627
628   // set busy flag
629   SetBusy sb (this);
630
631   if (send == StartPointLineEdit &&
632       myEditCurrentArgument == StartPointLineEdit)
633   {
634     if (!myPath->_is_nil()) {
635       SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
636       SMDS_Mesh* aMesh = aPathActor ? aPathActor->GetObject()->GetMesh() : 0;
637       if (aMesh) {
638         SALOME_ListIO aList;
639         aList.Append(aPathActor->getIO());
640         mySelectionMgr->setSelectedObjects(aList, false);
641
642         bool bOk;
643         long ind = theNewText.toLong(&bOk);
644         if (bOk) {
645           const SMDS_MeshNode* n = aMesh->FindNode(ind);
646           if (n) {
647             TColStd_MapOfInteger newIndices;
648             newIndices.Add(n->GetID());
649             mySelector->AddOrRemoveIndex( aPathActor->getIO(), newIndices, false );
650             if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
651               aViewWindow->highlight( aPathActor->getIO(), true, true );
652           }
653         }
654       }
655     }
656   }
657   CheckIsEnable();
658   onDisplaySimulation(true);
659 }
660
661 //=================================================================================
662 // function : SelectionIntoArgument()
663 // purpose  : Called when selection as changed or other case
664 //=================================================================================
665 void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
666 {
667   if (myBusy) return;
668
669   // return if dialog box is inactive
670   if (!GroupButtons->isEnabled())
671     return;
672
673   // selected objects count
674   const SALOME_ListIO& aList = mySelector->StoredIObjects();
675   int nbSel = aList.Extent();
676   if (nbSel != 1)
677     return;
678
679   // set busy flag
680   SetBusy sb (this);
681
682   const bool isPathDef = ( SelectPathMeshButton->isChecked() ||
683                            SelectStartPointButton->isChecked() );
684
685   if (myEditCurrentArgument == PathMeshLineEdit && isPathDef)
686   {
687     // we are now selecting path mesh
688     // reset
689     PathMeshLineEdit->clear();
690     myPath = SMESH::SMESH_IDSource::_nil();
691     StartPointLineEdit->clear();
692
693     // try to get mesh from selection
694     Handle(SALOME_InteractiveObject) IO = aList.First();
695     myPath = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
696     if( myPath->_is_nil() )
697       return;
698
699     QString aString;
700     SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
701     PathMeshLineEdit->setText(aString);
702   }
703   else if (myEditCurrentArgument == StartPointLineEdit && isPathDef )
704   {
705     // we are now selecting start point of path
706     // reset
707     StartPointLineEdit->clear();
708
709     // return if path mesh or path shape is not yet selected
710     if( myPath->_is_nil() )
711       return;
712
713     // try to get shape from selection
714     Handle(SALOME_InteractiveObject) IO = aList.First();
715
716     SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
717     if ( !aPathActor )
718       return;
719
720     QString aString;
721     int aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aPathActor->getIO(), aString);
722     if (aNbUnits == 1)
723       StartPointLineEdit->setText(aString.trimmed());
724   }
725   else if ( myEditCurrentArgument == XSpin &&
726             SelectBasePointButton->isChecked() )
727   {
728     // we are now selecting base point
729     // reset is not performed here!
730
731     // return if is not enabled
732     if (!BasePointGrp->isChecked())
733       return;
734
735     // try to get shape from selection
736     Handle(SALOME_InteractiveObject) IO = aList.First();
737
738     // check if geom vertex is selected
739     GEOM::GEOM_Object_var aGeomObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(IO);
740     TopoDS_Vertex aVertex;
741     if (!aGeomObj->_is_nil()) {
742       if (aGeomObj->IsShape() && GEOMBase::GetShape(aGeomObj, aVertex) && !aVertex.IsNull()) {
743         gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
744         XSpin->SetValue(aPnt.X());
745         YSpin->SetValue(aPnt.Y());
746         ZSpin->SetValue(aPnt.Z());
747       }
748       return;
749     }
750
751     // check if smesh node is selected
752     SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(IO);
753     if (aMesh->_is_nil())
754       return;
755
756     QString aString;
757     int aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
758     // return if more than one node is selected
759     if (aNbUnits != 1)
760       return;
761
762     SMESH_Actor* aMeshActor = SMESH::FindActorByObject(aMesh);
763     if (!aMeshActor)
764       return;
765
766     SMDS_Mesh* mesh = aMeshActor->GetObject()->GetMesh();
767     if (!mesh)
768       return;
769
770     const SMDS_MeshNode* n = mesh->FindNode(aString.toLong());
771     if (!n)
772       return;
773
774     XSpin->SetValue(n->X());
775     YSpin->SetValue(n->Y());
776     ZSpin->SetValue(n->Z());
777   }
778   else
779   {
780     return;
781   }
782
783   onDisplaySimulation(true);
784   CheckIsEnable();
785 }
786
787 //=================================================================================
788 // function : SetEditCurrentArgument()
789 // purpose  :
790 //=================================================================================
791 void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument()
792 {
793   QPushButton* send = (QPushButton*)sender();
794   if ( sender() == BasePointGrp )
795     send = SelectBasePointButton;
796   if (send != SelectPathMeshButton   &&
797       send != SelectStartPointButton &&
798       send != SelectBasePointButton)
799     return;
800   SetEditCurrentArgument(send);
801 }
802
803 //=================================================================================
804 // function : SetEditCurrentArgument()
805 // purpose  :
806 //=================================================================================
807 void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QPushButton* button)
808 {
809   disconnect(mySelectionMgr, 0, this, 0);
810   //  mySelectionMgr->clearSelected();
811   mySelectionMgr->clearFilters();
812   SMESH::SetPickable();
813
814   myEditCurrentArgument = 0;
815   if (button == SelectPathMeshButton)
816   {
817     myEditCurrentArgument = PathMeshLineEdit;
818     SMESH::SetPointRepresentation(false);
819     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
820       aViewWindow->SetSelectionMode(ActorSelection);
821     mySelectionMgr->installFilter(myPathMeshFilter);
822   }
823   else if (button == SelectStartPointButton)
824   {
825     myEditCurrentArgument = StartPointLineEdit;
826     if (!myPath->_is_nil()) {
827       SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
828       if (aPathActor) {
829         SMESH::SetPointRepresentation(true);
830         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
831           aViewWindow->SetSelectionMode(NodeSelection);
832         SMESH::SetPickable(aPathActor);
833       }
834     }
835   }
836   else if (button == SelectBasePointButton)
837   {
838     myEditCurrentArgument = XSpin;
839     SMESH::SetPointRepresentation(true);
840     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
841       aViewWindow->SetSelectionMode(NodeSelection);
842
843     SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter(SMESH::IDSOURCE);
844     SMESH_NumberFilter* aVertexFilter      = new SMESH_NumberFilter ("GEOM", TopAbs_SHAPE,
845                                                                      -1, TopAbs_VERTEX);
846     QList<SUIT_SelectionFilter*> aListOfFilters;
847     if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
848     if (aVertexFilter)        aListOfFilters.append(aVertexFilter);
849
850     mySelectionMgr->installFilter(new SMESH_LogicalFilter
851                                   (aListOfFilters, SMESH_LogicalFilter::LO_OR, true));
852   }
853
854   if (myEditCurrentArgument && !myEditCurrentArgument->hasFocus())
855     myEditCurrentArgument->setFocus();
856
857   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
858   SelectionIntoArgument();
859 }
860
861 //=================================================================================
862 // function : DeactivateActiveDialog()
863 // purpose  : Deactivates this dialog
864 //=================================================================================
865 void SMESHGUI_ExtrusionAlongPathDlg::DeactivateActiveDialog()
866 {
867   if (GroupButtons->isEnabled())
868   {
869     GroupArguments->setEnabled(false);
870     GroupButtons->setEnabled(false);
871     SelectorWdg->setEnabled(false);
872     mySMESHGUI->ResetState();
873     mySMESHGUI->SetActiveDialogBox(0);
874   }
875 }
876
877 //=================================================================================
878 // function : ActivateThisDialog()
879 // purpose  : Activates this dialog
880 //=================================================================================
881 void SMESHGUI_ExtrusionAlongPathDlg::ActivateThisDialog()
882 {
883   // Emit a signal to deactivate the active dialog
884   mySMESHGUI->EmitSignalDeactivateDialog();
885   GroupArguments->setEnabled(true);
886   GroupButtons->setEnabled(true);
887   SelectorWdg->setEnabled(true);
888
889   mySMESHGUI->SetActiveDialogBox(this);
890   SelectionIntoArgument();
891 }
892
893 //=================================================================================
894 // function : enterEvent()
895 // purpose  :
896 //=================================================================================
897 void SMESHGUI_ExtrusionAlongPathDlg::enterEvent (QEvent*)
898 {
899   if ( !GroupButtons->isEnabled() ) {
900     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
901     if ( aViewWindow && !mySelector) {
902       mySelector = aViewWindow->GetSelector();
903     }
904     ActivateThisDialog();
905   }
906 }
907
908 //=======================================================================
909 // function : OnAngleAdded()
910 // purpose  : Called when user adds angle to the list
911 //=======================================================================
912 void SMESHGUI_ExtrusionAlongPathDlg::OnAngleAdded()
913 {
914   QString msg;
915   if( !AngleSpin->isValid( msg, true ) ) {
916     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
917     if ( !msg.isEmpty() )
918       str += "\n" + msg;
919     SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
920     return;
921   }
922   AnglesList->addItem(AngleSpin->text());
923   myAnglesList.append(AngleSpin->GetValue());
924
925   updateLinearAngles();
926 }
927
928 //=======================================================================
929 // function : OnAngleRemoved()
930 // purpose  : Called when user removes angle(s) from the list
931 //=======================================================================
932 void SMESHGUI_ExtrusionAlongPathDlg::OnAngleRemoved()
933 {
934   QList<QListWidgetItem*> aList = AnglesList->selectedItems();
935   QListWidgetItem* anItem;
936   foreach(anItem, aList) {
937     myAnglesList.removeAt(AnglesList->row(anItem));
938     delete anItem;
939   }
940
941   updateLinearAngles();
942 }
943
944 //=================================================================================
945 // function : eventFilter()
946 // purpose  : event filter ???
947 //=================================================================================
948 bool SMESHGUI_ExtrusionAlongPathDlg::eventFilter (QObject* object, QEvent* event)
949 {
950   if (event->type() == QEvent::KeyPress) {
951     QKeyEvent* ke = (QKeyEvent*)event;
952     if (object == AnglesList) {
953       if (ke->key() == Qt::Key_Delete)
954         OnAngleRemoved();
955     }
956   }
957   else if (event->type() == QEvent::FocusIn) {
958     if (object == StartPointLineEdit) {
959       if (myEditCurrentArgument != StartPointLineEdit)
960         SetEditCurrentArgument(SelectStartPointButton);
961     }
962     else if (object == XSpin->editor() || object == YSpin->editor() || object == ZSpin->editor()) {
963       if (myEditCurrentArgument != XSpin)
964         SetEditCurrentArgument(SelectBasePointButton);
965     }
966   }
967   return QDialog::eventFilter(object, event);
968 }
969
970 //=================================================================================
971 // function : keyPressEvent()
972 // purpose  :
973 //=================================================================================
974 void SMESHGUI_ExtrusionAlongPathDlg::keyPressEvent( QKeyEvent* e )
975 {
976   QDialog::keyPressEvent( e );
977   if ( e->isAccepted() )
978     return;
979
980   if ( e->key() == Qt::Key_F1 ) {
981     e->accept();
982     ClickOnHelp();
983   }
984 }
985
986 //=================================================================================
987 // function : isValid
988 // purpose  :
989 //=================================================================================
990 bool SMESHGUI_ExtrusionAlongPathDlg::isValid()
991 {
992   QString msg;
993   bool ok = true;
994   ok = XSpin->isValid( msg, true ) && ok;
995   ok = YSpin->isValid( msg, true ) && ok;
996   ok = ZSpin->isValid( msg, true ) && ok;
997
998   if( !ok ) {
999     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
1000     if ( !msg.isEmpty() )
1001       str += "\n" + msg;
1002     SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
1003     return false;
1004   }
1005   return true;
1006 }
1007
1008 //=================================================================================
1009 // function : updateLinearAngles
1010 // purpose  :
1011 //=================================================================================
1012 void SMESHGUI_ExtrusionAlongPathDlg::updateLinearAngles()
1013 {
1014   bool enableLinear = true;
1015   for( int row = 0, nbRows = AnglesList->count(); row < nbRows; row++ ) {
1016     if( QListWidgetItem* anItem = AnglesList->item( row ) ) {
1017       enableLinear = false;
1018       anItem->text().toDouble(&enableLinear);
1019       if( !enableLinear )
1020         break;
1021     }
1022   }
1023   if( !enableLinear )
1024     LinearAnglesCheck->setChecked( false );
1025   LinearAnglesCheck->setEnabled( enableLinear );
1026 }
1027
1028 //=================================================================================
1029 // function : isValuesValid()
1030 // purpose  : Return true in case if values entered into dialog are valid
1031 //=================================================================================
1032
1033 bool SMESHGUI_ExtrusionAlongPathDlg::isValuesValid()
1034
1035   if ( myPath->_is_nil() )
1036     return false;
1037   
1038   bool bOk;
1039   long aNodeStart = StartPointLineEdit->text().toLong(&bOk);
1040   if ( !bOk || aNodeStart < 1 )
1041     return false;
1042
1043   SMESH::SMESH_Mesh_var mesh = myPath->GetMesh();
1044   if ( mesh->_is_nil() )
1045     return false;
1046
1047   SMESH::ElementType type = mesh->GetElementType( aNodeStart, false );
1048   if ( type != SMESH::NODE )
1049     return false;
1050
1051   if ( mesh->HasShapeToMesh() )
1052   {
1053     SMESH::NodePosition_var pos = mesh->GetNodePosition( aNodeStart );
1054     if ( pos->shapeType != GEOM::VERTEX )
1055       return false;
1056   }
1057   else
1058   {
1059     SMESH::long_array_var elems = mesh->GetNodeInverseElements( aNodeStart );
1060     if ( elems->length() != 1 ||
1061          mesh->GetElementType( elems[0], true ) != SMESH::EDGE )
1062       return false;
1063   }
1064   return true;
1065 }
1066
1067 //=================================================================================
1068 // function : onDisplaySimulation
1069 // purpose  : Show/Hide preview
1070 //=================================================================================
1071
1072 void SMESHGUI_ExtrusionAlongPathDlg::onDisplaySimulation( bool toDisplayPreview )
1073 {
1074   if ( myPreviewCheckBox->isChecked() && toDisplayPreview ) {
1075     if ( SelectorWdg->IsAnythingSelected() && isValid() && isValuesValid())
1076     {
1077       // get angles
1078       SMESH::double_array_var anAngles = getAngles();
1079       
1080       // get base point
1081       SMESH::PointStruct aBasePoint;
1082       if (BasePointGrp->isChecked()) {
1083         aBasePoint.x = XSpin->GetValue();
1084         aBasePoint.y = YSpin->GetValue();
1085         aBasePoint.z = ZSpin->GetValue();
1086       }
1087       bool bOk;
1088       long aNodeStart = StartPointLineEdit->text().toLong(&bOk);
1089       if (bOk) {
1090
1091         try {
1092           SUIT_OverrideCursor wc;
1093
1094           SMESH::SMESH_MeshEditor::Extrusion_Error retVal;
1095           SMESH::SMESH_Mesh_var             mesh = SelectorWdg->GetMesh();
1096           SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditPreviewer();
1097
1098           SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
1099           SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
1100           SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
1101           SelectorWdg->GetSelected( nodes, edges, faces );
1102           const bool makeGroups = false;
1103
1104           SMESH::ListOfGroups_var groups =
1105             meshEditor->ExtrusionAlongPathObjects( nodes, edges, faces, myPath,
1106                                                    GEOM::GEOM_Object::_nil(),
1107                                                    aNodeStart, AnglesGrp->isChecked(),
1108                                                    anAngles, LinearAnglesCheck->isChecked(),
1109                                                    BasePointGrp->isChecked(), aBasePoint,
1110                                                    makeGroups, retVal );
1111
1112           if( retVal == SMESH::SMESH_MeshEditor::EXTR_OK )
1113           {
1114             SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
1115             mySimulation->SetData( aMeshPreviewStruct._retn() );
1116           }
1117           else {
1118             hidePreview();
1119           }
1120
1121         } catch (...) {
1122           hidePreview();
1123         }
1124       } else {
1125         hidePreview();
1126       }
1127
1128     } else {
1129       hidePreview();
1130     }
1131   } else {
1132     hidePreview();
1133   }
1134 }
1135
1136 SMESH::double_array_var SMESHGUI_ExtrusionAlongPathDlg::getAngles()
1137 {
1138   SMESH::double_array_var anAngles = new SMESH::double_array;
1139   if (AnglesGrp->isChecked())
1140   {
1141     anAngles->length(myAnglesList.count());
1142     int j = 0;
1143     for (int i = 0; i < myAnglesList.count(); i++) {
1144       double angle = myAnglesList[i];
1145       anAngles[ j++ ] = angle*M_PI/180.;
1146     }
1147     anAngles->length(j);
1148   }
1149   return anAngles;
1150 }