Salome HOME
Add "const char* name" argument to consrtucctor of SMESH_subMeshEventListener
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.cxx
index af9123b210aae038ffbd085318238e6bec9941d8..c43ffae0ba6dfdccac4505527e295d6e803387a4 100644 (file)
@@ -35,7 +35,7 @@
 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
 
 #include "SMESH_Gen_i.hxx"
-/* SALOME headers that include CORBA headers that include windows.h 
+/* SALOME headers that include CORBA headers that include windows.h
  * that defines GetObject symbol as GetObjectA should stand before SALOME headers
  * that declare methods named GetObject - to apply the same rules of GetObject renaming
  * and thus to avoid mess with GetObject symbol on Windows */
@@ -134,7 +134,7 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
   // split theScript into separate commands
 
   SMESH_NoteBook * aNoteBook = new SMESH_NoteBook();
-  
+
   int from = 1, end = theScript.Length(), to;
   while ( from < end && ( to = theScript.Location( "\n", from, end )))
   {
@@ -143,13 +143,13 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
         aNoteBook->AddCommand( theScript.SubString( from, to - 1 ));
       from = to + 1;
   }
-  
+
   aNoteBook->ReplaceVariables();
 
   TCollection_AsciiString aNoteScript = aNoteBook->GetResultScript();
   delete aNoteBook;
   aNoteBook = 0;
-  
+
   // split theScript into separate commands
   from = 1, end = aNoteScript.Length();
   while ( from < end && ( to = aNoteScript.Location( "\n", from, end )))
@@ -175,7 +175,7 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
       if ( (*cmd)->SetDependentCmdsAfter() )
         orderChanges = true;
   } while ( orderChanges );
-  
+
   // concat commands back into a script
   TCollection_AsciiString aScript;
   for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd )
@@ -203,12 +203,15 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
 
 _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
                Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
-  : _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )),
+  : _pyObject( new _pyCommand( "", 0 )),
+    myNbCommands( 0 ),
     myID2AccessorMethod( theEntry2AccessorMethod ),
-    myObjectNames( theObjectNames )
+    myObjectNames( theObjectNames ),
+    myNbFilters( 0 )
 {
-  myNbCommands = 0;
   // make that GetID() to return TPythonDump::SMESHGenName()
+  GetCreationCmd()->Clear();
+  GetCreationCmd()->GetString() = TPythonDump::SMESHGenName();
   GetCreationCmd()->GetString() += "=";
 }
 
@@ -240,7 +243,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   MESSAGE ( "## COM " << myNbCommands << ": "<< aCommand->GetString() );
 #endif
 
-  _pyID objID = aCommand->GetObject();
+  const _pyID& objID = aCommand->GetObject();
 
   if ( objID.IsEmpty() )
     return aCommand;
@@ -248,7 +251,8 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   // Find an object to process theCommand
 
   // SMESH_Gen method?
-  if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName()) {
+  if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName())
+  {
     this->Process( aCommand );
     return aCommand;
   }
@@ -257,20 +261,22 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
   if ( id_mesh != myMeshes.end() )
   {
+    id_mesh->second->AddProcessedCmd( aCommand );
+
     // check for mesh editor object
     if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
       _pyID editorID = aCommand->GetResultValue();
       Handle(_pyMeshEditor) editor = new _pyMeshEditor( aCommand );
       myMeshEditors.insert( make_pair( editorID, editor ));
       return aCommand;
-    } 
+    }
     // check for SubMesh objects
     else if ( aCommand->GetMethod() == "GetSubMesh" ) { // SubMesh creation
       _pyID subMeshID = aCommand->GetResultValue();
       Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
       myObjects.insert( make_pair( subMeshID, subMesh ));
     }
-    
+
     id_mesh->second->Process( aCommand );
     return aCommand;
   }
@@ -280,12 +286,15 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   if ( id_editor != myMeshEditors.end() )
   {
     id_editor->second->Process( aCommand );
+    id_editor->second->AddProcessedCmd( aCommand );
     TCollection_AsciiString processedCommand = aCommand->GetString();
+
     // some commands of SMESH_MeshEditor create meshes
     if ( aCommand->GetMethod().Search("MakeMesh") != -1 ) {
-      Handle(_pyMesh) mesh = new _pyMesh( aCommand, aCommand->GetResultValue() );
+      _pyID meshID = aCommand->GetResultValue();
+      Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID );
       aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
-      myMeshes.insert( make_pair( mesh->GetID(), mesh ));
+      myMeshes.insert( make_pair( meshID, mesh ));
     }
     if ( aCommand->GetMethod() == "MakeBoundaryMesh") {
       _pyID meshID = aCommand->GetResultValue(0);
@@ -303,13 +312,21 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   for ( ; hyp != myHypos.end(); ++hyp )
     if ( !(*hyp)->IsAlgo() && objID == (*hyp)->GetID() ) {
       (*hyp)->Process( aCommand );
+      (*hyp)->AddProcessedCmd( aCommand );
       return aCommand;
     }
 
   // aFilterManager.CreateFilter() ?
   if ( aCommand->GetMethod() == "CreateFilter" )
   {
-    Handle(_pyObject) filter( new _pyFilter( aCommand ));
+    // 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 );
   }
 
@@ -317,6 +334,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.find( objID );
   if ( id_obj != myObjects.end() ) {
     id_obj->second->Process( aCommand );
+    id_obj->second->AddProcessedCmd( aCommand );
     return aCommand;
   }
 
@@ -376,6 +394,18 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
     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_HEXAGONAL_PRISM",
+        "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 )
@@ -438,7 +468,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     return;
   }
-  if( method == "CreateMeshesFromMED")
+  if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV")
   {
     for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
     {
@@ -793,72 +823,49 @@ void _pyGen::AddObject( Handle(_pyObject)& theObj )
 {
   myObjects.insert( make_pair( theObj->GetID(), theObj ));
 }
-  
-//================================================================================
-/*!
- * \brief Find out type of geom group
-  * \param grpID - The geom group entry
-  * \retval int - The type
- */
-//================================================================================
-
-// 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 Finds a _pyObject by ID
+ */
+//================================================================================
+
+Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID )  const
+{
+  {
+    map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.find( theObjID );
+    if ( id_obj != myObjects.end() )
+      return id_obj->second;
+  }
+  {
+    map< _pyID, Handle(_pyMesh) >::const_iterator id_obj = myMeshes.find( theObjID );
+    if ( id_obj != myMeshes.end() )
+      return id_obj->second;
+  }
+  {
+    map< _pyID, Handle(_pyMeshEditor) >::const_iterator id_obj = myMeshEditors.find( theObjID );
+    if ( id_obj != myMeshEditors.end() )
+      return id_obj->second;
+  }
+  return Handle(_pyObject)();
+}
+
+//================================================================================
+/*!
+ * \brief Returns true if an object is removed from study
+ */
+//================================================================================
+
+bool _pyGen::IsDead(const _pyID& theObjID) const
+{
+  if ( theObjID.IsEmpty() ) return false;
+  const bool hasStudyName = myObjectNames.IsBound( theObjID );
+  return !hasStudyName;
+}
+
+//================================================================================
+/*!
+ * \brief Mesh created by SMESH_Gen
  */
 //================================================================================
 
@@ -867,29 +874,25 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd)
 {
   // convert my creation command
   Handle(_pyCommand) creationCmd = GetCreationCmd();
-  //TCollection_AsciiString str = creationCmd->GetMethod();
-//   if(str != "CreateMeshesFromUNV" &&
-//      str != "CreateMeshesFromMED" &&
-//      str != "CreateMeshesFromSTL")
   creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
   creationCmd->SetMethod( "Mesh" );
 
-  theGen->SetAccessorMethod( GetID(), "GetMesh()" );
+  theGen->SetAccessorMethod( GetID(), _pyMesh::AccessorMethod() );
 }
 
 //================================================================================
 /*!
- * \brief
-  * \param theCreationCmd -
+ * \brief Mesh created by SMESH_MeshEditor
  */
 //================================================================================
+
 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString& id):
   _pyObject(theCreationCmd), myHasEditor(false)
 {
   // convert my creation command
   Handle(_pyCommand) creationCmd = GetCreationCmd();
   creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
-  theGen->SetAccessorMethod( id, "GetMesh()" );
+  theGen->SetAccessorMethod( id, _pyMesh::AccessorMethod() );
 }
 
 //================================================================================
@@ -923,6 +926,12 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
       mySubmeshes.push_back( subMesh );
     }
   }
+  else if ( method == "RemoveSubMesh" ) { // move submesh creation before its removal
+    Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetArg(1) );
+    if ( !subMesh.IsNull() )
+      subMesh->Process( theCommand );
+    AddMeshAccess( theCommand );
+  }
   // ----------------------------------------------------------------------
   else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
     myAddHypCmds.push_back( theCommand );
@@ -960,6 +969,23 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
   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()
@@ -1075,7 +1101,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
   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",
@@ -1119,7 +1145,7 @@ void _pyMesh::Flush()
     // check and create new algorithm instance if it is already wrapped
     if ( algo->IsWrapped() ) {
       _pyID localAlgoID = theGen->GenerateNewID( algoID );
-      TCollection_AsciiString aNewCmdStr = localAlgoID +
+      TCollection_AsciiString aNewCmdStr = addCmd->GetIndentation() + localAlgoID +
         TCollection_AsciiString( " = " ) + theGen->GetID() +
         TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
         TCollection_AsciiString( "\" )" );
@@ -1142,7 +1168,7 @@ void _pyMesh::Flush()
     // try to convert
     if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK
     {
-      // wrapped algo is created atfer mesh creation
+      // wrapped algo is created after mesh creation
       GetCreationCmd()->AddDependantCmd( addCmd );
 
       if ( isLocalAlgo ) {
@@ -1249,7 +1275,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 );
   }
@@ -1585,6 +1612,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");
@@ -1617,10 +1647,38 @@ 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;
 }
 
+//================================================================================
+/*!
+ * \brief Returns true if addition of this hypothesis to a given mesh can be
+ *        wrapped into hypothesis creation
+ */
+//================================================================================
+
+bool _pyHypothesis::IsWrappable(const _pyID& theMesh) const
+{
+  if ( !myIsWrapped && myMesh == theMesh && !IsRemovedFromStudy() )
+  {
+    Handle(_pyObject) pyMesh = theGen->FindObject( myMesh );
+    if ( !pyMesh.IsNull() && !pyMesh->IsRemovedFromStudy() )
+      return true;
+  }
+  return false;
+}
+
 //================================================================================
 /*!
  * \brief Convert the command adding a hypothesis to mesh into a smesh command
@@ -1787,15 +1845,47 @@ 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
+    // NOW it is OBSOLETE
     // ex: hyp.SetLength(start, 1)
     //     hyp.SetLength(end,   0)
     ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() ));
@@ -2632,6 +2722,19 @@ bool _pyCommand::AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod
   return added;
 }
 
+//================================================================================
+/*!
+ * \brief Creates pyObject
+ */
+//================================================================================
+
+_pyObject::_pyObject(const Handle(_pyCommand)& theCreationCmd)
+  : myCreationCmd(theCreationCmd), myNbCalls(0), myIsRemoved(false)
+{
+  if ( !theCreationCmd.IsNull() && !theCreationCmd->IsEmpty() )
+    myIsRemoved = theGen->IsDead( theCreationCmd->GetResultValue() );
+}
+
 //================================================================================
 /*!
  * \brief Return method name giving access to an interaface object wrapped by python class
@@ -2683,7 +2786,7 @@ void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
 
 //================================================================================
 /*!
- * \brief Clear creation command if no commands invoked
+ * \brief Move creation command depending on invoked commands
  */
 //================================================================================
 
@@ -2695,6 +2798,7 @@ void _pySubMesh::Flush()
     // move to be just after creator
     myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
 }
+
 //================================================================================
 /*!
  * \brief To convert creation of a group by filter
@@ -2710,31 +2814,25 @@ void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
   if ( theCommand->GetMethod() == "AddFrom" )
   {
     _pyID idSource = theCommand->GetArg(1);
-    // check if idSource is a filter: find a command creating idSource,
-    // it should be "idSource = aFilterManager.CreateFilter()" or
-    // "idSource = smesh.GetFilterFromCriteria(aCriteria)
-    const list< Handle(_pyCommand) >& commands = theGen->GetCommands();
-    list< Handle(_pyCommand) >::const_reverse_iterator cmdIt = commands.rbegin();
-    bool isFilter = false;
-    for ( ; cmdIt != commands.rend(); ++cmdIt )
-      if ( (*cmdIt)->GetResultValue() == idSource )
-      {
-        isFilter = ( (*cmdIt)->GetMethod() == "CreateFilter" ||
-                     (*cmdIt)->GetMethod() == "GetFilterFromCriteria" );
-        break;
-      }
-    if ( !isFilter ) return;
-
+    // 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
-    for ( cmdIt = commands.rbegin(); cmdIt != commands.rend(); ++cmdIt )
-      if ( *cmdIt == theCommand && (*cmdIt)->GetOrderNb() != 1 )
+    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")
       {
-        const Handle(_pyCommand)& setMeshCmd = *(++cmdIt);
-        if ( setMeshCmd->GetObject() == idSource &&
-             setMeshCmd->GetMethod() == "SetMesh")
-          setMeshCmd->Clear();
+        setMeshCmd->Clear();
         break;
       }
+    }
     // replace 3 commands by one
     theCommand->Clear();
     const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd();
@@ -2742,17 +2840,57 @@ void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
     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
+ * \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)
@@ -2761,7 +2899,10 @@ void _pyFilter::Process( const Handle(_pyCommand)& theCommand)
   {
     // aFilter.SetCriteria(aCriteria) ->
     // aFilter = smesh.GetFilterFromCriteria(criteria)
-    theCommand->SetResultValue( GetID() );
+    if ( myNewID.IsEmpty() )
+      theCommand->SetResultValue( GetID() );
+    else
+      theCommand->SetResultValue( myNewID );
     theCommand->SetObject( SMESH_2smeshpy::GenName() );
     theCommand->SetMethod( "GetFilterFromCriteria" );
 
@@ -2773,3 +2914,15 @@ void _pyFilter::Process( const Handle(_pyCommand)& theCommand)
     theGen->AddMeshAccessorMethod( theCommand );
   }
 }
+
+//================================================================================
+/*!
+ * \brief Set new filter name to the creation command
+ */
+//================================================================================
+
+void _pyFilter::Flush()
+{
+  if ( !myNewID.IsEmpty() && !GetCreationCmd()->IsEmpty() )
+    GetCreationCmd()->SetResultValue( myNewID );
+}