Salome HOME
Merge from V6_4_BR 05/12/2011
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.cxx
index f08fa9c879a856611c0c70be4086efa6eb87b2e1..2d5ee24f1031f8ead9562b5fccb35c59a7fdc5b8 100644 (file)
@@ -1,23 +1,23 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2011  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
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
@@ -30,7 +30,9 @@
 #include "utilities.h"
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_NoteBook.hxx"
-#include "Resource_DataMapOfAsciiStringAsciiString.hxx"
+#include "SMESH_Filter_i.hxx"
+
+#include <Resource_DataMapOfAsciiStringAsciiString.hxx>
 
 #include "SMESH_Gen_i.hxx"
 /* SALOME headers that include CORBA headers that include windows.h 
@@ -46,6 +48,8 @@ IMPLEMENT_STANDARD_HANDLE (_pySubMesh         ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pyMeshEditor      ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pyHypothesis      ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pySelfEraser      ,_pyObject);
+IMPLEMENT_STANDARD_HANDLE (_pyGroup           ,_pyObject);
+IMPLEMENT_STANDARD_HANDLE (_pyFilter          ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pyAlgorithm       ,_pyHypothesis);
 IMPLEMENT_STANDARD_HANDLE (_pyComplexParamHypo,_pyHypothesis);
 IMPLEMENT_STANDARD_HANDLE (_pyNumberOfSegmentsHyp,_pyHypothesis);
@@ -58,6 +62,8 @@ IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh         ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor      ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis      ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser      ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyGroup           ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyFilter          ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm       ,_pyHypothesis);
 IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
 IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
@@ -198,10 +204,11 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
 _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
                Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
   : _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )),
+    myNbCommands( 0 ),
     myID2AccessorMethod( theEntry2AccessorMethod ),
-    myObjectNames( theObjectNames )
+    myObjectNames( theObjectNames ),
+    myNbFilters( 0 )
 {
-  myNbCommands = 0;
   // make that GetID() to return TPythonDump::SMESHGenName()
   GetCreationCmd()->GetString() += "=";
 }
@@ -239,6 +246,8 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   if ( objID.IsEmpty() )
     return aCommand;
 
+  // Find an object to process theCommand
+
   // SMESH_Gen method?
   if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName()) {
     this->Process( aCommand );
@@ -298,19 +307,26 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       return aCommand;
     }
 
+  // aFilterManager.CreateFilter() ?
+  if ( aCommand->GetMethod() == "CreateFilter" )
+  {
+    // Set a more human readable name to a filter
+    // aFilter0x7fbf6c71cfb0 -> aFilter_nb
+    _pyID newID, filterID = aCommand->GetResultValue();
+    int pos = filterID.Search( "0x" );
+    if ( pos > 1 )
+      newID = (filterID.SubString(1,pos-1) + "_") + _pyID( ++myNbFilters );
+
+    Handle(_pyObject) filter( new _pyFilter( aCommand, newID ));
+    AddObject( filter );
+  }
+
   // other object method?
   map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.find( objID );
   if ( id_obj != myObjects.end() ) {
     id_obj->second->Process( aCommand );
     return aCommand;
   }
-//   if ( theCommand.Search( "aFilterManager" ) != -1 ) {
-//     if ( theCommand.Search( "CreateFilterManager" ) != -1 )
-//       myFilterManager = new _pySelfEraser( aCommand );
-//     else if ( !myFilterManager.IsNull() )
-//       myFilterManager->Process( aCommand );
-//     return aCommand;
-//   }
 
   // Add access to a wrapped mesh
   AddMeshAccessorMethod( aCommand );
@@ -321,7 +337,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   // PAL12227. PythonDump was not updated at proper time; result is
   //     aCriteria.append(SMESH.Filter.Criterion(17,26,0,'L1',26,25,1e-07,SMESH.EDGE,-1))
   // TypeError: __init__() takes exactly 11 arguments (10 given)
-  char wrongCommand[] = "SMESH.Filter.Criterion(";
+  const char wrongCommand[] = "SMESH.Filter.Criterion(";
   if ( int beg = theCommand.Location( wrongCommand, 1, theCommand.Length() ))
   {
     _pyCommand tmpCmd( theCommand.SubString( beg, theCommand.Length() ), -1);
@@ -335,13 +351,82 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       aCommand->GetString().Trunc( beg - 1 );
       aCommand->GetString() += tmpCmd.GetString();
     }
+    // IMP issue 0021014
+    // set GetCriterion(elementType,CritType,Compare,Treshold,UnaryOp,BinaryOp,Tolerance)
+    //                  1           2        3       4        5       6        7
+    // instead of "SMESH.Filter.Criterion(
+    // Type,Compare,Threshold,ThresholdStr,ThresholdID,UnaryOp,BinaryOp,Tolerance,TypeOfElement,Precision)
+    // 1    2       3         4            5           6       7        8         9             10
+    // in order to avoid the problem of type mismatch of long and FunctorType
+    const TCollection_AsciiString
+      SMESH("SMESH."), dfltFunctor = "SMESH.FT_Undefined", dftlTol = "1e-07", dftlPreci = "-1";
+    TCollection_AsciiString
+      Type          = aCommand->GetArg(1),  // long
+      Compare       = aCommand->GetArg(2),  // long
+      Threshold     = aCommand->GetArg(3),  // double
+      ThresholdStr  = aCommand->GetArg(4),  // string
+      ThresholdID   = aCommand->GetArg(5),  // string
+      UnaryOp       = aCommand->GetArg(6),  // long
+      BinaryOp      = aCommand->GetArg(7),  // long
+      Tolerance     = aCommand->GetArg(8),  // double
+      TypeOfElement = aCommand->GetArg(9),  // ElementType
+      Precision     = aCommand->GetArg(10); // long
+    Type     = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Type.IntegerValue() ));
+    Compare  = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Compare.IntegerValue() ));
+    UnaryOp  = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( UnaryOp.IntegerValue() ));
+    BinaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( BinaryOp.IntegerValue() ));
+
+    aCommand->RemoveArgs();
+    aCommand->SetObject( SMESH_2smeshpy::GenName() );
+    aCommand->SetMethod( "GetCriterion" );
+
+    aCommand->SetArg( 1, TypeOfElement );
+    aCommand->SetArg( 2, Type );
+    aCommand->SetArg( 3, Compare );
+
+    if ( Type == "SMESH.FT_ElemGeomType" && Threshold.IsIntegerValue() )
+    {
+      // set SMESH.GeometryType instead of a numerical Threshold
+      const char* types[SMESH::Geom_POLYHEDRA+1] = {
+        "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
+        "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_POLYHEDRA"
+      };
+      int iGeom = Threshold.IntegerValue();
+      if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 )
+        Threshold = SMESH + types[ iGeom ];
+    }
+    if ( ThresholdStr.Length() != 2 ) // not '' or ""
+      aCommand->SetArg( 4, ThresholdStr );
+    else if ( ThresholdID.Length() != 2 )
+      aCommand->SetArg( 4, ThresholdID );
+    else
+      aCommand->SetArg( 4, Threshold );
+    // find the last not default arg
+    int lastDefault = 8;
+    if ( Tolerance == dftlTol ) {
+      lastDefault = 7;
+      if ( BinaryOp == dfltFunctor ) {
+        lastDefault = 6;
+        if ( UnaryOp == dfltFunctor )
+          lastDefault = 5;
+      }
+    }
+    if ( 5 < lastDefault ) aCommand->SetArg( 5, UnaryOp );
+    if ( 6 < lastDefault ) aCommand->SetArg( 6, BinaryOp );
+    if ( 7 < lastDefault ) aCommand->SetArg( 7, Tolerance );
+    if ( Precision != dftlPreci )
+    {
+      TCollection_AsciiString crit = aCommand->GetResultValue();
+      aCommand->GetString() += "; ";
+      aCommand->GetString() += crit + ".Precision = " + Precision;
+    }
   }
   return aCommand;
 }
 
 //================================================================================
 /*!
- * \brief Convert the command or remember it for later conversion 
+ * \brief Convert the command or remember it for later conversion
   * \param theCommand - The python command calling a method of SMESH_Gen
  */
 //================================================================================
@@ -363,18 +448,21 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     return;
   }
-  if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL" || method == "CopyMesh" )
+  if ( method == "CreateMeshesFromUNV" ||
+       method == "CreateMeshesFromSTL" ||
+       method == "CreateMeshesFromCGNS" ||
+       method == "CopyMesh" )
   {
     Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     return;
   }
-  if( method == "CreateMeshesFromMED")
+  if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV")
   {
     for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
     {
       Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind));
-      myMeshes.insert( make_pair( theCommand->GetResultValue(ind), mesh ));     
+      myMeshes.insert( make_pair( theCommand->GetResultValue(ind), mesh ));
     }
   }
 
@@ -423,7 +511,9 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
 
   // objects erasing creation command if no more it's commands invoked:
   // SMESH_Pattern, FilterManager
-  if ( method == "GetPattern" || method == "CreateFilterManager" ) {
+  if ( method == "GetPattern" ||
+       method == "CreateFilterManager" ||
+       method == "CreateMeasurements" ) {
     Handle(_pyObject) obj = new _pySelfEraser( theCommand );
     if ( !myObjects.insert( make_pair( obj->GetID(), obj )).second )
       theCommand->Clear(); // already created
@@ -705,13 +795,36 @@ _pyID _pyGen::GenerateNewID( const _pyID& theID )
     aNewID = theID + _pyID( ":" ) + _pyID( index++ );
   }
   while ( myObjectNames.IsBound( aNewID ) );
-    
-  myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID ) 
+
+  myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID )
                       ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
                       : _pyID( "A" ) + aNewID );
   return aNewID;
 }
 
+//================================================================================
+/*!
+ * \brief Stores theObj in myObjects
+ */
+//================================================================================
+
+void _pyGen::AddObject( Handle(_pyObject)& theObj )
+{
+  myObjects.insert( make_pair( theObj->GetID(), theObj ));
+}
+
+//================================================================================
+/*!
+ * \brief Finds a _pyObject by ID
+ */
+//================================================================================
+
+Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID )  const
+{
+  std::map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.find( theObjID );
+  return ( id_obj == myObjects.end() ) ? Handle(_pyObject)() : id_obj->second;
+}
+  
 //================================================================================
 /*!
  * \brief Find out type of geom group
@@ -720,63 +833,63 @@ _pyID _pyGen::GenerateNewID( const _pyID& theID )
  */
 //================================================================================
 
-static bool sameGroupType( const _pyID&                   grpID,
-                           const TCollection_AsciiString& theType)
-{
-  // define group type as smesh.Mesh.Group() does
-  int type = -1;
-  SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
-  SALOMEDS::SObject_var aSObj = study->FindObjectID( grpID.ToCString() );
-  if ( !aSObj->_is_nil() ) {
-    GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aSObj->GetObject() );
-    if ( !aGeomObj->_is_nil() ) {
-      switch ( aGeomObj->GetShapeType() ) {
-      case GEOM::VERTEX: type = SMESH::NODE; break;
-      case GEOM::EDGE:   type = SMESH::EDGE; break;
-      case GEOM::FACE:   type = SMESH::FACE; break;
-      case GEOM::SOLID:
-      case GEOM::SHELL:  type = SMESH::VOLUME; break;
-      case GEOM::COMPOUND: {
-        GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine();
-        if ( !aGeomGen->_is_nil() ) {
-          GEOM::GEOM_IGroupOperations_var aGrpOp =
-            aGeomGen->GetIGroupOperations( study->StudyId() );
-          if ( !aGrpOp->_is_nil() ) {
-            switch ( aGrpOp->GetType( aGeomObj )) {
-            case TopAbs_VERTEX: type = SMESH::NODE; break;
-            case TopAbs_EDGE:   type = SMESH::EDGE; break;
-            case TopAbs_FACE:   type = SMESH::FACE; break;
-            case TopAbs_SOLID:  type = SMESH::VOLUME; break;
-            default:;
-            }
-          }
-        }
-      }
-      default:;
-      }
-    }
-  }
-  if ( type < 0 ) {
-    MESSAGE("Type of the group " << grpID << " not found");
-    return false;
-  }
-  if ( theType.IsIntegerValue() )
-    return type == theType.IntegerValue();
-
-  switch ( type ) {
-  case SMESH::NODE:   return theType.Location( "NODE", 1, theType.Length() );
-  case SMESH::EDGE:   return theType.Location( "EDGE", 1, theType.Length() );
-  case SMESH::FACE:   return theType.Location( "FACE", 1, theType.Length() );
-  case SMESH::VOLUME: return theType.Location( "VOLUME", 1, theType.Length() );
-  default:;
-  }
-  return false;
-}
+// static bool sameGroupType( const _pyID&                   grpID,
+//                            const TCollection_AsciiString& theType)
+// {
+//   // define group type as smesh.Mesh.Group() does
+//   int type = -1;
+//   SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+//   SALOMEDS::SObject_var aSObj = study->FindObjectID( grpID.ToCString() );
+//   if ( !aSObj->_is_nil() ) {
+//     GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aSObj->GetObject() );
+//     if ( !aGeomObj->_is_nil() ) {
+//       switch ( aGeomObj->GetShapeType() ) {
+//       case GEOM::VERTEX: type = SMESH::NODE; break;
+//       case GEOM::EDGE:   type = SMESH::EDGE; break;
+//       case GEOM::FACE:   type = SMESH::FACE; break;
+//       case GEOM::SOLID:
+//       case GEOM::SHELL:  type = SMESH::VOLUME; break;
+//       case GEOM::COMPOUND: {
+//         GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine();
+//         if ( !aGeomGen->_is_nil() ) {
+//           GEOM::GEOM_IGroupOperations_var aGrpOp =
+//             aGeomGen->GetIGroupOperations( study->StudyId() );
+//           if ( !aGrpOp->_is_nil() ) {
+//             switch ( aGrpOp->GetType( aGeomObj )) {
+//             case TopAbs_VERTEX: type = SMESH::NODE; break;
+//             case TopAbs_EDGE:   type = SMESH::EDGE; break;
+//             case TopAbs_FACE:   type = SMESH::FACE; break;
+//             case TopAbs_SOLID:  type = SMESH::VOLUME; break;
+//             default:;
+//             }
+//           }
+//         }
+//       }
+//       default:;
+//       }
+//     }
+//   }
+//   if ( type < 0 ) {
+//     MESSAGE("Type of the group " << grpID << " not found");
+//     return false;
+//   }
+//   if ( theType.IsIntegerValue() )
+//     return type == theType.IntegerValue();
+
+//   switch ( type ) {
+//   case SMESH::NODE:   return theType.Location( "NODE", 1, theType.Length() );
+//   case SMESH::EDGE:   return theType.Location( "EDGE", 1, theType.Length() );
+//   case SMESH::FACE:   return theType.Location( "FACE", 1, theType.Length() );
+//   case SMESH::VOLUME: return theType.Location( "VOLUME", 1, theType.Length() );
+//   default:;
+//   }
+//   return false;
+// }
 
 //================================================================================
 /*!
- * \brief 
-  * \param theCreationCmd - 
+ * \brief
+  * \param theCreationCmd -
  */
 //================================================================================
 
@@ -789,7 +902,7 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd)
 //   if(str != "CreateMeshesFromUNV" &&
 //      str != "CreateMeshesFromMED" &&
 //      str != "CreateMeshesFromSTL")
-  creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); 
+  creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
   creationCmd->SetMethod( "Mesh" );
 
   theGen->SetAccessorMethod( GetID(), "GetMesh()" );
@@ -797,8 +910,8 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd)
 
 //================================================================================
 /*!
- * \brief 
-  * \param theCreationCmd - 
+ * \brief
+  * \param theCreationCmd -
  */
 //================================================================================
 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString& id):
@@ -806,13 +919,13 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_Asci
 {
   // convert my creation command
   Handle(_pyCommand) creationCmd = GetCreationCmd();
-  creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); 
+  creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
   theGen->SetAccessorMethod( id, "GetMesh()" );
 }
 
 //================================================================================
 /*!
- * \brief Convert a IDL API command of SMESH::Mesh to a method call of python Mesh
+ * \brief Convert an IDL API command of SMESH::SMESH_Mesh to a method call of python Mesh
   * \param theCommand - Engine method called for this mesh
  */
 //================================================================================
@@ -834,7 +947,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
 
   const TCollection_AsciiString method = theCommand->GetMethod();
   // ----------------------------------------------------------------------
-  if ( method == "GetSubMesh" ) {
+  if ( method == "GetSubMesh" ) { // collect submeshes of the mesh
     Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
     if ( !subMesh.IsNull() ) {
       subMesh->SetCreator( this );
@@ -864,6 +977,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     //  theCommand->SetArg( 1, grp );
     //}
     //else {
+    // ------------------------->>>>> GroupOnGeom( grp, name, typ )
       _pyID type = theCommand->GetArg( 1 );
       _pyID name = theCommand->GetArg( 2 );
       theCommand->SetMethod( "GroupOnGeom" );
@@ -874,13 +988,62 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     //}
   }
   // ----------------------------------------------------------------------
-  else if ( method == "ExportToMED" ||   // ExportToMED() --> ExportMED()
+  else if ( method == "CreateGroupFromFilter" ) // --> GroupOnFilter()
+  {
+    theCommand->SetMethod( "GroupOnFilter" );
+    Handle(_pyGroup) group = new _pyGroup( theCommand );
+    theGen->AddObject( group );
+
+    // GroupOnFilter(typ, name, aFilter0x4743dc0 -> aFilter_1)
+    _pyID filterID = theCommand->GetArg(3);
+    Handle(_pyObject) filter = theGen->FindObject( filterID );
+    if ( !filter.IsNull() && filter->IsKind(STANDARD_TYPE(_pyFilter)))
+      filter->Process( theCommand );
+  }
+  // ----------------------------------------------------------------------
+  else if ( method == "GetIdsFromFilter" )
+  {
+    // GetIdsFromFilter( aFilter0x4743dc0) -> GetIdsFromFilter( aFilter_1)
+    _pyID filterID = theCommand->GetArg(1);
+    Handle(_pyObject) filter = theGen->FindObject( filterID );
+    if ( !filter.IsNull() && filter->IsKind(STANDARD_TYPE(_pyFilter)))
+      filter->Process( theCommand );
+  }
+  // ----------------------------------------------------------------------
+  else if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup()
+  {
+    theCommand->SetMethod( "CreateEmptyGroup" );
+    Handle(_pyGroup) group = new _pyGroup( theCommand );
+    theGen->AddObject( group );
+  }
+  // ----------------------------------------------------------------------
+  else if ( method == "ExportToMED" ||   // ExportToMED()  --> ExportMED()
             method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
     theCommand->SetMethod( "ExportMED" );
   }
   // ----------------------------------------------------------------------
-  else if ( method == "CreateGroup" ) { // CreateGroup() --> CreateEmptyGroup()
-    theCommand->SetMethod( "CreateEmptyGroup" );
+  else if ( method == "ExportCGNS" )
+  { // ExportCGNS(part, ...) -> ExportCGNS(..., part)
+    _pyID partID = theCommand->GetArg( 1 );
+    int nbArgs = theCommand->GetNbArgs();
+    for ( int i = 2; i <= nbArgs; ++i )
+      theCommand->SetArg( i-1, theCommand->GetArg( i ));
+    theCommand->SetArg( nbArgs, partID );
+  }
+  // ----------------------------------------------------------------------
+  else if ( method.Location( "ExportPartTo", 1, method.Length() ) == 1 )
+  { // ExportPartTo*(part, ...) -> Export*(..., part)
+    //
+    // remove "PartTo" from the method
+    TCollection_AsciiString newMethod = method;
+    newMethod.Remove( 7, 6 );
+    theCommand->SetMethod( newMethod );
+    // make the 1st arg be the last one
+    _pyID partID = theCommand->GetArg( 1 );
+    int nbArgs = theCommand->GetNbArgs();
+    for ( int i = 2; i <= nbArgs; ++i )
+      theCommand->SetArg( i-1, theCommand->GetArg( i ));
+    theCommand->SetArg( nbArgs, partID );
   }
   // ----------------------------------------------------------------------
   else if ( method == "RemoveHypothesis" ) // (geom, hyp)
@@ -917,16 +1080,11 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
   }
   // check for SubMesh order commands
   else if ( theCommand->GetMethod() == "GetMeshOrder" ||
-            theCommand->GetMethod() == "SetMeshOrder" ) {
-    // In fact arguments and result values does not support complex containers
-    // such as list of list
-    // So, here we parse it manually
-    // GetMeshOrder
-    //for(int ind = 0, n = theCommand->GetNbResultValues();ind<n;ind++) {
-    //  Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue(ind) );
-    // SetMeshOrder
-    //for(int ind = 0, n = theCommand->GetNbArgs();ind<n;ind++) {
-    //  Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetArg(ind) );
+            theCommand->GetMethod() == "SetMeshOrder" )
+  {
+    // make commands GetSubMesh() returning sub-meshes be before using sub-meshes
+    // by GetMeshOrder() and SetMeshOrder(), since by defalut GetSubMesh()
+    // commands are moved at the end of the script
     const bool isArg = theCommand->GetMethod() == "SetMeshOrder";
     const TCollection_AsciiString& cmdStr = theCommand->GetString();
     int begPos = (/*isArg ? cmdStr.Search( "(" ) :*/ cmdStr.Search( "[" )) + 1;
@@ -938,7 +1096,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
       while ( !anIDStr.IsEmpty() ) {
         Handle(_pySubMesh) subMesh = theGen->FindSubMesh( anIDStr );
         if ( !subMesh.IsNull() )
-          subMesh->Process( theCommand );
+          subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand
         anIDStr = aSubStr.Token("\t ,[]", index++);
       }
     }
@@ -960,12 +1118,12 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
 
 bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
 {
-  // names of SMESH_Mesh methods fully equal to methods of class Mesh, so
-  // no conversion is needed for them at all:
+  // names of SMESH_Mesh methods fully equal to methods of python class Mesh,
+  // so no conversion is needed for them at all:
   static TStringSet sameMethods;
   if ( sameMethods.empty() ) {
     const char * names[] =
-      { "ExportDAT","ExportUNV","ExportSTL", "RemoveGroup","RemoveGroupWithContents",
+      { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents",
         "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog",
         "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements",
         "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles",
@@ -1013,7 +1171,7 @@ void _pyMesh::Flush()
         TCollection_AsciiString( " = " ) + theGen->GetID() +
         TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
         TCollection_AsciiString( "\" )" );
-      
+
       Handle(_pyCommand) newCmd = theGen->AddCommand( aNewCmdStr );
       Handle(_pyAlgorithm) newAlgo = Handle(_pyAlgorithm)::DownCast(theGen->FindHyp( localAlgoID ));
       if ( !newAlgo.IsNull() ) {
@@ -1028,7 +1186,7 @@ void _pyMesh::Flush()
     }
     _pyID geom = addCmd->GetArg( 1 );
     bool isLocalAlgo = ( geom != GetGeom() );
-    
+
     // try to convert
     if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK
     {
@@ -1139,7 +1297,8 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
       "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
       "GetLastCreatedElems",
       "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
-      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh"
+      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh",
+      "MakeBoundaryElements"
       ,"" }; // <- mark of the end
     sameMethods.Insert( names );
   }
@@ -1160,7 +1319,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
   bool isPyMeshMethod = sameMethods.Contains( method );
   if ( !isPyMeshMethod )
   {
-    //Replace SMESH_MeshEditor "MakeGroups" functions on the Mesh 
+    //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh
     //functions with the flag "theMakeGroups = True" like:
     //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
     int pos = method.Search("MakeGroups");
@@ -1197,13 +1356,41 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
   // DoubleNodeGroupNew() -> DoubleNodeGroup()
   // DoubleNodeGroupsNew() -> DoubleNodeGroups()
   // DoubleNodeElemGroupsNew() -> DoubleNodeElemGroups()
-  if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew" || method == "DoubleNodeElemGroupsNew" ||
-                           method == "DoubleNodeGroupNew"     || method == "DoubleNodeGroupsNew"))
+  if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew"  ||
+                            method == "DoubleNodeElemGroupsNew" ||
+                            method == "DoubleNodeGroupNew"      ||
+                            method == "DoubleNodeGroupsNew"))
   {
     isPyMeshMethod=true;
     theCommand->SetMethod( method.SubString( 1, method.Length()-3));
     theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
   }
+  // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj)
+  // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj)
+  if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" ||
+                            method == "ConvertFromQuadraticObject" ))
+  {
+    isPyMeshMethod=true;
+    theCommand->SetMethod( method.SubString( 1, method.Length()-6));
+    // prevent moving creation of the converted sub-mesh to the end of the script
+    bool isFromQua = ( method.Value( 8 ) == 'F' );
+    Handle(_pySubMesh) sm = theGen->FindSubMesh( theCommand->GetArg( isFromQua ? 1 : 2 ));
+    if ( !sm.IsNull() )
+      sm->Process( theCommand );
+  }
+  // FindAmongElementsByPoint(meshPart, x, y, z, elementType) ->
+  // FindElementsByPoint(x, y, z, elementType, meshPart)
+  if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" )
+  {
+    isPyMeshMethod=true;
+    theCommand->SetMethod( "FindElementsByPoint" );
+    // make the 1st arg be the last one
+    _pyID partID = theCommand->GetArg( 1 );
+    int nbArgs = theCommand->GetNbArgs();
+    for ( int i = 2; i <= nbArgs; ++i )
+      theCommand->SetArg( i-1, theCommand->GetArg( i ));
+    theCommand->SetArg( nbArgs, partID );
+  }
 
   // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
   // so let _pyMesh care of it (TMP?)
@@ -1227,7 +1414,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
 //================================================================================
 /*!
  * \brief _pyHypothesis constructor
-  * \param theCreationCmd - 
+  * \param theCreationCmd -
  */
 //================================================================================
 
@@ -1363,7 +1550,7 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
   }
   else if ( hypType == "TrianglePreference" ) {
     hyp->SetConvMethodAndType( "TrianglePreference", "Quadrangle_2D");
-  }     
+  }
   // RadialQuadrangle_1D2D ----------
   else if ( hypType == "RadialQuadrangle_1D2D" ) {
     algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
@@ -1447,6 +1634,9 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
   else if ( hypType == "Projection_2D" ) {
     algo->SetConvMethodAndType( "Projection2D", hypType.ToCString());
   }
+  else if ( hypType == "Projection_1D2D" ) {
+    algo->SetConvMethodAndType( "Projection1D2D", hypType.ToCString());
+  }
   else if ( hypType == "ProjectionSource2D" ) {
     hyp->SetConvMethodAndType( "SourceFace", "Projection_2D");
     hyp->AddArgMethod( "SetSourceFace");
@@ -1479,6 +1669,16 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
     hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get3DHypothesis" );
     hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
   }
+  // Cartesian 3D ---------
+  else if ( hypType == "Cartesian_3D" ) {
+    algo->SetConvMethodAndType( "BodyFitted", hypType.ToCString());
+  }
+  else if ( hypType == "CartesianParameters3D" ) {
+    hyp = new _pyComplexParamHypo( theCreationCmd );
+    hyp->SetConvMethodAndType( "SetGrid", "Cartesian_3D");
+    for ( int iArg = 0; iArg < 4; ++iArg )
+      hyp->myArgs.Append("[]");
+  }
 
   return algo->IsValid() ? algo : hyp;
 }
@@ -1531,7 +1731,7 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
   // replace creation command by wrapped instance
   // please note, that hypothesis attaches to algo creation command (see upper)
   SetCreationCmd( theCmd );
-  
+
 
   // clear commands setting arg values
   list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
@@ -1649,12 +1849,44 @@ void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
 //================================================================================
 /*!
  * \brief Remember hypothesis parameter values
 * \param theCommand - The called hypothesis method
+ * \param theCommand - The called hypothesis method
  */
 //================================================================================
 
 void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand)
 {
+  if ( GetAlgoType() == "Cartesian_3D" )
+  {
+    // CartesianParameters3D hyp
+
+    if ( theCommand->GetMethod() == "SetSizeThreshold" )
+    {
+      myArgs( 4 ) = theCommand->GetArg( 1 );
+      myArgCommands.push_back( theCommand );
+      return;
+    }
+    if ( theCommand->GetMethod() == "SetGrid" ||
+         theCommand->GetMethod() == "SetGridSpacing" )
+    {
+      TCollection_AsciiString axis = theCommand->GetArg( theCommand->GetNbArgs() );
+      int iArg = 1 + ( axis.Value(1) - '0' );
+      if ( theCommand->GetMethod() == "SetGrid" )
+      {
+        myArgs( iArg ) = theCommand->GetArg( 1 );
+      }
+      else
+      {
+        myArgs( iArg ) = "[ ";
+        myArgs( iArg ) += theCommand->GetArg( 1 );
+        myArgs( iArg ) += ", ";
+        myArgs( iArg ) += theCommand->GetArg( 2 );
+        myArgs( iArg ) += "]";
+      }
+      myArgCommands.push_back( theCommand );
+      return;
+    }
+  }
+
   if( theCommand->GetMethod() == "SetLength" )
   {
     // NOW it becomes OBSOLETE
@@ -1721,7 +1953,7 @@ void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
 
 //================================================================================
 /*!
- * \brief 
+ * \brief
   * \param theAdditionCmd - command to be converted
   * \param theMesh - mesh instance
   * \retval bool - status
@@ -1767,7 +1999,7 @@ bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theA
 
 //================================================================================
 /*!
- * \brief 
+ * \brief
  */
 //================================================================================
 
@@ -1886,7 +2118,7 @@ void _pyNumberOfSegmentsHyp::Flush()
   * \retval bool - false if the command cant be converted
  */
 //================================================================================
-  
+
 bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
                                                          const _pyID&              theMeshID)
 {
@@ -1937,11 +2169,11 @@ _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd)
 /*!
  * \brief Convert the command adding an algorithm to mesh
   * \param theCmd - The command like mesh.AddHypothesis( geom, algo )
-  * \param theMesh - The mesh needing this algo 
+  * \param theMesh - The mesh needing this algo
   * \retval bool - false if the command cant be converted
  */
 //================================================================================
-  
+
 bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd,
                                       const _pyID&              theMeshID)
 {
@@ -2159,32 +2391,67 @@ const TCollection_AsciiString & _pyCommand::GetArg( int index )
 {
   if ( GetBegPos( ARG1_IND ) == UNKNOWN )
   {
-    // find all args
-    int begPos = GetBegPos( METHOD_IND ) + myMeth.Length();
-    if ( begPos < 1 )
-      begPos = myString.Location( "(", 1, Length() ) + 1;
-
-    int i = 0, prevLen = 0, nbNestings = 0;
-    while ( begPos != EMPTY ) {
-      begPos += prevLen;
-      if( myString.Value( begPos ) == '(' )
-        nbNestings++;
-      // check if we are looking at the closing parenthesis
-      while ( begPos <= Length() && isspace( myString.Value( begPos )))
-        ++begPos;
-      if ( begPos > Length() )
-        break;
-      if ( myString.Value( begPos ) == ')' ) {
-        nbNestings--;
-        if( nbNestings == 0 )
-          break;
+    // Find all args
+
+    int pos = GetBegPos( METHOD_IND ) + myMeth.Length();
+    if ( pos < 1 )
+      pos = myString.Location( "(", 1, Length() );
+    else
+      --pos;
+
+    // we are at or before '(', skip it if present
+    if ( pos > 0 ) {
+      while ( pos <= Length() && myString.Value( pos ) != '(' ) ++pos;
+      if ( myString.Value( pos ) != '(' )
+        pos = 0;
+    }
+    if ( pos < 1 ) {
+      SetBegPos( ARG1_IND, 0 ); // even no '('
+      return theEmptyString;
+    }
+    ++pos;
+
+    list< TCollection_AsciiString > separatorStack( 1, ",)");
+    bool ignoreNesting = false;
+    int prevPos = pos;
+    while ( pos <= Length() )
+    {
+      const char chr = myString.Value( pos );
+
+      if ( separatorStack.back().Location( chr, 1, separatorStack.back().Length()))
+      {
+        if ( separatorStack.size() == 1 ) // ',' dividing args or a terminal ')' found
+        {
+          while ( pos-1 >= prevPos && isspace( myString.Value( prevPos )))
+            ++prevPos;
+          if ( pos-1 >= prevPos ) {
+            TCollection_AsciiString arg = myString.SubString( prevPos, pos-1 );
+            arg.RightAdjust(); // remove spaces
+            arg.LeftAdjust();
+            SetBegPos( ARG1_IND + myArgs.Length(), prevPos );
+            myArgs.Append( arg );
+          }
+          if ( chr == ')' )
+            break;
+          prevPos = pos+1;
+        }
+        else // end of nesting args found
+        {
+          separatorStack.pop_back();
+          ignoreNesting = false;
+        }
       }
-      myArgs.Append( GetWord( myString, begPos, true, true ));
-      SetBegPos( ARG1_IND + i, begPos );
-      prevLen = myArgs.Last().Length();
-      if ( prevLen == 0 )
-        myArgs.Remove( myArgs.Length() ); // no more args
-      i++;
+      else if ( !ignoreNesting )
+      {
+        switch ( chr ) {
+        case '(' : separatorStack.push_back(")"); break;
+        case '[' : separatorStack.push_back("]"); break;
+        case '\'': separatorStack.push_back("'");  ignoreNesting=true; break;
+        case '"' : separatorStack.push_back("\""); ignoreNesting=true; break;
+        default:;
+        }
+      }
+      ++pos;
     }
   }
   if ( myArgs.Length() < index )
@@ -2276,11 +2543,11 @@ TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & the
 //================================================================================
 /*!
  * \brief Look for position where not space char is
-  * \param theString - The string 
+  * \param theString - The string
   * \param thePos - The position to search from and which returns result
   * \retval bool - false if there are only space after thePos in theString
- * 
- * 
+ *
+ *
  */
 //================================================================================
 
@@ -2320,7 +2587,7 @@ void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePar
       case METHOD_IND: seperator = "()"; break;
       default:;
       }
-    }      
+    }
     myString.Remove( pos, theOldPart.Length() );
     if ( !seperator.IsEmpty() )
       myString.Insert( pos , seperator );
@@ -2510,7 +2777,7 @@ void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
 
 //================================================================================
 /*!
- * \brief Clear creatin command if no commands invoked
+ * \brief Clear creation command if no commands invoked
  */
 //================================================================================
 
@@ -2522,3 +2789,131 @@ void _pySubMesh::Flush()
     // move to be just after creator
     myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
 }
+
+//================================================================================
+/*!
+ * \brief To convert creation of a group by filter
+ */
+//================================================================================
+
+void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
+{
+  // Convert the following set of commands into mesh.MakeGroupByFilter(groupName, theFilter)
+  // group = mesh.CreateEmptyGroup( elemType, groupName )
+  // aFilter.SetMesh(mesh)
+  // nbAdd = group.AddFrom( aFilter )
+  if ( theCommand->GetMethod() == "AddFrom" )
+  {
+    _pyID idSource = theCommand->GetArg(1);
+    // check if idSource is a filter
+    Handle(_pyObject) filter = theGen->FindObject( idSource );
+    if ( filter.IsNull() || !filter->IsKind(STANDARD_TYPE(_pyFilter)))
+      return;
+    // find aFilter.SetMesh(mesh) to clear it, it should be just before theCommand
+    list< Handle(_pyCommand) >::reverse_iterator cmdIt = theGen->GetCommands().rbegin();
+    while ( *cmdIt != theCommand ) ++cmdIt;
+    while ( (*cmdIt)->GetOrderNb() != 1 )
+    {
+      const Handle(_pyCommand)& setMeshCmd = *(++cmdIt);
+      if ((setMeshCmd->GetObject() == idSource ||
+           setMeshCmd->GetObject() == Handle(_pyFilter)::DownCast(filter)->GetNewID() )
+          &&
+          setMeshCmd->GetMethod() == "SetMesh")
+      {
+        setMeshCmd->Clear();
+        break;
+      }
+    }
+    // replace 3 commands by one
+    theCommand->Clear();
+    const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd();
+    TCollection_AsciiString name = makeGroupCmd->GetArg( 2 );
+    makeGroupCmd->SetMethod( "MakeGroupByFilter" );
+    makeGroupCmd->SetArg( 1, name );
+    makeGroupCmd->SetArg( 2, idSource );
+    // set new name of a filter
+    filter->Process( makeGroupCmd );
+  }
+  else if ( theCommand->GetMethod() == "SetFilter" )
+  {
+    // set new name of a filter
+    _pyID filterID = theCommand->GetArg(1);
+    Handle(_pyObject) filter = theGen->FindObject( filterID );
+    if ( !filter.IsNull() )
+      filter->Process( theCommand );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Constructor of _pyFilter
+ */
+//================================================================================
+
+_pyFilter::_pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID/*=""*/)
+  :_pyObject(theCreationCmd), myNewID( newID )
+{
+}
+
+//================================================================================
+/*!
+ * \brief To convert creation of a filter by criteria and
+ * to replace an old name by a new one
+ */
+//================================================================================
+
+void _pyFilter::Process( const Handle(_pyCommand)& theCommand)
+{
+  if ( theCommand->GetObject() == GetID() )
+    _pyObject::Process(theCommand); // count commands
+
+  if ( !myNewID.IsEmpty() )
+  {
+    if ( theCommand->GetObject() == GetID() )
+      theCommand->SetObject( myNewID );
+    else if ( theCommand->GetResultValue() == GetID() )
+      theCommand->SetResultValue( myNewID );
+    else
+      for ( int i = 1, nb = theCommand->GetNbArgs(); i <= nb; ++i )
+        if ( theCommand->GetArg( i ) == GetID() )
+        {
+          theCommand->SetArg( i, myNewID );
+          break;
+        }
+  }
+
+  // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria)
+  // aFilter0x2aaab0487080 = aFilterManager.CreateFilter()
+  // aFilter0x2aaab0487080.SetCriteria(aCriteria)
+  if ( GetNbCalls() == 0 && // none method was called before SetCriteria()
+       theCommand->GetMethod() == "SetCriteria")
+  {
+    // aFilter.SetCriteria(aCriteria) ->
+    // aFilter = smesh.GetFilterFromCriteria(criteria)
+    if ( myNewID.IsEmpty() )
+      theCommand->SetResultValue( GetID() );
+    else
+      theCommand->SetResultValue( myNewID );
+    theCommand->SetObject( SMESH_2smeshpy::GenName() );
+    theCommand->SetMethod( "GetFilterFromCriteria" );
+
+    // Clear aFilterManager.CreateFilter()
+    GetCreationCmd()->Clear();
+  }
+  else if ( theCommand->GetMethod() == "SetMesh")
+  {
+    theGen->AddMeshAccessorMethod( theCommand );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Set new filter name to the creation command
+ */
+//================================================================================
+
+void _pyFilter::Flush()
+{
+  if ( !myNewID.IsEmpty() && !GetCreationCmd()->IsEmpty() )
+    GetCreationCmd()->SetResultValue( myNewID );
+}