Salome HOME
Update copyright
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.cxx
index 0777667620f318c7f7304766f408d036cdf4df73..767c325827692f09fccd4edfb3a7491a78a45a6c 100644 (file)
@@ -1,26 +1,26 @@
-//  Copyright (C) 2007-2008  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
-//
 // File      : SMESH_2smeshpy.cxx
 // Created   : Fri Nov 18 13:20:10 2005
 // Author    : Edward AGAPOV (eap)
@@ -121,7 +121,7 @@ namespace {
 TCollection_AsciiString
 SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
                               Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
-                             Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
+                              Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
 {
   theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames );
 
@@ -196,7 +196,7 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
 //================================================================================
 
 _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
-              Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
+               Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
   : _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )),
     myID2AccessorMethod( theEntry2AccessorMethod ),
     myObjectNames( theObjectNames )
@@ -247,7 +247,8 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
 
   // SMESH_Mesh method?
   map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
-  if ( id_mesh != myMeshes.end() ) {
+  if ( id_mesh != myMeshes.end() )
+  {
     // check for mesh editor object
     if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
       _pyID editorID = aCommand->GetResultValue();
@@ -261,13 +262,15 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
       myObjects.insert( make_pair( subMeshID, subMesh ));
     }
+    
     id_mesh->second->Process( aCommand );
     return aCommand;
   }
 
   // SMESH_MeshEditor method?
   map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID );
-  if ( id_editor != myMeshEditors.end() ) {
+  if ( id_editor != myMeshEditors.end() )
+  {
     id_editor->second->Process( aCommand );
     TCollection_AsciiString processedCommand = aCommand->GetString();
     // some commands of SMESH_MeshEditor create meshes
@@ -276,6 +279,15 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
       myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     }
+    if ( aCommand->GetMethod() == "MakeBoundaryMesh") {
+      _pyID meshID = aCommand->GetResultValue(0);
+      if ( !myMeshes.count( meshID ) )
+      {
+        Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID );
+        aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
+        myMeshes.insert( make_pair( meshID, mesh ));
+      }
+    }
     return aCommand;
   }
   // SMESH_Hypothesis method?
@@ -341,6 +353,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
   // Concatenate( [mesh1, ...], ... )
   // CreateHypothesis( theHypType, theLibName )
   // Compute( mesh, geom )
+  // Evaluate( mesh, geom )
   // mesh creation
   TCollection_AsciiString method = theCommand->GetMethod();
 
@@ -350,7 +363,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     return;
   }
-  if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL")
+  if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL" || method == "CopyMesh" )
   {
     Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
@@ -394,6 +407,20 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     }
   }
 
+  // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom)
+  if ( method == "Evaluate" )
+  {
+    const _pyID& meshID = theCommand->GetArg( 1 );
+    map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
+    if ( id_mesh != myMeshes.end() ) {
+      theCommand->SetObject( meshID );
+      _pyID geom = theCommand->GetArg( 2 );
+      theCommand->RemoveArgs();
+      theCommand->SetArg( 1, geom );
+      return;
+    }
+  }
+
   // objects erasing creation command if no more it's commands invoked:
   // SMESH_Pattern, FilterManager
   if ( method == "GetPattern" || method == "CreateFilterManager" ) {
@@ -541,7 +568,7 @@ Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMe
     if ( !hyp->IsNull() &&
          (*hyp)->IsAlgo() &&
          theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) &&
-        (*hyp)->GetGeom() == theGeom &&
+         (*hyp)->GetGeom() == theGeom &&
          (*hyp)->GetMesh() == theMesh )
       return *hyp;
   return 0;
@@ -624,8 +651,8 @@ void _pyGen::SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) the
 //================================================================================
 
 void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd,
-                                 Handle(_pyCommand)& theOtherCmd,
-                                 const bool theIsAfter )
+                                  Handle(_pyCommand)& theOtherCmd,
+                                  const bool theIsAfter )
 {
   list< Handle(_pyCommand) >::iterator pos;
   pos = find( myCommands.begin(), myCommands.end(), theCmd );
@@ -680,8 +707,8 @@ _pyID _pyGen::GenerateNewID( const _pyID& theID )
   while ( myObjectNames.IsBound( aNewID ) );
     
   myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID ) 
-                     ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
-                     : _pyID( "A" ) + aNewID );
+                      ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
+                      : _pyID( "A" ) + aNewID );
   return aNewID;
 }
 
@@ -693,58 +720,58 @@ _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;
+// }
 
 //================================================================================
 /*!
@@ -829,12 +856,14 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
   // ----------------------------------------------------------------------
   else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp)
     _pyID grp = theCommand->GetArg( 3 );
-    if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp)
-      theCommand->SetMethod( "Group" );
-      theCommand->RemoveArgs();
-      theCommand->SetArg( 1, grp );
-    }
-    else {
+    // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump
+    // next if(){...} section is commented
+    //if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp)
+    //  theCommand->SetMethod( "Group" );
+    //  theCommand->RemoveArgs();
+    //  theCommand->SetArg( 1, grp );
+    //}
+    //else {
       _pyID type = theCommand->GetArg( 1 );
       _pyID name = theCommand->GetArg( 2 );
       theCommand->SetMethod( "GroupOnGeom" );
@@ -842,10 +871,11 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
       theCommand->SetArg( 1, grp );
       theCommand->SetArg( 2, name );
       theCommand->SetArg( 3, type );
-    }
+    //}
   }
   // ----------------------------------------------------------------------
-  else if ( method == "ExportToMED" ) { // ExportToMED() --> ExportMED()
+  else if ( method == "ExportToMED" ||   // ExportToMED() --> ExportMED()
+            method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
     theCommand->SetMethod( "ExportMED" );
   }
   // ----------------------------------------------------------------------
@@ -885,6 +915,34 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     // remove hyp from myHypos
     myHypos.remove( hyp );
   }
+  // 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) );
+    const bool isArg = theCommand->GetMethod() == "SetMeshOrder";
+    const TCollection_AsciiString& cmdStr = theCommand->GetString();
+    int begPos = (/*isArg ? cmdStr.Search( "(" ) :*/ cmdStr.Search( "[" )) + 1;
+    int endPos = (isArg ? cmdStr.Search( ")" ) : cmdStr.Search( "=" )) - 1;
+    if ( begPos != -1 && begPos < endPos && endPos <= cmdStr.Length() ) {
+      TCollection_AsciiString aSubStr = cmdStr.SubString( begPos, endPos );
+      Standard_Integer index = 1;
+      TCollection_AsciiString anIDStr = aSubStr.Token("\t ,[]", index++);
+      while ( !anIDStr.IsEmpty() ) {
+        Handle(_pySubMesh) subMesh = theGen->FindSubMesh( anIDStr );
+        if ( !subMesh.IsNull() )
+          subMesh->Process( theCommand );
+        anIDStr = aSubStr.Token("\t ,[]", index++);
+      }
+    }
+  }
   // add accessor method if necessary
   else
   {
@@ -919,7 +977,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
         "GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes",
         "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces",
         "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor",
-        "Clear", "ConvertToStandalone"
+        "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder"
         ,"" }; // <- mark of end
     sameMethods.Insert( names );
   }
@@ -952,21 +1010,21 @@ void _pyMesh::Flush()
     if ( algo->IsWrapped() ) {
       _pyID localAlgoID = theGen->GenerateNewID( algoID );
       TCollection_AsciiString aNewCmdStr = localAlgoID +
-       TCollection_AsciiString( " = " ) + theGen->GetID() +
-       TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
-       TCollection_AsciiString( "\" )" );
+        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() ) {
-       newAlgo->Assign( algo, this->GetID() );
-       newAlgo->SetCreationCmd( newCmd );
-       algo = newAlgo;
-       // set algorithm creation
-       theGen->SetCommandBefore( newCmd, addCmd );
+        newAlgo->Assign( algo, this->GetID() );
+        newAlgo->SetCreationCmd( newCmd );
+        algo = newAlgo;
+        // set algorithm creation
+        theGen->SetCommandBefore( newCmd, addCmd );
       }
       else
-       newCmd->Clear();
+        newCmd->Clear();
     }
     _pyID geom = addCmd->GetArg( 1 );
     bool isLocalAlgo = ( geom != GetGeom() );
@@ -982,14 +1040,14 @@ void _pyMesh::Flush()
         addCmd->SetArg( addCmd->GetNbArgs() + 1,
                         TCollection_AsciiString( "geom=" ) + geom );
         // sm = mesh.GetSubMesh(geom, name) --> sm = ALGO.GetSubMesh()
-       list < Handle(_pySubMesh) >::iterator smIt;
+        list < Handle(_pySubMesh) >::iterator smIt;
         for ( smIt = mySubmeshes.begin(); smIt != mySubmeshes.end(); ++smIt ) {
-         Handle(_pySubMesh) subMesh = *smIt;
+          Handle(_pySubMesh) subMesh = *smIt;
           Handle(_pyCommand) subCmd = subMesh->GetCreationCmd();
           if ( geom == subCmd->GetArg( 1 )) {
             subCmd->SetObject( algo->GetID() );
             subCmd->RemoveArgs();
-           subMesh->SetCreator( algo );
+            subMesh->SetCreator( algo );
           }
         }
       }
@@ -1061,34 +1119,35 @@ _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd):
 
 void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
 {
-  // names of SMESH_MeshEditor methods fully equal to methods of class Mesh, so
+  // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so
   // commands calling this methods are converted to calls of methods of Mesh
   static TStringSet sameMethods;
   if ( sameMethods.empty() ) {
     const char * names[] = {
-      "RemoveElements","RemoveNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace",
+      "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace",
       "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
       "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject",
       "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
       "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
       "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
       "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
-      "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
+      "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathX",
+      "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
       "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
-      "FindCoincidentNodes","FindCoincidentNodesOnPart","MergeNodes","FindEqualElements",
+      "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements",
       "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
       "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
       "GetLastCreatedElems",
       "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
-      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh"
+      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh"
       ,"" }; // <- mark of the end
     sameMethods.Insert( names );
   }
 
   // names of SMESH_MeshEditor methods which differ from methods of class Mesh
-  // only last two arguments
+  // only by last two arguments
   static TStringSet diffLastTwoArgsMethods;
-  if (diffLastTwoArgsMethods.empty() ){
+  if (diffLastTwoArgsMethods.empty() ) {
     const char * names[] = {
       "MirrorMakeGroups","MirrorObjectMakeGroups",
       "TranslateMakeGroups","TranslateObjectMakeGroups",
@@ -1097,41 +1156,85 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     diffLastTwoArgsMethods.Insert( names );
   }
 
-  if ( sameMethods.Contains( theCommand->GetMethod() )) {
-    theCommand->SetObject( myMesh );
-
-    // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
-    // so let _pyMesh care of it (TMP?)
-//     if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
-//       _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
-  }
-  else {
-    
-    //Replace SMESH_MeshEditor "MakeGroups" functions on the Mesh 
+  const TCollection_AsciiString & method = theCommand->GetMethod();
+  bool isPyMeshMethod = sameMethods.Contains( method );
+  if ( !isPyMeshMethod )
+  {
+    //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh 
     //functions with the flag "theMakeGroups = True" like:
     //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
-    int pos = theCommand->GetMethod().Search("MakeGroups");
-    if( pos != -1) {  
+    int pos = method.Search("MakeGroups");
+    if( pos != -1)
+    {
+      isPyMeshMethod = true;
+
       // 1. Remove "MakeGroups" from the Command
       TCollection_AsciiString aMethod = theCommand->GetMethod();
       int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1;
       aMethod.Trunc(pos-1);
       theCommand->SetMethod(aMethod);
 
-      // 2. Set Mesh object instead of SMESH_MeshEditor
-      theCommand->SetObject( myMesh );
-
-      // 3. And add last "True" argument
+      // 2. And add last "True" argument(s)
       while(nbArgsToAdd--)
-        theCommand->SetArg(theCommand->GetNbArgs()+1,"True ");
+        theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
     }
-    else {
-      // editor creation command is needed only if any editor function is called
-      theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
-      if ( !myCreationCmdStr.IsEmpty() ) {
-        GetCreationCmd()->GetString() = myCreationCmdStr;
-        myCreationCmdStr.Clear();
-      }
+  }
+
+  // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
+  if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
+  {
+    isPyMeshMethod=true;
+    theCommand->SetMethod("ExtrusionAlongPathX");
+  }
+
+  // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
+  if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
+  {
+    isPyMeshMethod=true;
+    theCommand->SetMethod("FindCoincidentNodesOnPart");
+  }
+  // DoubleNodeElemGroupNew() -> DoubleNodeElemGroup()
+  // DoubleNodeGroupNew() -> DoubleNodeGroup()
+  // DoubleNodeGroupsNew() -> DoubleNodeGroups()
+  // DoubleNodeElemGroupsNew() -> DoubleNodeElemGroups()
+  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 );
+  }
+
+  // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
+  // so let _pyMesh care of it (TMP?)
+  //     if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
+  //       _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
+  if ( isPyMeshMethod )
+  {
+    theCommand->SetObject( myMesh );
+  }
+  else
+  {
+    // editor creation command is needed only if any editor function is called
+    theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
+    if ( !myCreationCmdStr.IsEmpty() ) {
+      GetCreationCmd()->GetString() = myCreationCmdStr;
+      myCreationCmdStr.Clear();
     }
   }
 }
@@ -1271,11 +1374,24 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
   }
   else if ( hypType == "QuadranglePreference" ) {
     hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D");
-    hyp->SetConvMethodAndType( "QuadranglePreference", "NETGEN_2D_ONLY");
+    hyp->SetConvMethodAndType( "SetQuadAllowed", "NETGEN_2D_ONLY");
   }
   else if ( hypType == "TrianglePreference" ) {
     hyp->SetConvMethodAndType( "TrianglePreference", "Quadrangle_2D");
-  }    
+  }     
+  // RadialQuadrangle_1D2D ----------
+  else if ( hypType == "RadialQuadrangle_1D2D" ) {
+    algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
+    algo->myArgs.Append( "algo=smesh.RADIAL_QUAD" );
+  }
+  else if ( hypType == "NumberOfLayers2D" ) {
+    hyp->SetConvMethodAndType( "NumberOfLayers", "RadialQuadrangle_1D2D");
+    hyp->AddArgMethod( "SetNumberOfLayers" );
+  }
+  else if ( hypType == "LayerDistribution2D" ) {
+    hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get2DHypothesis" );
+    hyp->SetConvMethodAndType( "LayerDistribution", "RadialQuadrangle_1D2D");
+  }
   // BLSURF ----------
   else if ( hypType == "BLSURF" ) {
     algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
@@ -1375,14 +1491,11 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
     hyp->AddArgMethod( "SetNumberOfLayers" );
   }
   else if ( hypType == "LayerDistribution" ) {
-    hyp = new _pyLayerDistributionHypo( theCreationCmd );
+    hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get3DHypothesis" );
     hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
   }
 
-  if ( algo->IsValid() ) {
-    return algo;
-  }
-  return hyp;
+  return algo->IsValid() ? algo : hyp;
 }
 
 //================================================================================
@@ -1532,7 +1645,7 @@ void _pyHypothesis::ClearAllCommands()
 //================================================================================
 
 void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
-                           const _pyID&                 theMesh )
+                            const _pyID&                 theMesh )
 {
   myIsWrapped = false;
   myMesh = theMesh;
@@ -1615,46 +1728,10 @@ void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
     my1dHyp->ClearAllCommands();
   }
   my1dHyp = hyp1d;
-  if ( my1dHyp.IsNull() )
-    return; // something wrong :(
-
-  // make a new name for 1D hyp = "HypType" + "_Distribution"
-  if ( my1dHyp->GetCreationCmd()->GetMethod() == "CreateHypothesis" ) {
-    // not yet converted creation cmd
-    TCollection_AsciiString hypTypeQuoted = my1dHyp->GetCreationCmd()->GetArg(1);
-    TCollection_AsciiString hypType = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
-    newName = hypType + "_Distribution";
-    my1dHyp->GetCreationCmd()->SetResultValue( newName );
-  }
-  else {
-    // already converted creation cmd
-    newName = my1dHyp->GetCreationCmd()->GetResultValue();
-  }
 
-  // as creation of 1D hyp was written later then it's edition,
-  // we need to find all it's edition calls and process them
-  list< Handle(_pyCommand) >& cmds = theGen->GetCommands();
-  list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin();
-  for ( ; cmdIt != cmds.end(); ++cmdIt ) {
-    const _pyID& objID = (*cmdIt)->GetObject();
-    if ( objID == hyp1dID ) {
-      my1dHyp->Process( *cmdIt );
-      my1dHyp->GetCreationCmd()->AddDependantCmd( *cmdIt );
-      ( *cmdIt )->SetObject( newName );
-    }
-  }
   if ( !myArgCommands.empty() )
     myArgCommands.front()->Clear();
-  theCommand->SetArg( 1, newName );
   myArgCommands.push_back( theCommand );
-  // copy hyp1d's creation method and args
-//   myCreationMethod = hyp1d->GetCreationMethod();
-//   myArgs           = hyp1d->GetArgs();
-//   // make them cleared at conversion
-//   myArgCommands = hyp1d->GetArgCommands();
-
-//   // to be cleared at convertion only
-//   myArgCommands.push_back( theCommand );
 }
 
 //================================================================================
@@ -1679,20 +1756,23 @@ bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theA
 
   _pyID geom = theAdditionCmd->GetArg( 1 );
 
-  my1dHyp->SetMesh( theMesh );
-  if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh ))
-    return false;
+  Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this );
+  if ( !algo.IsNull() )
+  {
+    my1dHyp->SetMesh( theMesh );
+    my1dHyp->SetConvMethodAndType(my1dHyp->GetAlgoCreationMethod().ToCString(),
+                                  algo->GetAlgoType().ToCString());
+    if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh ))
+      return false;
 
-  // clear "SetLayerDistribution()" cmd
-  myArgCommands.front()->Clear();
+    // clear "SetLayerDistribution()" cmd
+    myArgCommands.back()->Clear();
 
-  // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis()
+    // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis()
 
-  // find RadialPrism algo created on <geom> for theMesh
-  Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this );
-  if ( !algo.IsNull() ) {
+    // find RadialPrism algo created on <geom> for theMesh
     GetCreationCmd()->SetObject( algo->GetID() );
-    GetCreationCmd()->SetMethod( "Get3DHypothesis" );
+    GetCreationCmd()->SetMethod( myAlgoMethod );
     GetCreationCmd()->RemoveArgs();
     theAdditionCmd->AddDependantCmd( GetCreationCmd() );
     myIsWrapped = true;
@@ -1708,8 +1788,38 @@ bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theA
 
 void _pyLayerDistributionHypo::Flush()
 {
-  //my1dHyp.Nullify();
-  //_pyHypothesis::Flush();
+  // as creation of 1D hyp was written later then it's edition,
+  // we need to find all it's edition calls and process them
+  if ( !my1dHyp.IsNull() )
+  {
+    _pyID hyp1dID = my1dHyp->GetCreationCmd()->GetResultValue();
+
+    // make a new name for 1D hyp = "HypType" + "_Distribution"
+    _pyID newName;
+    if ( my1dHyp->IsWrapped() ) {
+      newName = my1dHyp->GetCreationCmd()->GetMethod();
+    }
+    else {
+      TCollection_AsciiString hypTypeQuoted = my1dHyp->GetCreationCmd()->GetArg(1);
+      newName = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
+    }
+    newName += "_Distribution";
+    my1dHyp->GetCreationCmd()->SetResultValue( newName );
+
+    list< Handle(_pyCommand) >& cmds = theGen->GetCommands();
+    list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin();
+    for ( ; cmdIt != cmds.end(); ++cmdIt ) {
+      const _pyID& objID = (*cmdIt)->GetObject();
+      if ( objID == hyp1dID ) {
+        my1dHyp->Process( *cmdIt );
+        my1dHyp->GetCreationCmd()->AddDependantCmd( *cmdIt );
+        ( *cmdIt )->SetObject( newName );
+      }
+    }
+    // Set new hyp name to SetLayerDistribution() cmd
+    if ( !myArgCommands.empty() && !myArgCommands.back()->IsEmpty() )
+      myArgCommands.back()->SetArg( 1, newName );
+  }
 }
 
 //================================================================================
@@ -1995,15 +2105,15 @@ const TCollection_AsciiString & _pyCommand::GetObject()
       int nb1 = 0; // number of ' character at the left of =
       int nb2 = 0; // number of " character at the left of =
       for ( int i = 1; i < begPos-1; i++ ) {
-       if ( myString.Value( i )=='\'' )
-         nb1 += 1;
-       else if ( myString.Value( i )=='"' )
-         nb2 += 1;
+        if ( myString.Value( i )=='\'' )
+          nb1 += 1;
+        else if ( myString.Value( i )=='"' )
+          nb2 += 1;
       }
       // if number of ' or " is not divisible by 2,
       // then get an object at the start of the command
       if ( nb1 % 2 != 0 || nb2 % 2 != 0 )
-       begPos = 1;
+        begPos = 1;
     }
     myObj = GetWord( myString, begPos, true );
     // check if object is complex,
@@ -2073,16 +2183,16 @@ const TCollection_AsciiString & _pyCommand::GetArg( int index )
     while ( begPos != EMPTY ) {
       begPos += prevLen;
       if( myString.Value( begPos ) == '(' )
-       nbNestings++;
+        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;
+        nbNestings--;
+        if( nbNestings == 0 )
+          break;
       }
       myArgs.Append( GetWord( myString, begPos, true, true ));
       SetBegPos( ARG1_IND + i, begPos );
@@ -2415,7 +2525,7 @@ void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
 
 //================================================================================
 /*!
- * \brief Clear creatin command if no commands invoked
+ * \brief Clear creation command if no commands invoked
  */
 //================================================================================