Salome HOME
23305: [EDF 10301] Extrusion with scaling
authoreap <eap@opencascade.com>
Mon, 1 Aug 2016 12:42:08 +0000 (15:42 +0300)
committereap <eap@opencascade.com>
Mon, 1 Aug 2016 12:42:08 +0000 (15:42 +0300)
12 files changed:
doc/salome/gui/SMESH/images/extrusionalongaline1.png
doc/salome/gui/SMESH/input/extrusion.doc
idl/SMESH_MeshEditor.idl
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionDlg.h
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_SWIG/smeshBuilder.py
src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx

index 5f0d13039f1082c3c0e498abefb40c61dcbfe7b7..7de580be18c7ef18d5903b7752fdfb665fda67ae 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline1.png and b/doc/salome/gui/SMESH/images/extrusionalongaline1.png differ
index 6b07af9e1aa89d836a8adb0cb9140eb05388f725..96da45d43f1c7610f36ca0fae33714c044746b2f 100644 (file)
@@ -128,6 +128,25 @@ The following dialog will appear:
   </ul>
 
   <li>Specify the <b>Number of steps</b>.</li>
   </ul>
 
   <li>Specify the <b>Number of steps</b>.</li>
+
+  <li>Optionally specify <b>Scale Factors</b>. Each scale factor in
+  the list is applied to nodes of a corresponding extrusion step
+  unless <b>Linear Variation of Scale Factors</b> is checked, is
+  which case the scale factors are spread over all extrusion steps.</li>
+  <ul>
+    <li><b>Scaling Center</b> can be defined either using spin boxes
+    or by picking a node in the Viewer or by picking a geometrical
+    vertex in the Object Browser.</li>
+    <li>\b Add button adds a scale factor to the list.
+      \image html add.png
+      <center><em>"Add" button</em></center>
+    </li>
+    <li>\b Remove button removes selected scale factors from the list.
+      \image html remove.png
+      <center><em>"Remove" button</em></center>
+    </li>
+  </ul>
+
   <li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em>
     created from <em>selected elements</em> contained in groups will be
     included into new groups named by pattern "<old group
   <li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em>
     created from <em>selected elements</em> contained in groups will be
     included into new groups named by pattern "<old group
index 28bc6f9122db21ead20e863a68b44c535e3ac32c..120e41e49fa05a9cccdbd790fde417c56a12072f 100644 (file)
@@ -487,6 +487,9 @@ module SMESH
                                        in ListOfIDSources faces,
                                        in DirStruct       stepVector,
                                        in long            nbOfSteps,
                                        in ListOfIDSources faces,
                                        in DirStruct       stepVector,
                                        in long            nbOfSteps,
+                                       in double_array    scaleFactors,
+                                       in boolean         linearVariation,
+                                       in double_array    basePoint,
                                        in boolean         toMakeGroups)
       raises (SALOME::SALOME_Exception);
 
                                        in boolean         toMakeGroups)
       raises (SALOME::SALOME_Exception);
 
index f9eeb5755b97bf692bab72bc5807df54366d8108..f7fcec03e8fd5a6fdd42a1e261cdb4f0329a30f3 100644 (file)
@@ -5480,11 +5480,14 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet   theElemSets[2],
 //purpose  : standard construction
 //=======================================================================
 
 //purpose  : standard construction
 //=======================================================================
 
-SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec&  theStep,
-                                            const int      theNbSteps,
-                                            const int      theFlags,
-                                            const double   theTolerance):
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec&            theStep,
+                                            const int                theNbSteps,
+                                            const std::list<double>& theScales,
+                                            const gp_XYZ*            theBasePoint,
+                                            const int                theFlags,
+                                            const double             theTolerance):
   myDir( theStep ),
   myDir( theStep ),
+  myBaseP( Precision::Infinite(), 0, 0 ),
   myFlags( theFlags ),
   myTolerance( theTolerance ),
   myElemsToUse( NULL )
   myFlags( theFlags ),
   myTolerance( theTolerance ),
   myElemsToUse( NULL )
@@ -5494,6 +5497,37 @@ SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec&  theStep,
   for (int i=1; i<=theNbSteps; i++ )
     mySteps->Append( stepSize );
 
   for (int i=1; i<=theNbSteps; i++ )
     mySteps->Append( stepSize );
 
+  int nbScales = theScales.size();
+  if ( nbScales > 0 )
+  {
+    if ( IsLinearVariation() && nbScales < theNbSteps )
+    {
+      myScales.reserve( theNbSteps );
+      std::list<double>::const_iterator scale = theScales.begin();
+      double prevScale = 1.0;
+      for ( int iSc = 1; scale != theScales.end(); ++scale, ++iSc )
+      {
+        int      iStep = int( iSc / double( nbScales ) * theNbSteps + 0.5 );
+        int    stDelta = Max( 1, iStep - myScales.size());
+        double scDelta = ( *scale - prevScale ) / stDelta;
+        for ( int iStep = 0; iStep < stDelta; ++iStep )
+        {
+          myScales.push_back( prevScale + scDelta );
+          prevScale = myScales.back();
+        }
+        prevScale = *scale;
+      }
+    }
+    else
+    {
+      myScales.assign( theScales.begin(), theScales.end() );
+    }
+  }
+  if ( theBasePoint )
+  {
+    myBaseP = *theBasePoint;
+  }
+
   if (( theFlags & EXTRUSION_FLAG_SEW ) &&
       ( theTolerance > 0 ))
   {
   if (( theFlags & EXTRUSION_FLAG_SEW ) &&
       ( theTolerance > 0 ))
   {
@@ -5562,12 +5596,38 @@ SMESH_MeshEditor::ExtrusParam::ExtrusParam( const double theStepSize,
 //=======================================================================
 //function : ExtrusParam::SetElementsToUse
 //purpose  : stores elements to use for extrusion by normal, depending on
 //=======================================================================
 //function : ExtrusParam::SetElementsToUse
 //purpose  : stores elements to use for extrusion by normal, depending on
-//           state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag
+//           state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag;
+//           define myBaseP for scaling
 //=======================================================================
 
 //=======================================================================
 
-void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems )
+void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems,
+                                                      const TIDSortedElemSet& nodes )
 {
   myElemsToUse = ToUseInpElemsOnly() ? & elems : 0;
 {
   myElemsToUse = ToUseInpElemsOnly() ? & elems : 0;
+
+  if ( Precision::IsInfinite( myBaseP.X() )) // myBaseP not defined
+  {
+    myBaseP.SetCoord( 0.,0.,0. );
+    TIDSortedElemSet newNodes;
+
+    const TIDSortedElemSet* elemSets[] = { &elems, &nodes };
+    for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
+    {
+      const TIDSortedElemSet& elements = *( elemSets[ is2ndSet ]);
+      TIDSortedElemSet::const_iterator itElem = elements.begin();
+      for ( ; itElem != elements.end(); itElem++ )
+      {
+        const SMDS_MeshElement* elem = *itElem;
+        SMDS_ElemIteratorPtr     itN = elem->nodesIterator();
+        while ( itN->more() ) {
+          const SMDS_MeshElement* node = itN->next();
+          if ( newNodes.insert( node ).second )
+            myBaseP += SMESH_TNodeXYZ( node );
+        }
+      }
+    }
+    myBaseP /= newNodes.size();
+  }
 }
 
 //=======================================================================
 }
 
 //=======================================================================
@@ -5637,6 +5697,41 @@ makeNodesByDir( SMESHDS_Mesh*                     mesh,
     const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() );
     newNodes.push_back( newNode );
   }
     const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() );
     newNodes.push_back( newNode );
   }
+
+  if ( !myScales.empty() )
+  {
+    if ( makeMediumNodes && myMediumScales.empty() )
+    {
+      myMediumScales.resize( myScales.size() );
+      double prevFactor = 1.;
+      for ( size_t i = 0; i < myScales.size(); ++i )
+      {
+        myMediumScales[i] = 0.5 * ( prevFactor + myScales[i] );
+        prevFactor = myScales[i];
+      }
+    }
+    typedef std::vector<double>::iterator ScaleIt;
+    ScaleIt scales[] = { myScales.begin(), myMediumScales.begin() };
+
+    size_t iSc = 0, nbScales = myScales.size() + myMediumScales.size();
+
+    gp_XYZ center = myBaseP;
+    std::list<const SMDS_MeshNode*>::iterator nIt = newNodes.begin();
+    size_t iN  = 0;
+    for ( beginStepIter( makeMediumNodes ); moreSteps() && ( iN < nbScales ); ++nIt, ++iN )
+    {
+      center += myDir.XYZ() * nextStep();
+
+      iSc += int( makeMediumNodes );
+      ScaleIt& scale = scales[ iSc % 2 ];
+      
+      gp_XYZ xyz = SMESH_TNodeXYZ( *nIt );
+      xyz = ( *scale * ( xyz - center )) + center;
+      mesh->MoveNode( *nIt, xyz.X(), xyz.Y(), xyz.Z() );
+
+      ++scale;
+    }
+  }
   return nbNodes;
 }
 
   return nbNodes;
 }
 
@@ -5811,7 +5906,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet     theElems[2],
                                   const int            theFlags,
                                   const double         theTolerance)
 {
                                   const int            theFlags,
                                   const double         theTolerance)
 {
-  ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance );
+  ExtrusParam aParams( theStep, theNbSteps, std::list<double>(), 0, theFlags, theTolerance );
   return ExtrusionSweep( theElems, aParams, newElemsMap );
 }
 
   return ExtrusionSweep( theElems, aParams, newElemsMap );
 }
 
@@ -5832,16 +5927,12 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet     theElemSets[2],
   // source elements for each generated one
   SMESH_SequenceOfElemPtr srcElems, srcNodes;
 
   // source elements for each generated one
   SMESH_SequenceOfElemPtr srcElems, srcNodes;
 
-  //SMESHDS_Mesh* aMesh = GetMeshDS();
-
   setElemsFirst( theElemSets );
   const int nbSteps = theParams.NbSteps();
   setElemsFirst( theElemSets );
   const int nbSteps = theParams.NbSteps();
-  theParams.SetElementsToUse( theElemSets[0] );
+  theParams.SetElementsToUse( theElemSets[0], theElemSets[1] );
 
 
-  TNodeOfNodeListMap mapNewNodes;
-  //TNodeOfNodeVecMap mapNewNodes;
+  TNodeOfNodeListMap   mapNewNodes;
   TElemOfVecOfNnlmiMap mapElemNewNodes;
   TElemOfVecOfNnlmiMap mapElemNewNodes;
-  //TElemOfVecOfMapNodesMap mapElemNewNodes;
 
   const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) +
                                      myMesh->NbFaces(ORDER_QUADRATIC) +
 
   const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) +
                                      myMesh->NbFaces(ORDER_QUADRATIC) +
@@ -6656,24 +6747,23 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet                  theElemSets
 
 //=======================================================================
 //function : LinearAngleVariation
 
 //=======================================================================
 //function : LinearAngleVariation
-//purpose  : auxilary for ExtrusionAlongTrack
+//purpose  : spread values over nbSteps
 //=======================================================================
 //=======================================================================
-void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps,
+
+void SMESH_MeshEditor::LinearAngleVariation(const int     nbSteps,
                                             list<double>& Angles)
 {
   int nbAngles = Angles.size();
                                             list<double>& Angles)
 {
   int nbAngles = Angles.size();
-  if( nbSteps > nbAngles ) {
+  if( nbSteps > nbAngles && nbAngles > 0 )
+  {
     vector<double> theAngles(nbAngles);
     vector<double> theAngles(nbAngles);
-    list<double>::iterator it = Angles.begin();
-    int i = -1;
-    for(; it!=Angles.end(); it++) {
-      i++;
-      theAngles[i] = (*it);
-    }
+    theAngles.assign( Angles.begin(), Angles.end() );
+
     list<double> res;
     double rAn2St = double( nbAngles ) / double( nbSteps );
     double angPrev = 0, angle;
     list<double> res;
     double rAn2St = double( nbAngles ) / double( nbSteps );
     double angPrev = 0, angle;
-    for ( int iSt = 0; iSt < nbSteps; ++iSt ) {
+    for ( int iSt = 0; iSt < nbSteps; ++iSt )
+    {
       double angCur = rAn2St * ( iSt+1 );
       double angCurFloor  = floor( angCur );
       double angPrevFloor = floor( angPrev );
       double angCur = rAn2St * ( iSt+1 );
       double angCurFloor  = floor( angCur );
       double angPrevFloor = floor( angPrev );
@@ -6695,10 +6785,7 @@ void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps,
       res.push_back(angle);
       angPrev = angCur;
     }
       res.push_back(angle);
       angPrev = angCur;
     }
-    Angles.clear();
-    it = res.begin();
-    for(; it!=res.end(); it++)
-      Angles.push_back( *it );
+    Angles.swap( res );
   }
 }
 
   }
 }
 
index 4e9d0220d7940726dbb371cf797fc4e2247faac5..5dd53807a813bcac52c0ba0270c3b0c8f1d4f79b 100644 (file)
@@ -293,21 +293,26 @@ public:
    *                else step size is measured along average normal of any element
    * USE_INPUT_ELEMS_ONLY: to use only input elements to compute extrusion direction
    *                       for ExtrusionByNormal()
    *                else step size is measured along average normal of any element
    * USE_INPUT_ELEMS_ONLY: to use only input elements to compute extrusion direction
    *                       for ExtrusionByNormal()
+   * SCALE_LINEAR_VARIATION: to make linear variation of scale factors
    */
   enum ExtrusionFlags {
     EXTRUSION_FLAG_BOUNDARY = 0x01,
     EXTRUSION_FLAG_SEW = 0x02,
     EXTRUSION_FLAG_GROUPS = 0x04,
     EXTRUSION_FLAG_BY_AVG_NORMAL = 0x08,
    */
   enum ExtrusionFlags {
     EXTRUSION_FLAG_BOUNDARY = 0x01,
     EXTRUSION_FLAG_SEW = 0x02,
     EXTRUSION_FLAG_GROUPS = 0x04,
     EXTRUSION_FLAG_BY_AVG_NORMAL = 0x08,
-    EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY = 0x10
+    EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY = 0x10,
+    EXTRUSION_FLAG_SCALE_LINEAR_VARIATION = 0x20
   };
 
   /*!
    * Generator of nodes for extrusion functionality
    */
   };
 
   /*!
    * Generator of nodes for extrusion functionality
    */
-  class SMESH_EXPORT ExtrusParam {
+  class SMESH_EXPORT ExtrusParam
+  {
     gp_Dir                          myDir;   // direction of extrusion
     Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step
     gp_Dir                          myDir;   // direction of extrusion
     Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step
+    std::vector<double>             myScales, myMediumScales;// scale factors
+    gp_XYZ                          myBaseP; // scaling center
     SMESH_SequenceOfNode            myNodes; // nodes for using in sewing
     int                             myFlags; // see ExtrusionFlags
     double                          myTolerance; // tolerance for sewing nodes
     SMESH_SequenceOfNode            myNodes; // nodes for using in sewing
     int                             myFlags; // see ExtrusionFlags
     double                          myTolerance; // tolerance for sewing nodes
@@ -319,29 +324,33 @@ public:
                                        const bool                        makeMediumNodes);
 
   public:
                                        const bool                        makeMediumNodes);
 
   public:
-    ExtrusParam( const gp_Vec&  theStep,
-                 const int      theNbSteps,
-                 const int      theFlags = 0,
-                 const double   theTolerance = 1e-6);
+    ExtrusParam( const gp_Vec&                   theStep,
+                 const int                       theNbSteps,
+                 const std::list<double>&        theScales,
+                 const gp_XYZ*                   theBaseP,
+                 const int                       theFlags = 0,
+                 const double                    theTolerance = 1e-6);
     ExtrusParam( const gp_Dir&                   theDir,
                  Handle(TColStd_HSequenceOfReal) theSteps,
                  const int                       theFlags = 0,
                  const double                    theTolerance = 1e-6);
     ExtrusParam( const gp_Dir&                   theDir,
                  Handle(TColStd_HSequenceOfReal) theSteps,
                  const int                       theFlags = 0,
                  const double                    theTolerance = 1e-6);
-    ExtrusParam( const double theStep,
-                 const int    theNbSteps,
-                 const int    theFlags,
-                 const int    theDim); // for extrusion by normal
+    ExtrusParam( const double                    theStep,
+                 const int                       theNbSteps,
+                 const int                       theFlags,
+                 const int                       theDim); // for extrusion by normal
 
     SMESH_SequenceOfNode& ChangeNodes() { return myNodes; }
     int& Flags()                   { return myFlags; }
     bool ToMakeBoundary()    const { return myFlags & EXTRUSION_FLAG_BOUNDARY; }
     bool ToMakeGroups()      const { return myFlags & EXTRUSION_FLAG_GROUPS; }
     bool ToUseInpElemsOnly() const { return myFlags & EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY; }
 
     SMESH_SequenceOfNode& ChangeNodes() { return myNodes; }
     int& Flags()                   { return myFlags; }
     bool ToMakeBoundary()    const { return myFlags & EXTRUSION_FLAG_BOUNDARY; }
     bool ToMakeGroups()      const { return myFlags & EXTRUSION_FLAG_GROUPS; }
     bool ToUseInpElemsOnly() const { return myFlags & EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY; }
+    bool IsLinearVariation() const { return myFlags & EXTRUSION_FLAG_SCALE_LINEAR_VARIATION; }
     int  NbSteps()           const { return mySteps->Length(); }
 
     // stores elements to use for extrusion by normal, depending on
     int  NbSteps()           const { return mySteps->Length(); }
 
     // stores elements to use for extrusion by normal, depending on
-    // state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag
-    void SetElementsToUse( const TIDSortedElemSet& elems );
+    // state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag;
+    // define myBaseP for scaling
+    void SetElementsToUse( const TIDSortedElemSet& elems, const TIDSortedElemSet& nodes );
 
     // creates nodes and returns number of nodes added in \a newNodes
     int MakeNodes( SMESHDS_Mesh*                     mesh,
 
     // creates nodes and returns number of nodes added in \a newNodes
     int MakeNodes( SMESHDS_Mesh*                     mesh,
@@ -784,8 +793,8 @@ public:
                                    const bool                             theHasRefPoint,
                                    const gp_Pnt&                          theRefPoint,
                                    const bool                             theMakeGroups);
                                    const bool                             theHasRefPoint,
                                    const gp_Pnt&                          theRefPoint,
                                    const bool                             theMakeGroups);
-  void LinearAngleVariation(const int          NbSteps,
-                            std::list<double>& theAngles);
+  static void LinearAngleVariation(const int          NbSteps,
+                                   std::list<double>& theAngles);
 
   bool doubleNodes( SMESHDS_Mesh*           theMeshDS,
                     const TIDSortedElemSet& theElems,
 
   bool doubleNodes( SMESHDS_Mesh*           theMeshDS,
                     const TIDSortedElemSet& theElems,
index af09f482c79952659ca2dc63c5b50bea2aad1497..6f944e520fc656221fe7b7e7f6d469053df3e72b 100644 (file)
 #include "SMESHGUI_ExtrusionDlg.h"
 
 #include "SMESHGUI.h"
 #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_FilterDlg.h"
+#include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_MeshEditPreview.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_Actor.h>
-#include <SMESH_TypeFilter.hxx>
 #include <SMESH_LogicalFilter.hxx>
 #include <SMESH_LogicalFilter.hxx>
-
-#include <SMDS_Mesh.hxx>
+#include <SMESH_TypeFilter.hxx>
 
 // SALOME GUI includes
 
 // 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_Desktop.h>
 #include <SUIT_MessageBox.h>
-#include <SUIT_Session.h>
 #include <SUIT_OverrideCursor.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 <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
-
 #include <SalomeApp_IntSpinBox.h>
 
 // OCCT includes
 #include <SalomeApp_IntSpinBox.h>
 
 // OCCT includes
-#include <TColStd_MapOfInteger.hxx>
+#include <BRep_Tool.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <gp_XYZ.hxx>
 
 // Qt includes
 #include <QApplication>
 #include <QButtonGroup>
 #include <gp_XYZ.hxx>
 
 // Qt includes
 #include <QApplication>
 #include <QButtonGroup>
+#include <QCheckBox>
+#include <QGridLayout>
 #include <QGroupBox>
 #include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
 #include <QLabel>
 #include <QLineEdit>
 #include <QLabel>
 #include <QLineEdit>
+#include <QListWidget>
 #include <QPushButton>
 #include <QRadioButton>
 #include <QPushButton>
 #include <QRadioButton>
-#include <QCheckBox>
-#include <QHBoxLayout>
+#include <QToolButton>
 #include <QVBoxLayout>
 #include <QVBoxLayout>
-#include <QGridLayout>
-#include <QKeyEvent>
 
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Group)
 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 // 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
 
 #define SPACING 6
 #define MARGIN  11
@@ -595,7 +596,10 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   : SMESHGUI_PreviewDlg( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( 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 );
 
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
@@ -638,8 +642,8 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
 
   TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments);
 
 
   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 );
 
   SelectVectorButton->setCheckable( true );
   SelectorWdg->GetButtonGroup()->addButton( SelectVectorButton );
 
@@ -671,6 +675,66 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   //Preview check box
   myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
 
   //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);
+  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);
+  ScalesGrpLayout->setRowMinimumHeight(1, 10);
+  ScalesGrpLayout->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);
   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 +760,10 @@ 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(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, 9);
+  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);
 
   /***************************************************************/
   GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 10, 0);
 
   /***************************************************************/
@@ -740,6 +806,11 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   SpinBox_NbSteps->setRange(1, 999999);
   SpinBox_VDist->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
   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");
+
   ExtrMethod_RBut0->setChecked(true);
   UseInputElemsOnlyCheck->setChecked(true);
   MakeGroupsCheck->setChecked(true);
   ExtrMethod_RBut0->setChecked(true);
   UseInputElemsOnlyCheck->setChecked(true);
   MakeGroupsCheck->setChecked(true);
@@ -771,7 +842,13 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   connect(SpinBox_Dy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
   connect(SpinBox_Dz, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
 
   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(SelectVectorButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   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(mySMESHGUI,           SIGNAL(SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
   connect(mySelectionMgr,       SIGNAL(currentSelectionChanged()), SLOT(toDisplaySimulation()));
   connect(SelectorWdg,          SIGNAL(selectionChanged()), this, SLOT(toDisplaySimulation()));
@@ -791,6 +868,13 @@ 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(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(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()));
 
   //To Connect preview check box
   connectPreviewControl();
 
   //To Connect preview check box
   connectPreviewControl();
@@ -875,6 +959,31 @@ bool SMESHGUI_ExtrusionDlg::isValuesValid()
   return aModule > 1.0E-38;
 }
 
   return aModule > 1.0E-38;
 }
 
+//=======================================================================
+//function : getScaleParams
+//purpose  : return 3 scaling parameters
+//=======================================================================
+
+bool SMESHGUI_ExtrusionDlg::getScaleParams( SMESH::double_array*& scales,
+                                            SMESH::double_array*& basePoint )
+{
+  scales = new SMESH::double_array;
+  scales->length( myScalesList.count() );
+  for ( int i = 0; i < myScalesList.count(); ++i )
+    (*scales)[i] = myScalesList[i];
+
+  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();
+  }
+
+  return ( scales->length() > 0 && LinearScalesCheck->isChecked() );
+}
+
 //=================================================================================
 // function : ClickOnRadio()
 // purpose  : Radio button management
 //=================================================================================
 // function : ClickOnRadio()
 // purpose  : Radio button management
@@ -989,7 +1098,7 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
   {
     SMESH::DirStruct aVector;
     getExtrusionVector(aVector);
   {
     SMESH::DirStruct aVector;
     getExtrusionVector(aVector);
-    
+
     QStringList aParameters;
     if ( ExtrMethod_RBut0->isChecked() )
     {
     QStringList aParameters;
     if ( ExtrMethod_RBut0->isChecked() )
     {
@@ -1011,14 +1120,22 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
     }
 
     long aNbSteps = (long)SpinBox_NbSteps->value();
     }
 
     long aNbSteps = (long)SpinBox_NbSteps->value();
-
     aParameters << SpinBox_NbSteps->text();
 
     aParameters << SpinBox_NbSteps->text();
 
+    SMESH::double_array_var scales = new SMESH::double_array;
+    scales->length( myScalesList.count() );
+    for (int i = 0; i < myScalesList.count(); i++)
+    {
+      scales[i] = myScalesList[i];
+      aParameters << ScalesList->item(i)->text();
+    }
+
     bool meshHadNewTypeBefore = true;
     int  maxSelType = 0;
     const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
 
     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();
       SUIT_OverrideCursor aWaitCursor;
 
       SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh();
@@ -1054,8 +1171,12 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
       }
       else
       {
       }
       else
       {
+        SMESH::double_array_var scales, basePoint;
+        bool linVariation = getScaleParams( scales.out(), basePoint.out() );
         groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
         groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
-                                                    aVector, aNbSteps, makeGroups );
+                                                    aVector, aNbSteps,
+                                                    scales, linVariation, basePoint,
+                                                    makeGroups );
       }
 
     } catch (...) {
       }
 
     } catch (...) {
@@ -1180,13 +1301,13 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
   if (!GroupButtons->isEnabled())
     return;
 
   if (!GroupButtons->isEnabled())
     return;
 
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects(aList);
+  if ( aList.IsEmpty() || aList.Extent() > 1 )
+    return;
+
   if ( SelectVectorButton->isChecked() )
   {
   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);
     Handle(SALOME_InteractiveObject) IO = aList.First();
     TColStd_IndexedMapOfInteger aMapIndex;
     mySelector->GetIndex(IO,aMapIndex);
@@ -1207,6 +1328,56 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
     SpinBox_Vy->SetValue(aNormale.Y());
     SpinBox_Vz->SetValue(aNormale.Z());
   }
     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();
 
   onDisplaySimulation(true);
   CheckIsEnable();
@@ -1229,6 +1400,21 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->SetSelectionMode(FaceSelection);
   }
     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();
   
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
   SelectionIntoArgument();
@@ -1316,6 +1502,12 @@ bool SMESHGUI_ExtrusionDlg::isValid()
   }
   ok = SpinBox_NbSteps->isValid( msg, true ) && ok;
 
   }
   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() )
   if( !ok ) {
     QString str( tr( "SMESH_INCORRECT_INPUT" ) );
     if ( !msg.isEmpty() )
@@ -1369,8 +1561,12 @@ void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview )
         }
         else
         {
         }
         else
         {
+          SMESH::double_array_var scales, basePoint;
+          bool linVariation = getScaleParams( scales.out(), basePoint.out() );
           groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
           groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
-                                                      aVector, aNbSteps, makeGroups );
+                                                      aVector, aNbSteps,
+                                                      scales, linVariation, basePoint,
+                                                      makeGroups );
         }
         SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
         mySimulation->SetData(aMeshPreviewStruct._retn());
         }
         SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
         mySimulation->SetData(aMeshPreviewStruct._retn());
@@ -1411,3 +1607,38 @@ void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector)
     aVector.PS.z = aNormale.Z()*aVDist;
   }
 }
     aVector.PS.z = aNormale.Z()*aVDist;
   }
 }
+
+//=======================================================================
+// function : OnScaleAdded()
+// purpose  : Called when user adds Scale to the list
+//=======================================================================
+void SMESHGUI_ExtrusionDlg::OnScaleAdded()
+{
+  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());
+}
+
+//=======================================================================
+// function : OnScaleRemoved()
+// purpose  : Called when user removes Scale(s) from the list
+//=======================================================================
+void SMESHGUI_ExtrusionDlg::OnScaleRemoved()
+{
+  QList<QListWidgetItem*> aList = ScalesList->selectedItems();
+  QListWidgetItem* anItem;
+  int row = 0;
+  foreach(anItem, aList) {
+    row = ScalesList->row(anItem);
+    myScalesList.removeAt(row);
+    delete anItem;
+  }
+  ScalesList->setCurrentRow( row, QItemSelectionModel::Select );
+}
index ed94f5c84a76a31a33b13f5ba19f99e4991fa5c6..b86138e082765cf7a305c6c67e431650d5271003 100644 (file)
 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 class QButtonGroup;
 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 class QButtonGroup;
-class QRadioButton;
+class QCheckBox;
 class QGroupBox;
 class QLabel;
 class QLineEdit;
 class QGroupBox;
 class QLabel;
 class QLineEdit;
-class QCheckBox;
+class QListWidget;
 class QPushButton;
 class QPushButton;
+class QRadioButton;
+class QToolButton;
 
 class SMESHGUI;
 class SMESH_Actor;
 
 class SMESHGUI;
 class SMESH_Actor;
@@ -59,7 +61,7 @@ class SUIT_SelectionFilter;
 class SalomeApp_IntSpinBox;
 
 //=================================================================================
 class SalomeApp_IntSpinBox;
 
 //=================================================================================
-// class    : SMESHGUI_ExtrusionDlg
+// class    : SMESHGUI_3TypesSelector
 // purpose  : A widget used to select both nodes, edges and faces for
 //            Extrusion and Revolution operations
 //=================================================================================
 // purpose  : A widget used to select both nodes, edges and faces for
 //            Extrusion and Revolution operations
 //=================================================================================
@@ -143,12 +145,15 @@ private:
   void                             getExtrusionVector(SMESH::DirStruct& aVector);
   void                             extrusionByNormal(SMESH::SMESH_MeshEditor_ptr meshEditor,
                                                      const bool                  makeGroups=false);
   void                             getExtrusionVector(SMESH::DirStruct& aVector);
   void                             extrusionByNormal(SMESH::SMESH_MeshEditor_ptr meshEditor,
                                                      const bool                  makeGroups=false);
+  bool                             getScaleParams( SMESH::double_array*& scales,
+                                                   SMESH::double_array*& basePoint );
   
   bool                             isValid();
   bool                             isValuesValid();
   
   LightApp_SelectionMgr*           mySelectionMgr;        /* User shape selection */
   SVTK_Selector*                   mySelector;
   
   bool                             isValid();
   bool                             isValuesValid();
   
   LightApp_SelectionMgr*           mySelectionMgr;        /* User shape selection */
   SVTK_Selector*                   mySelector;
+  QList<double>                    myScalesList;
 
   // widgets
   SMESHGUI_3TypesSelector*         SelectorWdg;
 
   // widgets
   SMESHGUI_3TypesSelector*         SelectorWdg;
@@ -180,6 +185,18 @@ private:
   QCheckBox*                       UseInputElemsOnlyCheck;
   QCheckBox*                       MakeGroupsCheck;
 
   QCheckBox*                       UseInputElemsOnlyCheck;
   QCheckBox*                       MakeGroupsCheck;
 
+  QCheckBox*                       LinearScalesCheck;
+  QGroupBox*                       ScalesGrp;
+  QListWidget*                     ScalesList;
+  QToolButton*                     AddScaleButton;
+  QToolButton*                     RemoveScaleButton;
+  SMESHGUI_SpinBox*                ScaleSpin;
+  QGroupBox*                       BasePointGrp;
+  QPushButton*                     SelectBasePointButton;
+  SMESHGUI_SpinBox*                BasePoint_XSpin;
+  SMESHGUI_SpinBox*                BasePoint_YSpin;
+  SMESHGUI_SpinBox*                BasePoint_ZSpin;
+
   QGroupBox*                       GroupButtons;
   QPushButton*                     buttonOk;
   QPushButton*                     buttonCancel;
   QGroupBox*                       GroupButtons;
   QPushButton*                     buttonOk;
   QPushButton*                     buttonCancel;
@@ -205,6 +222,8 @@ private slots:
   void                            ActivateThisDialog();
   void                            onOpenView();
   void                            onCloseView();
   void                            ActivateThisDialog();
   void                            onOpenView();
   void                            onCloseView();
+  void                            OnScaleAdded();
+  void                            OnScaleRemoved();
 
 };
 
 
 };
 
index a235b9cc9dc8cac5118d807d583cb4f9e970029b..6f6d0c605d7132530af644033543b95e51fb529a 100644 (file)
@@ -5267,6 +5267,18 @@ Please select a group and try again</translation>
         <source>USE_INPUT_ELEMS_ONLY</source>
         <translation>Use only input elements</translation>
     </message>
         <source>USE_INPUT_ELEMS_ONLY</source>
         <translation>Use only input elements</translation>
     </message>
+    <message>
+        <source>SMESH_SCALES</source>
+        <translation>Scale Factors</translation>
+    </message>
+    <message>
+        <source>LINEAR_SCALES</source>
+        <translation>Linear Variation of Scale Factors</translation>
+    </message>
+    <message>
+        <source>BASE_POINT</source>
+        <translation>Scaling Center</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_FilterDlg</name>
 </context>
 <context>
     <name>SMESHGUI_FilterDlg</name>
index cecee4596fdb7606e3157d3d4213634293cb5757..f9fb06334cc561f588da2a1262c7a2f9ca49bfab 100644 (file)
@@ -2484,6 +2484,7 @@ namespace MeshEditor_I
     bool myIsExtrusionByNormal;
 
     static int makeFlags( CORBA::Boolean MakeGroups,
     bool myIsExtrusionByNormal;
 
     static int makeFlags( CORBA::Boolean MakeGroups,
+                          CORBA::Boolean LinearVariation = false,
                           CORBA::Boolean ByAverageNormal = false,
                           CORBA::Boolean UseInputElemsOnly = false,
                           CORBA::Long    Flags = 0,
                           CORBA::Boolean ByAverageNormal = false,
                           CORBA::Boolean UseInputElemsOnly = false,
                           CORBA::Long    Flags = 0,
@@ -2492,18 +2493,24 @@ namespace MeshEditor_I
       if ( MakeGroups       ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
       if ( ByAverageNormal  ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
       if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
       if ( MakeGroups       ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
       if ( ByAverageNormal  ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
       if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
+      if ( LinearVariation  ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_SCALE_LINEAR_VARIATION;
       if ( MakeBoundary     ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
       return Flags;
     }
     // standard params
       if ( MakeBoundary     ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
       return Flags;
     }
     // standard params
-    ExtrusionParams(const SMESH::DirStruct &  theDir,
-                    CORBA::Long               theNbOfSteps,
-                    CORBA::Boolean            theMakeGroups):
+    ExtrusionParams(const SMESH::DirStruct &    theDir,
+                    CORBA::Long                 theNbOfSteps,
+                    const SMESH::double_array & theScaleFactors,
+                    CORBA::Boolean              theLinearVariation,
+                    const SMESH::double_array & theBasePoint,
+                    CORBA::Boolean              theMakeGroups):
       ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
                                                 theDir.PS.y,
                                                 theDir.PS.z ),
                                         theNbOfSteps,
       ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
                                                 theDir.PS.y,
                                                 theDir.PS.z ),
                                         theNbOfSteps,
-                                        makeFlags( theMakeGroups )),
+                                        toList( theScaleFactors ),
+                                        TBasePoint( theBasePoint ),
+                                        makeFlags( theMakeGroups, theLinearVariation )),
       myIsExtrusionByNormal( false )
     {
     }
       myIsExtrusionByNormal( false )
     {
     }
@@ -2517,7 +2524,9 @@ namespace MeshEditor_I
                                                 theDir.PS.y,
                                                 theDir.PS.z ),
                                         theNbOfSteps,
                                                 theDir.PS.y,
                                                 theDir.PS.z ),
                                         theNbOfSteps,
-                                        makeFlags( theMakeGroups, false, false,
+                                        std::list<double>(),
+                                        0,
+                                        makeFlags( theMakeGroups, false, false, false,
                                                    theExtrFlags, false ),
                                         theSewTolerance ),
       myIsExtrusionByNormal( false )
                                                    theExtrFlags, false ),
                                         theSewTolerance ),
       myIsExtrusionByNormal( false )
@@ -2532,7 +2541,7 @@ namespace MeshEditor_I
                     CORBA::Boolean theMakeGroups ):
       ::SMESH_MeshEditor::ExtrusParam ( theStepSize, 
                                         theNbOfSteps,
                     CORBA::Boolean theMakeGroups ):
       ::SMESH_MeshEditor::ExtrusParam ( theStepSize, 
                                         theNbOfSteps,
-                                        makeFlags( theMakeGroups,
+                                        makeFlags( theMakeGroups, false,
                                                    theByAverageNormal, theUseInputElemsOnly ),
                                         theDim),
       myIsExtrusionByNormal( true )
                                                    theByAverageNormal, theUseInputElemsOnly ),
                                         theDim),
       myIsExtrusionByNormal( true )
@@ -2543,6 +2552,32 @@ namespace MeshEditor_I
     {
       Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
     }
     {
       Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
     }
+
+  private:
+
+    static std::list<double> toList( const SMESH::double_array & theScaleFactors )
+    {
+      std::list<double> scales;
+      for ( CORBA::ULong i = 0; i < theScaleFactors.length(); ++i )
+        scales.push_back( theScaleFactors[i] );
+      return scales;
+    }
+
+    // structure used to convert SMESH::double_array to gp_XYZ*
+    struct TBasePoint
+    {
+      gp_XYZ *pp, p;
+      TBasePoint( const SMESH::double_array & theBasePoint )
+      {
+        pp = 0;
+        if ( theBasePoint.length() == 3 )
+        {
+          p.SetCoord( theBasePoint[0], theBasePoint[1], theBasePoint[2] );
+          pp = &p;
+        }
+      }
+      operator const gp_XYZ*() const { return pp; }
+    };
   };
 }
 
   };
 }
 
@@ -2566,13 +2601,17 @@ SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNode
                                           const SMESH::ListOfIDSources & theFaces,
                                           const SMESH::DirStruct &       theStepVector,
                                           CORBA::Long                    theNbOfSteps,
                                           const SMESH::ListOfIDSources & theFaces,
                                           const SMESH::DirStruct &       theStepVector,
                                           CORBA::Long                    theNbOfSteps,
+                                          const SMESH::double_array &    theScaleFactors,
+                                          CORBA::Boolean                 theLinearVariation,
+                                          const SMESH::double_array &    theBasePoint,
                                           CORBA::Boolean                 theToMakeGroups)
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
   initData();
 
                                           CORBA::Boolean                 theToMakeGroups)
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
   initData();
 
-  ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
+  ExtrusionParams params( theStepVector, theNbOfSteps, theScaleFactors,
+                          theLinearVariation, theBasePoint, theToMakeGroups );
 
   TIDSortedElemSet elemsNodes[2];
   for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
 
   TIDSortedElemSet elemsNodes[2];
   for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
@@ -2916,13 +2955,13 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & the
                 << thePathShape        << ", "
                 << theNodeStart        << ", "
                 << theHasAngles        << ", "
                 << thePathShape        << ", "
                 << theNodeStart        << ", "
                 << theHasAngles        << ", "
-                << theAngles           << ", "
+                << TVar( theAngles )   << ", "
                 << theLinearVariation  << ", "
                 << theHasRefPoint      << ", "
                 << "SMESH.PointStruct( "
                 << theLinearVariation  << ", "
                 << theHasRefPoint      << ", "
                 << "SMESH.PointStruct( "
-                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
+                << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
+                << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
+                << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
                 << theMakeGroups       << " )";
   }
   else
                 << theMakeGroups       << " )";
   }
   else
index c3b0a42865dd01bd0be3cb9f6fb70b31978e5d2f..ab953091e279df55263738538b9012936d602461 100644 (file)
@@ -330,6 +330,9 @@ public:
                                              const SMESH::ListOfIDSources & faces,
                                              const SMESH::DirStruct &       stepVector,
                                              CORBA::Long                    nbOfSteps,
                                              const SMESH::ListOfIDSources & faces,
                                              const SMESH::DirStruct &       stepVector,
                                              CORBA::Long                    nbOfSteps,
+                                             const SMESH::double_array &    theScaleFactors,
+                                             CORBA::Boolean                 theLinearVariation,
+                                             const SMESH::double_array &    theBasePoint,
                                              CORBA::Boolean                 toMakeGroups)
     throw (SALOME::SALOME_Exception);
 
                                              CORBA::Boolean                 toMakeGroups)
     throw (SALOME::SALOME_Exception);
 
index f56f9551c823039637838cf3e40964f484dda164..b4da6ea8e8495ff4ba537f1d8a372ec09e680303 100644 (file)
@@ -3820,17 +3820,27 @@ class Mesh:
                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
 
     ## Generates new elements by extrusion of the given elements and nodes
                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
 
     ## Generates new elements by extrusion of the given elements and nodes
-    #  @param nodes nodes to extrude: a list including ids, groups, sub-meshes or a mesh
-    #  @param edges edges to extrude: a list including ids, groups, sub-meshes or a mesh
-    #  @param faces faces to extrude: a list including ids, groups, sub-meshes or a mesh
+    #  @param nodes nodes to extrude: a list including ids, groups, sub-meshes or a mesh
+    #  @param edges edges to extrude: a list including ids, groups, sub-meshes or a mesh
+    #  @param faces faces to extrude: a list including ids, groups, sub-meshes or a mesh
     #  @param StepVector vector or DirStruct or 3 vector components, defining
     #         the direction and value of extrusion for one step (the total extrusion
     #         length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @param StepVector vector or DirStruct or 3 vector components, defining
     #         the direction and value of extrusion for one step (the total extrusion
     #         length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
+    #  @param scaleFactors optional scale factors to apply during extrusion
+    #  @param linearVariation if @c True, scaleFactors are spread over all @a scaleFactors,
+    #         else scaleFactors[i] is applied to nodes at the i-th extrusion step
+    #  @param basePoint optional scaling center; if not provided, a gravity center of
+    #         nodes and elements being extruded is used as the scaling center.
+    #         It can be either
+    #         - a list of tree components of the point or
+    #         - a node ID or
+    #         - a GEOM point
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
-    def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False):
+    def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
+                              scaleFactors=[], linearVariation=False, basePoint=[] ):
         unRegister = genObjUnRegister()
         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
         unRegister = genObjUnRegister()
         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
@@ -3841,12 +3851,22 @@ class Mesh:
         if isinstance( StepVector, list ):
             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
 
         if isinstance( StepVector, list ):
             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
 
+        if isinstance( basePoint, int):
+            xyz = self.GetNodeXYZ( basePoint )
+            if not xyz:
+                raise RuntimeError, "Invalid node ID: %s" % basePoint
+            basePoint = xyz
+        if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
+            basePoint = self.geompyD.PointCoordinates( basePoint )
+
         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
         Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
 
         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
         Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
 
         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
-                                                  StepVector, NbOfSteps, MakeGroups)
+                                                  StepVector, NbOfSteps,
+                                                  scaleFactors, linearVariation, basePoint,
+                                                  MakeGroups)
 
 
     ## Generates new elements by extrusion of the elements with given ids
 
 
     ## Generates new elements by extrusion of the elements with given ids
index 4f2329d5932db1ad5f770be021cdb6c6a5a6898f..9de37716ab05d67e9576ea955c663e139c6be4e9 100644 (file)
@@ -732,13 +732,13 @@ protected:
 
 void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMesh)
 {
 
 void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMesh)
 {
-  // if ( !faceSubMesh->IsEmpty() )
-  // {
-  //   for ( TopExp_Explorer e( faceSubMesh->GetSubShape(), TopAbs_EDGE ); e.More(); e.Next() )
-  //   {
-  //     markEdgeAsComputedByMe( TopoDS::Edge( e.Current() ), faceSubMesh );
-  //   }
-  // }
+  if ( !faceSubMesh->IsEmpty() )
+  {
+    for ( TopExp_Explorer e( faceSubMesh->GetSubShape(), TopAbs_EDGE ); e.More(); e.Next() )
+    {
+      markEdgeAsComputedByMe( TopoDS::Edge( e.Current() ), faceSubMesh );
+    }
+  }
 }
 
 //=======================================================================
 }
 
 //=======================================================================
@@ -762,12 +762,12 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
                  "of edges is less or equal to 3 and one of them is an ellipse curve)");
 
   // get not yet computed EDGEs
                  "of edges is less or equal to 3 and one of them is an ellipse curve)");
 
   // get not yet computed EDGEs
-  // list< TopoDS_Edge > emptyEdges;
-  // for ( TopExp_Explorer e( aShape, TopAbs_EDGE ); e.More(); e.Next() )
-  // {
-  //   if ( aMesh.GetSubMesh( e.Current() )->IsEmpty() )
-  //     emptyEdges.push_back( TopoDS::Edge( e.Current() ));
-  // }
+  list< TopoDS_Edge > emptyEdges;
+  for ( TopExp_Explorer e( aShape, TopAbs_EDGE ); e.More(); e.Next() )
+  {
+    if ( aMesh.GetSubMesh( e.Current() )->IsEmpty() )
+      emptyEdges.push_back( TopoDS::Edge( e.Current() ));
+  }
 
   TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh);
 
 
   TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh);
 
@@ -941,9 +941,9 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
     centerUV   = nodes2.back().UV();
   }
 
     centerUV   = nodes2.back().UV();
   }
 
-  // list< TopoDS_Edge >::iterator ee = emptyEdges.begin();
-  // for ( ; ee != emptyEdges.end(); ++ee )
-  //   markEdgeAsComputedByMe( *ee, aMesh.GetSubMesh( F ));
+  list< TopoDS_Edge >::iterator ee = emptyEdges.begin();
+  for ( ; ee != emptyEdges.end(); ++ee )
+    markEdgeAsComputedByMe( *ee, aMesh.GetSubMesh( F ));
 
   circSide->GetUVPtStruct(); // let sides take into account just computed nodes
   linSide1->GetUVPtStruct();
 
   circSide->GetUVPtStruct(); // let sides take into account just computed nodes
   linSide1->GetUVPtStruct();