Salome HOME
0022318: [CEA] Problems with study dump in SMESH
[modules/smesh.git] / src / SMESH_I / SMESH_DumpPython.cxx
index a8e4205b26c4121d3ce52d0d8ec3b5349216e31c..7d26ddd73e05e956ad5b7b0e94516aeb5fc0966c 100644 (file)
@@ -1,31 +1,29 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  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
 //
+//  File    : SMESH_DumpPython.cxx
+//  Created : Thu Mar 24 17:17:59 2005
+//  Author  : Julia DOROVSKIKH
+//  Module  : SMESH
 
-// File    : SMESH_Gen_i_DumpPython.cxx
-// Created : Thu Mar 24 17:17:59 2005
-// Author  : Julia DOROVSKIKH
-// Module  : SMESH
-// $Header : $
-//
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Filter_i.hxx"
@@ -43,18 +41,23 @@ static int MYDEBUG = 0;
 static int MYDEBUG = 0;
 #endif
 
-static TCollection_AsciiString NotPublishedObjectName()
-{
-  return "__NOT__Published__Object__";
-}
-
 namespace SMESH
 {
 
   size_t TPythonDump::myCounter = 0;
+  const char theNotPublishedObjectName[] = "__NOT__Published__Object__";
+
+  TVar::TVar(CORBA::Double value):myVals(1) { myVals[0] = SMESH_Comment(value); }
+  TVar::TVar(CORBA::Long   value):myVals(1) { myVals[0] = SMESH_Comment(value); }
+  TVar::TVar(CORBA::Short  value):myVals(1) { myVals[0] = SMESH_Comment(value); }
+  TVar::TVar(const SMESH::double_array& value):myVals(value.length())
+  {
+    for ( size_t i = 0; i < value.length(); i++)
+      myVals[i] = SMESH_Comment(value[i]);
+  }
 
   TPythonDump::
-  TPythonDump()
+  TPythonDump():myVarsCounter(0)
   {
     ++myCounter;
   }
@@ -69,46 +72,80 @@ namespace SMESH
       if(!aStudy->_is_nil() && !aCollection.IsEmpty()){
         aSMESHGen->AddToPythonScript(aStudy->StudyId(),aCollection);
         if(MYDEBUG) MESSAGE(aString);
+        aSMESHGen->UpdateParameters(""); // prevent misuse of already treated variables
       }
     }
   }
 
-  TPythonDump& 
+  TPythonDump& //!< to store a variable value
+  TPythonDump::
+  operator<<(const TVar& theVarValue)
+  {
+    if ( theVarValue.myVals.empty() ) return *this;
+
+    const std::vector< std::string >& varNames = SMESH_Gen_i::GetSMESHGen()->GetLastParameters();
+    if ( theVarValue.myVals.size() > 1 )
+    {
+      myStream << "[ ";
+      for ( size_t i = 1; i <= theVarValue.myVals.size(); ++i )
+      {
+        if ( myVarsCounter < varNames.size() && !varNames[ myVarsCounter ].empty() )
+          myStream << TVar::Quote() << varNames[ myVarsCounter ] << TVar::Quote();
+        else
+          myStream << theVarValue.myVals[i-1];
+        if ( i < theVarValue.myVals.size() )
+          myStream << ", ";
+        ++myVarsCounter;
+      }
+      myStream << " ]";
+    }
+    else
+    {
+      if ( myVarsCounter < varNames.size() && !varNames[ myVarsCounter ].empty() )
+        myStream << TVar::Quote() << varNames[ myVarsCounter ] << TVar::Quote();
+      else
+        myStream << theVarValue.myVals[0];
+      ++myVarsCounter;
+    }
+    return *this;
+  }
+
+  TPythonDump&
   TPythonDump::
   operator<<(long int theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(int theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(double theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(float theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(const void* theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(const char* theArg){
     if ( theArg )
@@ -116,7 +153,7 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(const SMESH::ElementType& theArg)
   {
@@ -127,6 +164,8 @@ namespace SMESH
     case EDGE:  myStream<<"EDGE";break;
     case FACE:  myStream<<"FACE";break;
     case VOLUME:myStream<<"VOLUME";break;
+    case ELEM0D:myStream<<"ELEM0D";break;
+    default:    myStream<<"__UNKNOWN__ElementType: " << theArg;
     }
     return *this;
   }
@@ -147,7 +186,8 @@ namespace SMESH
     case Geom_HEXA:       myStream<<"Geom_HEXA";       break;
     case Geom_PENTA:      myStream<<"Geom_PENTA";      break;
     case Geom_POLYHEDRA:  myStream<<"Geom_POLYHEDRA";  break;
-   }
+    default:    myStream<<"__UNKNOWN__GeometryType: " << theArg;
+    }
     return *this;
   }
 
@@ -163,32 +203,48 @@ namespace SMESH
     theStream << " ]";
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::operator<<(const SMESH::long_array& theArg)
   {
     DumpArray( theArg, *this );
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::operator<<(const SMESH::double_array& theArg)
   {
     DumpArray( theArg, *this );
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
+  TPythonDump::operator<<(const SMESH::string_array& theArray)
+  {
+    myStream << "[ ";
+    for (int i = 1; i <= theArray.length(); i++) {
+      myStream << "'" << theArray[i-1] << "'";
+      if ( i < theArray.length() )
+        myStream << ", ";
+    }
+    myStream << " ]";
+    return *this;
+  }
+
+  TPythonDump&
   TPythonDump::
   operator<<(SALOMEDS::SObject_ptr aSObject)
   {
-    if ( !aSObject->_is_nil() )
-      myStream << aSObject->GetID();
-    else
-      myStream << NotPublishedObjectName();
+    if ( !aSObject->_is_nil() ) {
+      CORBA::String_var entry = aSObject->GetID();
+      myStream << entry.in();
+    }
+    else {
+      myStream << theNotPublishedObjectName;
+    }
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(CORBA::Object_ptr theArg)
   {
@@ -202,14 +258,14 @@ namespace SMESH
       if ( aSMESHGen->CanPublishInStudy( theArg )) // not published SMESH object
         myStream << "smeshObj_" << size_t(theArg);
       else
-        myStream << NotPublishedObjectName();
+        myStream << theNotPublishedObjectName;
     }
     else
       myStream << "None";
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::SMESH_Hypothesis_ptr theArg)
   {
@@ -222,23 +278,31 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::SMESH_IDSource_ptr theArg)
   {
+    if ( CORBA::is_nil( theArg ) )
+      return *this << "None";
     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
     SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
     SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
-    if(!aSObject->_is_nil() || CORBA::is_nil( theArg ))
+    if(!aSObject->_is_nil())
       return *this << aSObject;
-    SMESH::long_array_var anElementsId = theArg->GetIDs();
+    if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theArg ))
+      return *this << filter;
     SMESH::SMESH_Mesh_var mesh = theArg->GetMesh();
-    SMESH::array_of_ElementType_var types =  theArg->GetTypes();
-    SMESH::ElementType type = types->length() ? types[0] : SMESH::ALL;
-    return *this << mesh << ".GetIDSource(" << anElementsId << ", " << type << ")";
+    if ( !theArg->_is_equivalent( mesh ))
+    {
+      SMESH::long_array_var anElementsId = theArg->GetIDs();
+      SMESH::array_of_ElementType_var types =  theArg->GetTypes();
+      SMESH::ElementType type = types->length() ? types[0] : SMESH::ALL;
+      return *this << mesh << ".GetIDSource(" << anElementsId << ", " << type << ")";
+    }
+    return *this << theNotPublishedObjectName;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::FilterLibrary_i* theArg)
   {
@@ -246,7 +310,7 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::FilterManager_i* theArg)
   {
@@ -254,7 +318,7 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::Filter_i* theArg)
   {
@@ -262,7 +326,7 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::Functor_i* theArg)
   {
@@ -316,7 +380,7 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::Measurements_i* theArg)
   {
@@ -353,23 +417,32 @@ namespace SMESH
 
   TPythonDump& TPythonDump::operator<<(const SMESH::AxisStruct & theAxis)
   {
-    myStream << "SMESH.AxisStruct( "
-             << theAxis.x  << ", "
-             << theAxis.y  << ", "
-             << theAxis.z  << ", "
-             << theAxis.vx << ", "
-             << theAxis.vy << ", "
-             << theAxis.vz << " )";
+    *this << "SMESH.AxisStruct( "
+          << TVar( theAxis.x  ) << ", "
+          << TVar( theAxis.y  ) << ", "
+          << TVar( theAxis.z  ) << ", "
+          << TVar( theAxis.vx ) << ", "
+          << TVar( theAxis.vy ) << ", "
+          << TVar( theAxis.vz ) << " )";
     return *this;
   }
 
   TPythonDump& TPythonDump::operator<<(const SMESH::DirStruct & theDir)
   {
     const SMESH::PointStruct & P = theDir.PS;
-    myStream << "SMESH.DirStruct( SMESH.PointStruct ( "
-             << P.x  << ", "
-             << P.y  << ", "
-             << P.z  << " ))";
+    *this << "SMESH.DirStruct( SMESH.PointStruct ( "
+          << TVar( P.x ) << ", "
+          << TVar( P.y ) << ", "
+          << TVar( P.z ) << " ))";
+    return *this;
+  }
+
+  TPythonDump& TPythonDump::operator<<(const SMESH::PointStruct & P)
+  {
+    *this << "SMESH.PointStruct ( "
+          << TVar( P.x ) << ", "
+          << TVar( P.y ) << ", "
+          << TVar( P.z ) << " )";
     return *this;
   }
 
@@ -378,11 +451,20 @@ namespace SMESH
     DumpArray( theList, *this );
     return *this;
   }
+  TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups * theList)
+  {
+    DumpArray( *theList, *this );
+    return *this;
+  }
   TPythonDump& TPythonDump::operator<<(const SMESH::ListOfIDSources& theList)
   {
     DumpArray( theList, *this );
     return *this;
   }
+  const char* TPythonDump::NotPublishedObjectName()
+  {
+    return theNotPublishedObjectName;
+  }
 
   TCollection_AsciiString myLongStringStart( "TPythonDump::LongStringStart" );
   TCollection_AsciiString myLongStringEnd  ( "TPythonDump::LongStringEnd" );
@@ -390,7 +472,7 @@ namespace SMESH
   //================================================================================
   /*!
    * \brief Return marker of long string literal beginning
-   * \param type - a name of functionality producing the string literal 
+   * \param type - a name of functionality producing the string literal
    * \retval TCollection_AsciiString - the marker string to be written into
    * a raw python script
    */
@@ -426,7 +508,7 @@ namespace SMESH
       * \param theLongString - the retrieved literal
       * \param theStringType - a name of functionality produced the literal
       * \retval bool - true if a string literal found
-     * 
+     *
      * The literal is removed from theText; theFrom points position right after
      * the removed literal
    */
@@ -480,11 +562,31 @@ namespace SMESH
 }
 
 //=======================================================================
-//function : DumpPython
+//function : RemoveTabulation
 //purpose  : 
 //=======================================================================
+void RemoveTabulation( TCollection_AsciiString& theScript )
+{
+  std::string aString( theScript.ToCString() );
+  std::string::size_type aPos = 0;
+  while( aPos < aString.length() )
+  {
+    aPos = aString.find( "\n\t", aPos );
+    if( aPos == std::string::npos )
+      break;
+    aString.replace( aPos, 2, "\n" );
+    aPos++;
+  }
+  theScript = aString.c_str();
+}
+
+//=======================================================================
+//function : DumpPython
+//purpose  :
+//=======================================================================
 Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
                                            CORBA::Boolean isPublished,
+                                           CORBA::Boolean isMultiFile,
                                            CORBA::Boolean& isValidScript)
 {
   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
@@ -524,20 +626,20 @@ Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
 
   // Add trace of API methods calls and replace study entries by names
   TCollection_AsciiString aScript;
-  aScript += DumpPython_impl(aStudy, aMap, aMapNames,
-                             isPublished, isValidScript, aSavedTrace);
+  aScript += DumpPython_impl(aStudy, aMap, aMapNames, isPublished, isMultiFile,
+                             myIsHistoricalPythonDump, isValidScript, aSavedTrace);
 
-  int aLen = aScript.Length(); 
+  int aLen = aScript.Length();
   unsigned char* aBuffer = new unsigned char[aLen+1];
   strcpy((char*)aBuffer, aScript.ToCString());
 
   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
-  Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1); 
+  Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1);
 
-  bool hasNotPublishedObjects = aScript.Location( NotPublishedObjectName(), 1, aLen);
+  bool hasNotPublishedObjects = aScript.Location( SMESH::theNotPublishedObjectName, 1, aLen);
   isValidScript = isValidScript && !hasNotPublishedObjects;
 
-  return aStreamFile._retn(); 
+  return aStreamFile._retn();
 }
 
 //=============================================================================
@@ -568,7 +670,7 @@ void SMESH_Gen_i::RemoveLastFromPythonScript (int theStudyID)
 
 //=======================================================================
 //function : SavePython
-//purpose  : 
+//purpose  :
 //=======================================================================
 void SMESH_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy)
 {
@@ -621,10 +723,10 @@ Handle(TColStd_HSequenceOfInteger) FindEntries (TCollection_AsciiString& theStri
     int c = (int)arr[i];
     j = i+1;
     if ( isdigit( c )) { //Is digit?
+
       isFound = Standard_False;
       while((j < aLen) && ( isdigit(c) || c == ':' )) { //Check if it is an entry
-        c = (int)arr[j++];  
+        c = (int)arr[j++];
         if(c == ':') isFound = Standard_True;
       }
 
@@ -661,20 +763,28 @@ namespace {
     const TCollection_AsciiString allowedChars =
       "qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_";
     bool isValidName = true;
-    int p=1; // replace not allowed chars with underscore
+    int nbUnderscore = 0;
+    int p=1; // replace not allowed chars by underscore
     while (p <= aName.Length() &&
            (p = aName.FirstLocationNotInSet(allowedChars, p, aName.Length())))
     {
       if ( p == 1 || p == aName.Length() || aName.Value(p-1) == '_')
-        aName.Remove( p, 1 ); // remove double _ and from the start and the end
+        aName.Remove( p, 1 ); // remove double _ from the start and the end
       else
-        aName.SetValue(p, '_');
+        aName.SetValue(p, '_'), nbUnderscore++;
       isValidName = false;
     }
     if ( aName.IsIntegerValue() ) { // aName must not start with a digit
       aName.Insert( 1, 'a' );
       isValidName = false;
     }
+    // shorten names like CartesianParameters3D_400_400_400_1000000_1
+    if ( aName.Length() > 20 && nbUnderscore > 2 )
+    {
+      p = aName.Location( "_", 20, aName.Length());
+      if ( p > 1 )
+        aName.Trunc( p-1 );
+    }
     return isValidName;
   }
 }
@@ -685,10 +795,12 @@ namespace {
  */
 //=============================================================================
 TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
-                        (SALOMEDS::Study_ptr theStudy, 
+                        (SALOMEDS::Study_ptr theStudy,
                          Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
                          Resource_DataMapOfAsciiStringAsciiString& theNames,
-                         bool isPublished, 
+                         bool isPublished,
+                         bool isMultiFile,
+                         bool isHistoricalDump,
                          bool& aValidScript,
                          const TCollection_AsciiString& theSavedTrace)
 {
@@ -700,7 +812,9 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   TCollection_AsciiString anOldGen( SMESH::TPythonDump::SMESHGenName() );
 
   TCollection_AsciiString aScript;
-  aScript = "def RebuildData(theStudy):\n\t";
+  if( isMultiFile )
+    aScript += "def RebuildData(theStudy):";
+  aScript += "\n\t";
   aScript += helper + "aFilterManager = " + aSMESHGen + ".CreateFilterManager()\n\t";
   aScript += helper + "aMeasurements = " + aSMESHGen + ".CreateMeasurements()\n\t";
   if ( isPublished )
@@ -754,13 +868,24 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   // Some objects are wrapped with python classes and
   // Resource_DataMapOfAsciiStringAsciiString holds methods returning wrapped objects
   Resource_DataMapOfAsciiStringAsciiString anEntry2AccessorMethod;
-  aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod, theObjectNames );
+  std::set< TCollection_AsciiString >      aRemovedObjIDs;
+  if ( !getenv("NO_2smeshpy_conversion"))
+    SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod,
+                                   theObjectNames, aRemovedObjIDs,
+                                   theStudy, isHistoricalDump );
+
+  // Replace characters used instead of quote marks to quote notebook variables
+  {
+    int pos = 1;
+    while (( pos = aScript.Location( 1, SMESH::TVar::Quote(), pos, aScript.Length() )))
+      aScript.SetValue( pos, '"' );
+  }
 
   // Find entries to be replaced by names
   Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript);
   Standard_Integer aLen = aSeq->Length();
 
-  if (aLen == 0)
+  if (aLen == 0 && isMultiFile)
     return aScript;
 
   // Replace entries by the names
@@ -770,7 +895,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   Standard_Integer objectCounter = 0, aStart = 1, aScriptLength = aScript.Length();
   TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("smeshObj_");
 
-  // Collect names of GEOM objects to exclude same names for SMESH objects
+  // Collect names of GEOM objects to exclude same names of SMESH objects
   GEOM::string_array_var aGeomNames = geom->GetAllDumpNames();
   int ign = 0, nbgn = aGeomNames->length();
   for (; ign < nbgn; ign++) {
@@ -809,7 +934,8 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
         do {
           aName = aBaseName + (++objectCounter);
         } while (theObjectNames.IsBound(aName));
-        seqRemoved.Append(aName);
+        if ( !aRemovedObjIDs.count( anEntry ))
+          seqRemoved.Append(aName);
         mapRemoved.Bind(anEntry, "1");
         theObjectNames.Bind(anEntry, aName);
       }
@@ -824,52 +950,23 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   }
 
   // set initial part of aSript
-  TCollection_AsciiString initPart = "import salome, SMESH, SALOMEDS\n";
-  initPart += helper + "import " + aSmeshpy + "\n\n";
-  if ( importGeom )
+  TCollection_AsciiString initPart = "import ";
+  if ( isMultiFile )
+    initPart += helper + "salome, ";
+  initPart += aSmeshpy + ", SMESH, SALOMEDS\n";
+  if ( importGeom && isMultiFile )
   {
-    initPart += ("## import GEOM dump file ## \n"
+    initPart += ("\n## import GEOM dump file ## \n"
                  "import string, os, sys, re\n"
                  "sys.path.insert( 0, os.path.dirname(__file__) )\n"
-                 "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",__name__)+\" import *\")\n\n");
+                 "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",__name__)+\" import *\")\n");
   }
   anUpdatedScript.Insert ( 1, initPart );
 
   // add final part of aScript
-  if (aSeq->Value(aLen) < aScriptLength)
+  if (aLen && aSeq->Value(aLen) < aScriptLength)
     anUpdatedScript += aScript.SubString(aSeq->Value(aLen) + 1, aScriptLength);
 
-  // Set colors
-  SALOMEDS::SObject_var aComp = theStudy->FindComponent(ComponentDataType());
-  if( !CORBA::is_nil(aComp) )
-  {
-    SALOMEDS::ChildIterator_var Itr = theStudy->NewChildIterator(aComp);
-    for( Itr->InitEx(true); Itr->More(); Itr->Next() )
-    {
-      SALOMEDS::SObject_var aSObj = Itr->Value();
-      SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SObjectToObject( aSObj ) );
-      // mesh auto color
-      if( !CORBA::is_nil(aMesh) && aMesh->GetAutoColor() )
-      {
-        CORBA::String_var anEntry = aSObj->GetID();
-        anUpdatedScript +=
-          SMESH_Comment("\n\t") << theObjectNames(anEntry.inout()) << ".SetAutoColor(1)";
-      }
-      SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SObjectToObject(aSObj));
-      if( !CORBA::is_nil(aGroup) )
-      {
-        SALOMEDS::Color aColor = aGroup->GetColor();
-        if ( aColor.R >= 0 || aColor.G >= 0 || aColor.B >= 0 )
-        {
-          CORBA::String_var anEntry = aSObj->GetID();
-          anUpdatedScript += SMESH_Comment("\n\t")
-            << theObjectNames(anEntry.inout()) << ".SetColor(SALOMEDS.Color("
-            << aColor.R <<", "<< aColor.G <<", "<< aColor.B <<" ))";
-        }
-      }
-    }
-  }
-
   // Remove removed objects
   if ( seqRemoved.Length() > 0 ) {
     anUpdatedScript += "\n\t## some objects were removed";
@@ -886,12 +983,8 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   }
 
   // Set object names
-  anUpdatedScript += "\n\t## set object names";
-//   anUpdatedScript += "\n\t\tsmeshgui = salome.ImportComponentGUI(\"SMESH\")";
-//   anUpdatedScript += "\n\t\tsmeshgui.Init(theStudy._get_StudyId())";
-//   anUpdatedScript += "\n";
 
-  TCollection_AsciiString aGUIName;
+  TCollection_AsciiString aGUIName, aSetNameScriptPart;
   Resource_DataMapOfAsciiStringAsciiString mapEntries;
   for (Standard_Integer i = 1; i <= aLen; i += 2)
   {
@@ -899,20 +992,24 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
     aName = geom->GetDumpName( anEntry.ToCString() );
     if (aName.IsEmpty() && // Not a GEOM object
         theNames.IsBound(anEntry) &&
+        !aRemovedObjIDs.count(anEntry) && // a command creating anEntry was erased
         !mapEntries.IsBound(anEntry) && // Not yet processed
         !mapRemoved.IsBound(anEntry)) // Was not removed
     {
       aName = theObjectNames.Find(anEntry);
       aGUIName = theNames.Find(anEntry);
       mapEntries.Bind(anEntry, aName);
-      anUpdatedScript += helper + "\n\t" + aSMESHGen + ".SetName(" + aName;
+      aSetNameScriptPart += helper + "\n\t" + aSMESHGen + ".SetName(" + aName;
       if ( anEntry2AccessorMethod.IsBound( anEntry ) )
-        anUpdatedScript += helper + "." + anEntry2AccessorMethod( anEntry );
-      anUpdatedScript += helper + ", '" + aGUIName + "')";
+        aSetNameScriptPart += helper + "." + anEntry2AccessorMethod( anEntry );
+      aSetNameScriptPart += helper + ", '" + aGUIName + "')";
     }
   }
-  anUpdatedScript += "\n\tif salome.sg.hasDesktop():";
-  anUpdatedScript += "\n\t\tsalome.sg.updateObjBrowser(0)";
+  if ( !aSetNameScriptPart.IsEmpty() )
+  {
+    anUpdatedScript += "\n\t## set object names";
+    anUpdatedScript += aSetNameScriptPart;
+  }
 
   // -----------------------------------------------------------------
   // store visual properties of displayed objects
@@ -928,7 +1025,13 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
       CORBA::string_free(script);
     }
   }
-  anUpdatedScript += "\n\n\tpass\n";
+
+  if( isMultiFile )
+    anUpdatedScript += "\n\tpass";
+  anUpdatedScript += "\n";
+
+  if( !isMultiFile ) // remove unnecessary tabulation
+    RemoveTabulation( anUpdatedScript );
 
   // -----------------------------------------------------------------
   // put string literals describing patterns into separate functions
@@ -968,7 +1071,18 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
       do functionName = aFunctionType + "_" + ( nb++ ) + "()";
       while ( !functionNameSet.insert( functionName.ToCString() ).second );
 
-      anUpdatedScript += helper + "\n\ndef " + functionName + aLongString; // define function
+      // define function
+      TCollection_AsciiString funDef = helper + "def " + functionName + aLongString;
+      if ( isMultiFile )
+      {
+        anUpdatedScript += helper + "\n\n" + funDef;
+      }
+      else
+      {
+        funDef += "\n\n";
+        anUpdatedScript.Insert( 1, funDef);
+        where += funDef.Length();
+      }
     }
     anUpdatedScript.InsertBefore( where, functionName ); // call function
   }