Salome HOME
#17636 [CEA 17369] Extrusion by normal: along average normal option issue
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_ExtrusionDlg.cxx
index 0a7901267b630e6cb8e1900e3a7fbda257f10be7..2fe9e92bcc5b7ec3b7e9138c963bf8cf47dcae42 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESHGUI_ExtrusionDlg.h"
 
 #include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_MeshUtils.h"
-#include "SMESHGUI_SpinBox.h"
-#include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_MeshEditPreview.h"
-
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include <GEOMBase.h>
+#include <SMDS_Mesh.hxx>
 #include <SMESH_Actor.h>
-#include <SMESH_TypeFilter.hxx>
 #include <SMESH_LogicalFilter.hxx>
-
-#include <SMDS_Mesh.hxx>
+#include <SMESH_TypeFilter.hxx>
 
 // SALOME GUI includes
-#include <SUIT_ResourceMgr.h>
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
 #include <SUIT_Desktop.h>
 #include <SUIT_MessageBox.h>
-#include <SUIT_Session.h>
 #include <SUIT_OverrideCursor.h>
-
-#include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
-
 #include <SalomeApp_IntSpinBox.h>
 
 // OCCT includes
-#include <TColStd_MapOfInteger.hxx>
+#include <BRep_Tool.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <gp_XYZ.hxx>
 
 // Qt includes
 #include <QApplication>
 #include <QButtonGroup>
+#include <QCheckBox>
+#include <QGridLayout>
 #include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
 #include <QLabel>
 #include <QLineEdit>
+#include <QListWidget>
 #include <QPushButton>
 #include <QRadioButton>
-#include <QCheckBox>
-#include <QHBoxLayout>
+#include <QToolButton>
 #include <QVBoxLayout>
-#include <QGridLayout>
-#include <QKeyEvent>
 
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Group)
 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+#include <SMESH_NumberFilter.hxx>
 
 #define SPACING 6
 #define MARGIN  11
@@ -336,7 +337,7 @@ void SMESHGUI_3TypesSelector::onTextChange( const QString& theNewText )
 
   myBusy = true;
 
-  // hilight entered elements/nodes
+  // highlight entered elements/nodes
 
   myIDSource[ iType ]->length( 0 );
 
@@ -397,7 +398,7 @@ void SMESHGUI_3TypesSelector::addTmpIdSource( SMESH::long_array_var& ids, int iT
   SMESH::SMESH_IDSource_var idSrc =
     aMeshEditor->MakeIDSource( ids, SMESH::ElementType( iType+1 ));
 
-  if ( myIDSource[ iType ]->length() <= index )
+  if ( (int) myIDSource[ iType ]->length() <= index )
     myIDSource[ iType ]->length( index + 1 );
   myIDSource[ iType ][ index ] = idSrc;
 
@@ -595,7 +596,10 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   : SMESHGUI_PreviewDlg( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
 {
-  QPixmap image (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
+  SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
+  QPixmap selectImage ( mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+  QPixmap addImage    ( mgr->loadPixmap("SMESH", tr("ICON_APPEND")));
+  QPixmap removeImage ( mgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
 
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
@@ -638,8 +642,8 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
 
   TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments);
 
-  SelectVectorButton = new QPushButton(GroupArguments);
-  SelectVectorButton->setIcon(image);
+  SelectVectorButton = new QPushButton( GroupArguments );
+  SelectVectorButton->setIcon( selectImage );
   SelectVectorButton->setCheckable( true );
   SelectorWdg->GetButtonGroup()->addButton( SelectVectorButton );
 
@@ -671,6 +675,98 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   //Preview check box
   myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
 
+  // Base point
+
+  BasePointGrp = new QGroupBox(tr("BASE_POINT"), GroupArguments);
+  BasePointGrp->setCheckable(true);
+  BasePointGrp->setChecked(false);
+  QHBoxLayout* BasePointGrpLayout = new QHBoxLayout(BasePointGrp);
+  BasePointGrpLayout->setSpacing(SPACING); BasePointGrpLayout->setMargin(MARGIN);
+
+  SelectBasePointButton = new QPushButton(BasePointGrp);
+  SelectBasePointButton->setIcon(selectImage);
+  SelectBasePointButton->setCheckable(true);
+  SelectorWdg->GetButtonGroup()->addButton( SelectBasePointButton );
+
+  QLabel* XLab  = new QLabel(tr("SMESH_X"), BasePointGrp);
+  BasePoint_XSpin = new SMESHGUI_SpinBox(BasePointGrp);
+  BasePoint_XSpin->SetValue(0.);
+  QLabel* YLab  = new QLabel(tr("SMESH_Y"), BasePointGrp);
+  BasePoint_YSpin = new SMESHGUI_SpinBox(BasePointGrp);
+  BasePoint_YSpin->SetValue(0.);
+  QLabel* ZLab  = new QLabel(tr("SMESH_Z"), BasePointGrp);
+  BasePoint_ZSpin = new SMESHGUI_SpinBox(BasePointGrp);
+  BasePoint_ZSpin->SetValue(0.);
+
+  BasePointGrpLayout->addWidget(SelectBasePointButton);
+  BasePointGrpLayout->addWidget(XLab);
+  BasePointGrpLayout->addWidget(BasePoint_XSpin, 1);
+  BasePointGrpLayout->addWidget(YLab);
+  BasePointGrpLayout->addWidget(BasePoint_YSpin, 1);
+  BasePointGrpLayout->addWidget(ZLab);
+  BasePointGrpLayout->addWidget(BasePoint_ZSpin, 1);
+
+  // Scales
+
+  ScalesGrp = new QGroupBox(tr("SMESH_SCALES"), GroupArguments);
+  ScalesGrp->setCheckable(true);
+  ScalesGrp->setChecked(false);
+  QGridLayout* ScalesGrpLayout = new QGridLayout( ScalesGrp );
+  ScalesGrpLayout->setSpacing(SPACING); ScalesGrpLayout->setMargin(MARGIN);
+
+  ScalesList = new QListWidget( ScalesGrp );
+  ScalesList->setSelectionMode(QListWidget::ExtendedSelection);
+
+  AddScaleButton = new QToolButton( ScalesGrp );
+  AddScaleButton->setIcon( addImage );
+
+  RemoveScaleButton = new QToolButton( ScalesGrp );
+  RemoveScaleButton->setIcon( removeImage );
+
+  ScaleSpin = new SMESHGUI_SpinBox( ScalesGrp );
+  ScaleSpin->SetValue(2);
+
+  LinearScalesCheck = new QCheckBox(tr("LINEAR_SCALES"), ScalesGrp );
+
+  ScalesGrpLayout->addWidget(ScalesList,        0, 0, 4, 1);
+  ScalesGrpLayout->addWidget(AddScaleButton,    0, 1);
+  ScalesGrpLayout->addWidget(RemoveScaleButton, 2, 1);
+  ScalesGrpLayout->addWidget(ScaleSpin,         0, 2);
+  ScalesGrpLayout->addWidget(LinearScalesCheck, 4, 0, 1, 3);
+  ScalesGrpLayout->setRowMinimumHeight(1, 10);
+  ScalesGrpLayout->setRowStretch(3, 10);
+
+  // Angles
+
+  AnglesGrp = new QGroupBox(tr("SMESH_ANGLES"), GroupArguments);
+  AnglesGrp->setCheckable(true);
+  AnglesGrp->setChecked(false);
+  QGridLayout* AnglesGrpLayout = new QGridLayout( AnglesGrp );
+  AnglesGrpLayout->setSpacing(SPACING); AnglesGrpLayout->setMargin(MARGIN);
+
+  AnglesList = new QListWidget( AnglesGrp );
+  AnglesList->setSelectionMode(QListWidget::ExtendedSelection);
+
+  AddAngleButton = new QToolButton( AnglesGrp );
+  AddAngleButton->setIcon( addImage );
+
+  RemoveAngleButton = new QToolButton( AnglesGrp );
+  RemoveAngleButton->setIcon( removeImage );
+
+  AngleSpin = new SMESHGUI_SpinBox( AnglesGrp );
+  AngleSpin->SetValue(10);
+
+  LinearAnglesCheck = new QCheckBox(tr("LINEAR_ANGLES"), AnglesGrp );
+
+  AnglesGrpLayout->addWidget(AnglesList,        0, 0, 4, 1);
+  AnglesGrpLayout->addWidget(AddAngleButton,    0, 1);
+  AnglesGrpLayout->addWidget(RemoveAngleButton, 2, 1);
+  AnglesGrpLayout->addWidget(AngleSpin,         0, 2);
+  AnglesGrpLayout->addWidget(LinearAnglesCheck, 4, 0, 1, 3);
+  AnglesGrpLayout->setRowMinimumHeight(1, 10);
+  AnglesGrpLayout->setRowStretch(3, 10);
+
+  // layouting
   GroupArgumentsLayout->addWidget(SelectorWdg,            0, 0, 1, 9);
   GroupArgumentsLayout->addWidget(ExtrMethod_RBut0,       1, 0, 1, 3);
   GroupArgumentsLayout->addWidget(ExtrMethod_RBut1,       1, 3, 1, 3);
@@ -696,8 +792,11 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   GroupArgumentsLayout->addWidget(SpinBox_NbSteps,        5, 3);
   GroupArgumentsLayout->addWidget(ByAverageNormalCheck,   6, 0, 1, 4);
   GroupArgumentsLayout->addWidget(UseInputElemsOnlyCheck, 6, 4, 1, 4);
-  GroupArgumentsLayout->addWidget(myPreviewCheckBox,      7, 0, 1, 8);
-  GroupArgumentsLayout->addWidget(MakeGroupsCheck,        8, 0, 1, 8);
+  GroupArgumentsLayout->addWidget(BasePointGrp,           7, 0, 1, 9);
+  GroupArgumentsLayout->addWidget(ScalesGrp,              8, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(AnglesGrp,              8, 5, 1, 4);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,      9, 0, 1, 8);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,        10,0, 1, 8);
   GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 10, 0);
 
   /***************************************************************/
@@ -740,15 +839,21 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   SpinBox_NbSteps->setRange(1, 999999);
   SpinBox_VDist->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
+  BasePoint_XSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  BasePoint_YSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  BasePoint_ZSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  ScaleSpin->RangeStepAndValidator      (COORD_MIN, COORD_MAX, 1.0, "length_precision");
+  AngleSpin->RangeStepAndValidator      (-180.0, 180.0, 5.0, "angle_precision");
+
   ExtrMethod_RBut0->setChecked(true);
   UseInputElemsOnlyCheck->setChecked(true);
   MakeGroupsCheck->setChecked(true);
 
-  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+  mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
 
   mySMESHGUI->SetActiveDialogBox(this);
 
-  myHelpFileName = "extrusion_page.html";
+  myHelpFileName = "extrusion.html";
 
   Init();
 
@@ -771,13 +876,23 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   connect(SpinBox_Dy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
   connect(SpinBox_Dz, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
 
+  connect(AddScaleButton,    SIGNAL(clicked()), this, SLOT(OnScaleAdded()));
+  connect(RemoveScaleButton, SIGNAL(clicked()), this, SLOT(OnScaleRemoved()));
+  connect(AddAngleButton,    SIGNAL(clicked()), this, SLOT(OnScaleAdded()));
+  connect(RemoveAngleButton, SIGNAL(clicked()), this, SLOT(OnScaleRemoved()));
+
   connect(SelectVectorButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+  connect(SelectBasePointButton,SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+  connect(BasePointGrp,         SIGNAL(toggled(bool)), this, SLOT(SetEditCurrentArgument()));
+  connect(BasePointGrp,         SIGNAL(toggled(bool)), SelectBasePointButton, SLOT(click()));
   connect(mySMESHGUI,           SIGNAL(SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
   connect(mySelectionMgr,       SIGNAL(currentSelectionChanged()), SLOT(toDisplaySimulation()));
   connect(SelectorWdg,          SIGNAL(selectionChanged()), this, SLOT(toDisplaySimulation()));
   connect(SelectorWdg,          SIGNAL(selectionChanged()), this, SLOT(CheckIsEnable()));
   /* to close dialog if study change */
-  connect(mySMESHGUI,           SIGNAL(SignalCloseAllDialogs()),   this, SLOT(reject()));
+  connect(mySMESHGUI,           SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI,           SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI,           SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
 
   connect(SpinBox_Dx,      SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
   connect(SpinBox_Dy,      SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
@@ -789,6 +904,18 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   connect(SpinBox_NbSteps, SIGNAL(valueChanged(int)),    this, SLOT(toDisplaySimulation()));
   connect(ByAverageNormalCheck,   SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
   connect(UseInputElemsOnlyCheck, SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
+  connect(AddScaleButton,         SIGNAL(clicked()),     this, SLOT(toDisplaySimulation()));
+  connect(RemoveScaleButton,      SIGNAL(clicked()),     this, SLOT(toDisplaySimulation()));
+  connect(LinearScalesCheck,      SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
+  connect(AddAngleButton,         SIGNAL(clicked()),     this, SLOT(toDisplaySimulation()));
+  connect(RemoveAngleButton,      SIGNAL(clicked()),     this, SLOT(toDisplaySimulation()));
+  connect(LinearAnglesCheck,      SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
+  connect(BasePointGrp,           SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
+  connect(BasePoint_XSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(BasePoint_YSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(BasePoint_ZSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(ScalesGrp,       SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
+  connect(AnglesGrp,       SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
 
   //To Connect preview check box
   connectPreviewControl();
@@ -873,6 +1000,44 @@ bool SMESHGUI_ExtrusionDlg::isValuesValid()
   return aModule > 1.0E-38;
 }
 
+//=======================================================================
+//function : getScaleParams
+//purpose  : return 3 scaling parameters
+//=======================================================================
+
+void SMESHGUI_ExtrusionDlg::getScaleParams( SMESH::double_array*& scales,
+                                            SMESH::double_array*& basePoint,
+                                            bool &                scalesVariation,
+                                            SMESH::double_array*& angles,
+                                            bool &                anglesVariation )
+{
+  scales = new SMESH::double_array;
+  if ( ScalesGrp->isChecked() )
+  {
+    scales->length( myScalesList.count() );
+    for ( int i = 0; i < myScalesList.count(); ++i )
+      (*scales)[i] = myScalesList[i];
+  }
+  angles = new SMESH::double_array;
+  if ( AnglesGrp->isChecked() )
+  {
+    angles->length( myAnglesList.count() );
+    for ( int i = 0; i < myAnglesList.count(); ++i )
+      (*angles)[i] = myAnglesList[i]*M_PI/180.;
+  }
+  basePoint = new SMESH::double_array;
+  if ( BasePointGrp->isChecked() )
+  {
+    basePoint->length( 3 );
+    (*basePoint)[0] = BasePoint_XSpin->GetValue();
+    (*basePoint)[1] = BasePoint_YSpin->GetValue();
+    (*basePoint)[2] = BasePoint_ZSpin->GetValue();
+  }
+
+  scalesVariation = ( scales->length() > 0 && LinearScalesCheck->isChecked() );
+  anglesVariation = ( angles->length() > 0 && LinearAnglesCheck->isChecked() );
+}
+
 //=================================================================================
 // function : ClickOnRadio()
 // purpose  : Radio button management
@@ -961,6 +1126,11 @@ void SMESHGUI_ExtrusionDlg::ClickOnRadio()
     SelectorWdg->SetEnabled( false, SMESH::EDGE );
   }
 
+  BasePointGrp->setEnabled( !ExtrMethod_RBut2->isChecked() );
+  ScalesGrp   ->setEnabled( !ExtrMethod_RBut2->isChecked() );
+  AnglesGrp   ->setEnabled( !ExtrMethod_RBut2->isChecked() );
+
+
   CheckIsEnable();
 
   onDisplaySimulation(true);
@@ -977,7 +1147,7 @@ void SMESHGUI_ExtrusionDlg::ClickOnRadio()
 
 bool SMESHGUI_ExtrusionDlg::ClickOnApply()
 {
-  if (mySMESHGUI->isActiveStudyLocked())
+  if (SMESHGUI::isStudyLocked())
     return false;
 
   if (!isValid())
@@ -987,7 +1157,7 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
   {
     SMESH::DirStruct aVector;
     getExtrusionVector(aVector);
-    
+
     QStringList aParameters;
     if ( ExtrMethod_RBut0->isChecked() )
     {
@@ -1009,14 +1179,20 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
     }
 
     long aNbSteps = (long)SpinBox_NbSteps->value();
-
     aParameters << SpinBox_NbSteps->text();
 
+    for (int i = 0; i < myScalesList.count(); i++)
+      aParameters << ScalesList->item(i)->text();
+
+    for (int i = 0; i < myAnglesList.count(); i++)
+      aParameters << AnglesList->item(i)->text();
+
     bool meshHadNewTypeBefore = true;
     int  maxSelType = 0;
     const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
 
-    try {
+    try
+    {
       SUIT_OverrideCursor aWaitCursor;
 
       SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh();
@@ -1036,7 +1212,7 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
       SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditor();
       SMESH::ListOfGroups_var groups;
 
-      mesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+      mesh->SetParameters( aParameters.join(":").toUtf8().constData() );
 
       if ( ExtrMethod_RBut2->isVisible() &&
            ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
@@ -1047,13 +1223,19 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
         bool   byAverageNormal   = ByAverageNormalCheck->isChecked();
         int    dim               = (maxSelType == SMESH::FACE) ? 2 : 1;
 
-        groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, useInputElemsOnly,
-                                                byAverageNormal, makeGroups, dim );
+        groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, byAverageNormal,
+                                                useInputElemsOnly, makeGroups, dim );
       }
       else
       {
+        SMESH::double_array_var scales, basePoint, angles;
+        bool scalesVariation, anglesVariation;
+        getScaleParams( scales.out(), basePoint.out(), scalesVariation,
+                        angles.out(), anglesVariation );
         groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
-                                                    aVector, aNbSteps, makeGroups );
+                                                    aVector, aNbSteps, makeGroups,
+                                                    scales, scalesVariation, basePoint,
+                                                    angles, anglesVariation );
       }
 
     } catch (...) {
@@ -1079,9 +1261,9 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
       SMESH::Update( actor->getIO(), actor->GetVisibility() );
     if ( makeGroups )
       mySMESHGUI->updateObjBrowser(true); // new groups may appear
-    Init(false);
+
     mySelectionMgr->clearSelected();
-    SelectorWdg->Clear();
+    Init(false);
 
     SMESHGUI::Modified();
   }
@@ -1119,6 +1301,31 @@ void SMESHGUI_ExtrusionDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -1137,7 +1344,7 @@ void SMESHGUI_ExtrusionDlg::ClickOnHelp()
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
                                                                  platform)).
                              arg(myHelpFileName));
   }
@@ -1153,13 +1360,13 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
   if (!GroupButtons->isEnabled())
     return;
 
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects(aList);
+  if ( aList.IsEmpty() || aList.Extent() > 1 )
+    return;
+
   if ( SelectVectorButton->isChecked() )
   {
-    SALOME_ListIO aList;
-    mySelectionMgr->selectedObjects(aList);
-    if ( aList.IsEmpty() || aList.Extent() > 1 )
-      return;
-
     Handle(SALOME_InteractiveObject) IO = aList.First();
     TColStd_IndexedMapOfInteger aMapIndex;
     mySelector->GetIndex(IO,aMapIndex);
@@ -1171,7 +1378,7 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
       return;
 
     const SMDS_MeshFace* face =
-      dynamic_cast<const SMDS_MeshFace*>(aMesh->FindElement(aMapIndex(1)));
+      aMesh->DownCast< SMDS_MeshFace >(aMesh->FindElement(aMapIndex(1)));
     if (!face)
       return;
 
@@ -1180,6 +1387,56 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
     SpinBox_Vy->SetValue(aNormale.Y());
     SpinBox_Vz->SetValue(aNormale.Z());
   }
+  else if ( SelectBasePointButton->isChecked() )
+  {
+    if (!BasePointGrp->isChecked())
+      return;
+
+    // try to get shape from selection
+    Handle(SALOME_InteractiveObject) IO = aList.First();
+
+    // check if geom vertex is selected
+    GEOM::GEOM_Object_var aGeomObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(IO);
+    TopoDS_Vertex aVertex;
+    if (!aGeomObj->_is_nil()) {
+      if (aGeomObj->IsShape() && GEOMBase::GetShape(aGeomObj, aVertex) && !aVertex.IsNull()) {
+        gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
+        BasePoint_XSpin->SetValue(aPnt.X());
+        BasePoint_YSpin->SetValue(aPnt.Y());
+        BasePoint_ZSpin->SetValue(aPnt.Z());
+      }
+    }
+
+    if ( aVertex.IsNull() )
+    {
+      // check if smesh node is selected
+      SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(IO);
+      if (aMesh->_is_nil())
+        return;
+
+      QString aString;
+      int aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
+      // return if more than one node is selected
+      if (aNbUnits != 1)
+        return;
+
+      SMESH_Actor* aMeshActor = SMESH::FindActorByObject(aMesh);
+      if (!aMeshActor)
+        return;
+
+      SMDS_Mesh* mesh = aMeshActor->GetObject()->GetMesh();
+      if (!mesh)
+        return;
+
+      const SMDS_MeshNode* n = mesh->FindNode(aString.toLong());
+      if (!n)
+        return;
+
+      BasePoint_XSpin->SetValue(n->X());
+      BasePoint_YSpin->SetValue(n->Y());
+      BasePoint_ZSpin->SetValue(n->Z());
+    }
+  }
 
   onDisplaySimulation(true);
   CheckIsEnable();
@@ -1202,6 +1459,21 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->SetSelectionMode(FaceSelection);
   }
+  else if ( send == SelectBasePointButton )
+  {
+    SMESH::SetPointRepresentation(true);
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(NodeSelection);
+
+    SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter(SMESH::IDSOURCE);
+    SMESH_NumberFilter* aVertexFilter      = new SMESH_NumberFilter ("GEOM", TopAbs_VERTEX,
+                                                                     1, TopAbs_VERTEX);
+    QList<SUIT_SelectionFilter*> aListOfFilters;
+    aListOfFilters << aMeshOrSubMeshFilter << aVertexFilter;
+
+    mySelectionMgr->installFilter(new SMESH_LogicalFilter
+                                  (aListOfFilters, SMESH_LogicalFilter::LO_OR, true));
+  }
   
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
   SelectionIntoArgument();
@@ -1240,12 +1512,17 @@ void SMESHGUI_ExtrusionDlg::ActivateThisDialog()
 
 //=================================================================================
 // function : enterEvent()
-// purpose  : Mouse enter event
+// purpose  :
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::enterEvent (QEvent*)
 {
-  if (!GroupButtons->isEnabled())
+  if ( !GroupButtons->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=================================================================================
@@ -1284,6 +1561,12 @@ bool SMESHGUI_ExtrusionDlg::isValid()
   }
   ok = SpinBox_NbSteps->isValid( msg, true ) && ok;
 
+  if ( BasePointGrp->isChecked()) {
+    ok = BasePoint_XSpin->isValid( msg, true ) && ok;
+    ok = BasePoint_YSpin->isValid( msg, true ) && ok;
+    ok = BasePoint_ZSpin->isValid( msg, true ) && ok;
+  }
+
   if( !ok ) {
     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
     if ( !msg.isEmpty() )
@@ -1332,16 +1615,22 @@ void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview )
           bool   byAverageNormal   = ByAverageNormalCheck->isChecked();
           int    dim               = (maxSelType == SMESH::FACE) ? 2 : 1;
 
-          groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, useInputElemsOnly,
-                                                  byAverageNormal, makeGroups, dim );
+          groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, byAverageNormal,
+                                                  useInputElemsOnly, makeGroups, dim );
         }
         else
         {
+          SMESH::double_array_var scales, basePoint, angles;
+          bool scalesVariation, anglesVariation;
+          getScaleParams( scales.out(), basePoint.out(), scalesVariation,
+                          angles.out(), anglesVariation );
           groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
-                                                      aVector, aNbSteps, makeGroups );
+                                                      aVector, aNbSteps, makeGroups,
+                                                      scales, scalesVariation, basePoint,
+                                                      angles, anglesVariation );
         }
         SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
-        mySimulation->SetData(aMeshPreviewStruct._retn());
+        mySimulation->SetData(aMeshPreviewStruct);
 
       } catch (...) {
         hidePreview();
@@ -1379,3 +1668,68 @@ void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector)
     aVector.PS.z = aNormale.Z()*aVDist;
   }
 }
+
+//=======================================================================
+// function : OnScaleAdded()
+// purpose  : Called when user adds Scale or Angle to the list
+//=======================================================================
+void SMESHGUI_ExtrusionDlg::OnScaleAdded()
+{
+  if ( sender() == AddScaleButton )
+  {
+    QString msg;
+    if( !ScaleSpin->isValid( msg, true ) ) {
+      QString str( tr( "SMESH_INCORRECT_INPUT" ) );
+      if ( !msg.isEmpty() )
+        str += "\n" + msg;
+      SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
+      return;
+    }
+    ScalesList->addItem(ScaleSpin->text());
+    myScalesList.append(ScaleSpin->GetValue());
+  }
+
+  if ( sender() == AddAngleButton )
+  {
+    QString msg;
+    if( !AngleSpin->isValid( msg, true ) ) {
+      QString str( tr( "SMESH_INCORRECT_INPUT" ) );
+      if ( !msg.isEmpty() )
+        str += "\n" + msg;
+      SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
+      return;
+    }
+    AnglesList->addItem(AngleSpin->text());
+    myAnglesList.append(AngleSpin->GetValue());
+  }
+}
+
+//=======================================================================
+// function : OnScaleRemoved()
+// purpose  : Called when user removes Scales or Angles from the list
+//=======================================================================
+void SMESHGUI_ExtrusionDlg::OnScaleRemoved()
+{
+  QListWidget* widget;
+  QList<double>* list;
+  if ( sender() == RemoveScaleButton )
+  {
+    widget = ScalesList;
+    list   = & myScalesList;
+  }
+  else
+  {
+    widget = AnglesList;
+    list   = & myAnglesList;
+  }
+
+  QList<QListWidgetItem*> aList = widget->selectedItems();
+  QListWidgetItem* anItem;
+  int row = 0;
+  foreach(anItem, aList) {
+    row = widget->row(anItem);
+    list->removeAt(row);
+    delete anItem;
+  }
+  widget->setCurrentRow( row, QItemSelectionModel::Select );
+}