Version: 6.3.1

src/SMESH_I/SMESH_DumpPython.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 //  File    : SMESH_DumpPython.cxx
00023 //  Created : Thu Mar 24 17:17:59 2005
00024 //  Author  : Julia DOROVSKIKH
00025 //  Module  : SMESH
00026 
00027 #include "SMESH_PythonDump.hxx"
00028 #include "SMESH_Gen_i.hxx"
00029 #include "SMESH_Filter_i.hxx"
00030 #include "SMESH_MeshEditor_i.hxx"
00031 #include "SMESH_2smeshpy.hxx"
00032 
00033 #include <TColStd_HSequenceOfInteger.hxx>
00034 #include <TCollection_AsciiString.hxx>
00035 #include <SMESH_Comment.hxx>
00036 
00037 
00038 #ifdef _DEBUG_
00039 static int MYDEBUG = 0;
00040 #else
00041 static int MYDEBUG = 0;
00042 #endif
00043 
00044 static TCollection_AsciiString NotPublishedObjectName()
00045 {
00046   return "__NOT__Published__Object__";
00047 }
00048 
00049 namespace SMESH
00050 {
00051 
00052   size_t TPythonDump::myCounter = 0;
00053 
00054   TPythonDump::
00055   TPythonDump()
00056   {
00057     ++myCounter;
00058   }
00059   TPythonDump::
00060   ~TPythonDump()
00061   {
00062     if(--myCounter == 0){
00063       SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
00064       std::string aString = myStream.str();
00065       TCollection_AsciiString aCollection(Standard_CString(aString.c_str()));
00066       SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
00067       if(!aStudy->_is_nil() && !aCollection.IsEmpty()){
00068         aSMESHGen->AddToPythonScript(aStudy->StudyId(),aCollection);
00069         if(MYDEBUG) MESSAGE(aString);
00070       }
00071     }
00072   }
00073 
00074   TPythonDump&
00075   TPythonDump::
00076   operator<<(long int theArg){
00077     myStream<<theArg;
00078     return *this;
00079   }
00080 
00081   TPythonDump&
00082   TPythonDump::
00083   operator<<(int theArg){
00084     myStream<<theArg;
00085     return *this;
00086   }
00087 
00088   TPythonDump&
00089   TPythonDump::
00090   operator<<(double theArg){
00091     myStream<<theArg;
00092     return *this;
00093   }
00094 
00095   TPythonDump&
00096   TPythonDump::
00097   operator<<(float theArg){
00098     myStream<<theArg;
00099     return *this;
00100   }
00101 
00102   TPythonDump&
00103   TPythonDump::
00104   operator<<(const void* theArg){
00105     myStream<<theArg;
00106     return *this;
00107   }
00108 
00109   TPythonDump&
00110   TPythonDump::
00111   operator<<(const char* theArg){
00112     if ( theArg )
00113       myStream<<theArg;
00114     return *this;
00115   }
00116 
00117   TPythonDump&
00118   TPythonDump::
00119   operator<<(const SMESH::ElementType& theArg)
00120   {
00121     myStream<<"SMESH.";
00122     switch(theArg){
00123     case ALL:   myStream<<"ALL";break;
00124     case NODE:  myStream<<"NODE";break;
00125     case EDGE:  myStream<<"EDGE";break;
00126     case FACE:  myStream<<"FACE";break;
00127     case VOLUME:myStream<<"VOLUME";break;
00128     }
00129     return *this;
00130   }
00131 
00132   TPythonDump&
00133   TPythonDump::
00134   operator<<(const SMESH::GeometryType& theArg)
00135   {
00136     myStream<<"SMESH.";
00137     switch(theArg){
00138     case Geom_POINT:      myStream<<"Geom_POINT";      break;
00139     case Geom_EDGE:       myStream<<"Geom_EDGE";       break;
00140     case Geom_TRIANGLE:   myStream<<"Geom_TRIANGLE";   break;
00141     case Geom_QUADRANGLE: myStream<<"Geom_QUADRANGLE"; break;
00142     case Geom_POLYGON:    myStream<<"Geom_POLYGON";    break;
00143     case Geom_TETRA:      myStream<<"Geom_TETRA";      break;
00144     case Geom_PYRAMID:    myStream<<"Geom_PYRAMID";    break;
00145     case Geom_HEXA:       myStream<<"Geom_HEXA";       break;
00146     case Geom_PENTA:      myStream<<"Geom_PENTA";      break;
00147     case Geom_POLYHEDRA:  myStream<<"Geom_POLYHEDRA";  break;
00148    }
00149     return *this;
00150   }
00151 
00152   template<class TArray>
00153   void DumpArray(const TArray& theArray, TPythonDump & theStream)
00154   {
00155     theStream << "[ ";
00156     for (int i = 1; i <= theArray.length(); i++) {
00157       theStream << theArray[i-1];
00158       if ( i < theArray.length() )
00159         theStream << ", ";
00160     }
00161     theStream << " ]";
00162   }
00163 
00164   TPythonDump&
00165   TPythonDump::operator<<(const SMESH::long_array& theArg)
00166   {
00167     DumpArray( theArg, *this );
00168     return *this;
00169   }
00170 
00171   TPythonDump&
00172   TPythonDump::operator<<(const SMESH::double_array& theArg)
00173   {
00174     DumpArray( theArg, *this );
00175     return *this;
00176   }
00177 
00178   TPythonDump&
00179   TPythonDump::
00180   operator<<(SALOMEDS::SObject_ptr aSObject)
00181   {
00182     if ( !aSObject->_is_nil() )
00183       myStream << aSObject->GetID();
00184     else
00185       myStream << NotPublishedObjectName();
00186     return *this;
00187   }
00188 
00189   TPythonDump&
00190   TPythonDump::
00191   operator<<(CORBA::Object_ptr theArg)
00192   {
00193     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
00194     SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
00195     SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
00196     if(!aSObject->_is_nil()) {
00197       CORBA::String_var id = aSObject->GetID();
00198       myStream << id;
00199     } else if ( !CORBA::is_nil(theArg)) {
00200       if ( aSMESHGen->CanPublishInStudy( theArg )) // not published SMESH object
00201         myStream << "smeshObj_" << size_t(theArg);
00202       else
00203         myStream << NotPublishedObjectName();
00204     }
00205     else
00206       myStream << "None";
00207     return *this;
00208   }
00209 
00210   TPythonDump&
00211   TPythonDump::
00212   operator<<(SMESH::SMESH_Hypothesis_ptr theArg)
00213   {
00214     SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
00215     SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
00216     if(aSObject->_is_nil() && !CORBA::is_nil(theArg))
00217       myStream << "hyp_" << theArg->GetId();
00218     else
00219       *this << CORBA::Object_ptr( theArg );
00220     return *this;
00221   }
00222 
00223   TPythonDump&
00224   TPythonDump::
00225   operator<<(SMESH::SMESH_IDSource_ptr theArg)
00226   {
00227     if ( CORBA::is_nil( theArg ) )
00228       return *this << "None";
00229     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
00230     SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
00231     SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
00232     if(!aSObject->_is_nil())
00233       return *this << aSObject;
00234     SMESH::SMESH_Mesh_var mesh = theArg->GetMesh();
00235     if ( !theArg->_is_equivalent( mesh ))
00236     {
00237       SMESH::long_array_var anElementsId = theArg->GetIDs();
00238       SMESH::array_of_ElementType_var types =  theArg->GetTypes();
00239       SMESH::ElementType type = types->length() ? types[0] : SMESH::ALL;
00240       return *this << mesh << ".GetIDSource(" << anElementsId << ", " << type << ")";
00241     }
00242     return *this;
00243   }
00244 
00245   TPythonDump&
00246   TPythonDump::
00247   operator<<(SMESH::FilterLibrary_i* theArg)
00248   {
00249     myStream<<"aFilterLibrary"<<theArg;
00250     return *this;
00251   }
00252 
00253   TPythonDump&
00254   TPythonDump::
00255   operator<<(SMESH::FilterManager_i* theArg)
00256   {
00257     myStream<<"aFilterManager";
00258     return *this;
00259   }
00260 
00261   TPythonDump&
00262   TPythonDump::
00263   operator<<(SMESH::Filter_i* theArg)
00264   {
00265     myStream<<"aFilter"<<theArg;
00266     return *this;
00267   }
00268 
00269   TPythonDump&
00270   TPythonDump::
00271   operator<<(SMESH::Functor_i* theArg)
00272   {
00273     if ( theArg ) {
00274       FunctorType aFunctorType = theArg->GetFunctorType();
00275       switch(aFunctorType){
00276       case FT_AspectRatio:           myStream<< "anAspectRatio";          break;
00277       case FT_AspectRatio3D:         myStream<< "anAspectRatio3D";        break;
00278       case FT_Warping:               myStream<< "aWarping";               break;
00279       case FT_MinimumAngle:          myStream<< "aMinimumAngle";          break;
00280       case FT_Taper:                 myStream<< "aTaper";                 break;
00281       case FT_Skew:                  myStream<< "aSkew";                  break;
00282       case FT_Area:                  myStream<< "aArea";                  break;
00283       case FT_Volume3D:              myStream<< "aVolume3D";              break;
00284       case FT_MaxElementLength2D:    myStream<< "aMaxElementLength2D";    break;
00285       case FT_MaxElementLength3D:    myStream<< "aMaxElementLength3D";    break;
00286       case FT_FreeBorders:           myStream<< "aFreeBorders";           break;
00287       case FT_FreeEdges:             myStream<< "aFreeEdges";             break;
00288       case FT_FreeNodes:             myStream<< "aFreeNodes";             break;
00289       case FT_FreeFaces:             myStream<< "aFreeFaces";             break;
00290       case FT_MultiConnection:       myStream<< "aMultiConnection";       break;
00291       case FT_MultiConnection2D:     myStream<< "aMultiConnection2D";     break;
00292       case FT_Length:                myStream<< "aLength";                break;
00293       case FT_Length2D:              myStream<< "aLength2D";              break;
00294       case FT_BelongToGeom:          myStream<< "aBelongToGeom";          break;
00295       case FT_BelongToPlane:         myStream<< "aBelongToPlane";         break;
00296       case FT_BelongToCylinder:      myStream<< "aBelongToCylinder";      break;
00297       case FT_BelongToGenSurface:    myStream<< "aBelongToGenSurface";    break;
00298       case FT_LyingOnGeom:           myStream<< "aLyingOnGeom";           break;
00299       case FT_CoplanarFaces:         myStream<< "aCoplanarFaces";         break;
00300       case FT_RangeOfIds:            myStream<< "aRangeOfIds";            break;
00301       case FT_BadOrientedVolume:     myStream<< "aBadOrientedVolume";     break;
00302       case FT_BareBorderVolume:      myStream<< "aBareBorderVolume";      break;
00303       case FT_BareBorderFace:        myStream<< "aBareBorderFace";        break;
00304       case FT_OverConstrainedVolume: myStream<< "aOverConstrainedVolume"; break;
00305       case FT_OverConstrainedFace:   myStream<< "aOverConstrainedFace";   break;
00306       case FT_LinearOrQuadratic:     myStream<< "aLinearOrQuadratic";     break;
00307       case FT_GroupColor:            myStream<< "aGroupColor";            break;
00308       case FT_ElemGeomType:          myStream<< "anElemGeomType";         break;
00309       case FT_LessThan:              myStream<< "aLessThan";              break;
00310       case FT_MoreThan:              myStream<< "aMoreThan";              break;
00311       case FT_EqualTo:               myStream<< "anEqualTo";              break;
00312       case FT_LogicalNOT:            myStream<< "aLogicalNOT";            break;
00313       case FT_LogicalAND:            myStream<< "aLogicalAND";            break;
00314       case FT_LogicalOR:             myStream<< "aLogicalOR";             break;
00315       case FT_Undefined:
00316       default:                       myStream<< "anUndefined";            break;
00317       }
00318       myStream<<theArg;
00319     }
00320     return *this;
00321   }
00322 
00323   TPythonDump&
00324   TPythonDump::
00325   operator<<(SMESH::Measurements_i* theArg)
00326   {
00327     myStream<<"aMeasurements";
00328     return *this;
00329   }
00330 
00331 
00332   TPythonDump& TPythonDump:: operator<<(SMESH_Gen_i* theArg)
00333   {
00334     myStream << SMESHGenName(); return *this;
00335   }
00336 
00337   TPythonDump& TPythonDump::operator<<(SMESH_MeshEditor_i* theArg)
00338   {
00339     myStream << MeshEditorName() << "_" << ( theArg ? theArg->GetMeshId() : -1 ); return *this;
00340   }
00341 
00342   TPythonDump& TPythonDump::operator<<(const TCollection_AsciiString & theStr)
00343   {
00344     myStream << theStr; return *this;
00345   }
00346 
00347 
00348   TPythonDump& TPythonDump::operator<<(SMESH::MED_VERSION theVersion)
00349   {
00350     switch (theVersion) {
00351     case SMESH::MED_V2_1: myStream << "SMESH.MED_V2_1"; break;
00352     case SMESH::MED_V2_2: myStream << "SMESH.MED_V2_2"; break;
00353     default: myStream << theVersion;
00354     }
00355     return *this;
00356   }
00357 
00358   TPythonDump& TPythonDump::operator<<(const SMESH::AxisStruct & theAxis)
00359   {
00360     myStream << "SMESH.AxisStruct( "
00361              << theAxis.x  << ", "
00362              << theAxis.y  << ", "
00363              << theAxis.z  << ", "
00364              << theAxis.vx << ", "
00365              << theAxis.vy << ", "
00366              << theAxis.vz << " )";
00367     return *this;
00368   }
00369 
00370   TPythonDump& TPythonDump::operator<<(const SMESH::DirStruct & theDir)
00371   {
00372     const SMESH::PointStruct & P = theDir.PS;
00373     myStream << "SMESH.DirStruct( SMESH.PointStruct ( "
00374              << P.x  << ", "
00375              << P.y  << ", "
00376              << P.z  << " ))";
00377     return *this;
00378   }
00379 
00380   TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups& theList)
00381   {
00382     DumpArray( theList, *this );
00383     return *this;
00384   }
00385   TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups * theList)
00386   {
00387     DumpArray( *theList, *this );
00388     return *this;
00389   }
00390   TPythonDump& TPythonDump::operator<<(const SMESH::ListOfIDSources& theList)
00391   {
00392     DumpArray( theList, *this );
00393     return *this;
00394   }
00395 
00396   TCollection_AsciiString myLongStringStart( "TPythonDump::LongStringStart" );
00397   TCollection_AsciiString myLongStringEnd  ( "TPythonDump::LongStringEnd" );
00398 
00399   //================================================================================
00406   //================================================================================
00407 
00408   TCollection_AsciiString TPythonDump::LongStringStart(const char* type)
00409   {
00410     return
00411       myLongStringStart +
00412       (Standard_Integer) strlen(type) +
00413       " " +
00414       (char*) type;
00415   }
00416 
00417   //================================================================================
00423   //================================================================================
00424 
00425   TCollection_AsciiString TPythonDump::LongStringEnd()
00426   {
00427     return myLongStringEnd;
00428   }
00429 
00430   //================================================================================
00442   //================================================================================
00443 
00444   bool  TPythonDump::CutoutLongString( TCollection_AsciiString & theText,
00445                                        int                     & theFrom,
00446                                        TCollection_AsciiString & theLongString,
00447                                        TCollection_AsciiString & theStringType)
00448   {
00449     if ( theFrom < 1 || theFrom > theText.Length() )
00450       return false;
00451 
00452     // ...script \  beg marker    \ \ type \       literal              \  end marker  \ script...
00453     //  "theText myLongStringStart7 Pattern!!! SALOME Mesh Pattern file myLongStringEndtextEnd"
00454     //  012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
00455     //  0         1         2         3         4         5         6         7         8
00456 
00457     theFrom = theText.Location( myLongStringStart, theFrom, theText.Length() ); // = 09
00458     if ( !theFrom )
00459       return false;
00460 
00461     // find where literal begins
00462     int literalBeg = theFrom + myLongStringStart.Length(); // = 26
00463     char* typeLenStr = (char*) theText.ToCString() + literalBeg - 1; // = "7 Pattern!!! SALO...."
00464     int typeLen = atoi ( typeLenStr ); // = 7
00465     while ( *typeLenStr != ' ' ) { // look for ' ' after typeLen
00466       literalBeg++; // 26 -> 27
00467       typeLenStr++;
00468     }
00469     literalBeg += typeLen + 1; // = 35
00470     if ( literalBeg > theText.Length() )
00471       return false;
00472 
00473     // where literal ends (i.e. end marker begins)
00474     int literalEnd = theText.Location( myLongStringEnd, literalBeg, theText.Length() ); // = 64
00475     if ( !literalEnd )
00476       literalEnd = theText.Length();
00477 
00478     // literal
00479     theLongString = theText.SubString( literalBeg, literalEnd - 1); // "!!! SALOME Mesh Pattern file "
00480     // type
00481     theStringType = theText.SubString( literalBeg - typeLen, literalBeg - 1 ); // "Pattern"
00482     // cut off literal
00483     literalEnd += myLongStringEnd.Length(); // = 79
00484     TCollection_AsciiString textEnd = theText.SubString( literalEnd, theText.Length() ); // "textE..."
00485     theText = theText.SubString( 1, theFrom - 1 ) + textEnd;
00486 
00487     return true;
00488   }
00489 }
00490 
00491 //=======================================================================
00492 //function : RemoveTabulation
00493 //purpose  : 
00494 //=======================================================================
00495 void RemoveTabulation( TCollection_AsciiString& theScript )
00496 {
00497   std::string aString( theScript.ToCString() );
00498   std::string::size_type aPos = 0;
00499   while( aPos < aString.length() )
00500   {
00501     aPos = aString.find( "\n\t", aPos );
00502     if( aPos == std::string::npos )
00503       break;
00504     aString.replace( aPos, 2, "\n" );
00505     aPos++;
00506   }
00507   theScript = aString.c_str();
00508 }
00509 
00510 //=======================================================================
00511 //function : DumpPython
00512 //purpose  :
00513 //=======================================================================
00514 Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
00515                                            CORBA::Boolean isPublished,
00516                                            CORBA::Boolean isMultiFile,
00517                                            CORBA::Boolean& isValidScript)
00518 {
00519   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
00520   if (CORBA::is_nil(aStudy))
00521     return new Engines::TMPFile(0);
00522 
00523   SALOMEDS::SObject_var aSO = aStudy->FindComponent(ComponentDataType());
00524   if (CORBA::is_nil(aSO))
00525     return new Engines::TMPFile(0);
00526 
00527   // Map study entries to object names
00528   Resource_DataMapOfAsciiStringAsciiString aMap;
00529   Resource_DataMapOfAsciiStringAsciiString aMapNames;
00530   //TCollection_AsciiString s ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_");
00531 
00532   SALOMEDS::ChildIterator_var Itr = aStudy->NewChildIterator(aSO);
00533   for (Itr->InitEx(true); Itr->More(); Itr->Next()) {
00534     SALOMEDS::SObject_var aValue = Itr->Value();
00535     CORBA::String_var anID = aValue->GetID();
00536     CORBA::String_var aName = aValue->GetName();
00537     TCollection_AsciiString aGUIName ( (char*) aName.in() );
00538     TCollection_AsciiString anEnrty ( (char*) anID.in() );
00539     if (aGUIName.Length() > 0) {
00540       aMapNames.Bind( anEnrty, aGUIName );
00541       aMap.Bind( anEnrty, aGUIName );
00542     }
00543   }
00544 
00545   // Get trace of restored study
00546   //SALOMEDS::SObject_var aSO = SMESH_Gen_i::ObjectToSObject(theStudy, _this());
00547   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
00548   SALOMEDS::GenericAttribute_var anAttr =
00549     aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
00550 
00551   char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
00552   TCollection_AsciiString aSavedTrace (oldValue);
00553 
00554   // Add trace of API methods calls and replace study entries by names
00555   TCollection_AsciiString aScript;
00556   aScript += DumpPython_impl(aStudy, aMap, aMapNames,
00557                              isPublished, isMultiFile, isValidScript, aSavedTrace);
00558 
00559   int aLen = aScript.Length();
00560   unsigned char* aBuffer = new unsigned char[aLen+1];
00561   strcpy((char*)aBuffer, aScript.ToCString());
00562 
00563   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
00564   Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1);
00565 
00566   bool hasNotPublishedObjects = aScript.Location( NotPublishedObjectName(), 1, aLen);
00567   isValidScript = isValidScript && !hasNotPublishedObjects;
00568 
00569   return aStreamFile._retn();
00570 }
00571 
00572 //=============================================================================
00576 //=============================================================================
00577 void SMESH_Gen_i::AddToPythonScript (int theStudyID, const TCollection_AsciiString& theString)
00578 {
00579   if (myPythonScripts.find(theStudyID) == myPythonScripts.end()) {
00580     myPythonScripts[theStudyID] = new TColStd_HSequenceOfAsciiString;
00581   }
00582   myPythonScripts[theStudyID]->Append(theString);
00583 }
00584 
00585 //=============================================================================
00589 //=============================================================================
00590 void SMESH_Gen_i::RemoveLastFromPythonScript (int theStudyID)
00591 {
00592   if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
00593     int aLen = myPythonScripts[theStudyID]->Length();
00594     myPythonScripts[theStudyID]->Remove(aLen);
00595   }
00596 }
00597 
00598 //=======================================================================
00599 //function : SavePython
00600 //purpose  :
00601 //=======================================================================
00602 void SMESH_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy)
00603 {
00604   // Dump trace of API methods calls
00605   TCollection_AsciiString aScript = GetNewPythonLines(theStudy->StudyId());
00606 
00607   // Check contents of PythonObject attribute
00608   SALOMEDS::SObject_var aSO = theStudy->FindComponent(ComponentDataType());
00609   //SALOMEDS::SObject_var aSO = SMESH_Gen_i::ObjectToSObject(theStudy, _this());
00610   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
00611   SALOMEDS::GenericAttribute_var anAttr =
00612     aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
00613 
00614   char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
00615   TCollection_AsciiString oldScript (oldValue);
00616 
00617   if (oldScript.Length() > 0) {
00618     oldScript += "\n";
00619     oldScript += aScript;
00620   } else {
00621     oldScript = aScript;
00622   }
00623 
00624   // Store in PythonObject attribute
00625   SALOMEDS::AttributePythonObject::_narrow(anAttr)->SetObject(oldScript.ToCString(), 1);
00626 
00627   // Clean trace of API methods calls
00628   CleanPythonTrace(theStudy->StudyId());
00629 }
00630 
00631 
00632 // impl
00633 
00634 
00635 //=============================================================================
00639 //=============================================================================
00640 Handle(TColStd_HSequenceOfInteger) FindEntries (TCollection_AsciiString& theString)
00641 {
00642   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
00643   Standard_Integer aLen = theString.Length();
00644   Standard_Boolean isFound = Standard_False;
00645 
00646   char* arr = (char*) theString.ToCString();
00647   Standard_Integer i = 0, j;
00648 
00649   while(i < aLen) {
00650     int c = (int)arr[i];
00651     j = i+1;
00652     if ( isdigit( c )) { //Is digit?
00653 
00654       isFound = Standard_False;
00655       while((j < aLen) && ( isdigit(c) || c == ':' )) { //Check if it is an entry
00656         c = (int)arr[j++];
00657         if(c == ':') isFound = Standard_True;
00658       }
00659 
00660       if (isFound) {
00661         int prev = (i < 1) ? 0 : (int)arr[i - 1];
00662         // to distinguish from a sketcher command:
00663         // last char should be a digit, not ":",
00664         // previous char should not be '"'.
00665         if (arr[j-2] != ':' && prev != '"') {
00666           aSeq->Append(i+1); // +1 because AsciiString starts from 1
00667           aSeq->Append(j-1);
00668         }
00669       }
00670     }
00671 
00672     i = j;
00673   }
00674 
00675   return aSeq;
00676 }
00677 
00678 namespace {
00679 
00680   //================================================================================
00686   //================================================================================
00687 
00688   bool fixPythonName(TCollection_AsciiString & aName )
00689   {
00690     const TCollection_AsciiString allowedChars =
00691       "qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_";
00692     bool isValidName = true;
00693     int p=1; // replace not allowed chars with underscore
00694     while (p <= aName.Length() &&
00695            (p = aName.FirstLocationNotInSet(allowedChars, p, aName.Length())))
00696     {
00697       if ( p == 1 || p == aName.Length() || aName.Value(p-1) == '_')
00698         aName.Remove( p, 1 ); // remove double _ and from the start and the end
00699       else
00700         aName.SetValue(p, '_');
00701       isValidName = false;
00702     }
00703     if ( aName.IsIntegerValue() ) { // aName must not start with a digit
00704       aName.Insert( 1, 'a' );
00705       isValidName = false;
00706     }
00707     return isValidName;
00708   }
00709 }
00710 
00711 //=============================================================================
00715 //=============================================================================
00716 TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
00717                         (SALOMEDS::Study_ptr theStudy,
00718                          Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
00719                          Resource_DataMapOfAsciiStringAsciiString& theNames,
00720                          bool isPublished,
00721                          bool isMultiFile,
00722                          bool& aValidScript,
00723                          const TCollection_AsciiString& theSavedTrace)
00724 {
00725   int aStudyID = theStudy->StudyId();
00726 
00727   TCollection_AsciiString helper; // to comfortably concatenate C strings
00728   TCollection_AsciiString aSmeshpy( SMESH_2smeshpy::SmeshpyName() );
00729   TCollection_AsciiString aSMESHGen( SMESH_2smeshpy::GenName() );
00730   TCollection_AsciiString anOldGen( SMESH::TPythonDump::SMESHGenName() );
00731 
00732   TCollection_AsciiString aScript;
00733   if( isMultiFile )
00734     aScript += "def RebuildData(theStudy):";
00735   aScript += "\n\t";
00736   aScript += helper + "aFilterManager = " + aSMESHGen + ".CreateFilterManager()\n\t";
00737   aScript += helper + "aMeasurements = " + aSMESHGen + ".CreateMeasurements()\n\t";
00738   if ( isPublished )
00739     aScript += aSMESHGen + ".SetCurrentStudy(theStudy)";
00740   else
00741     aScript += aSMESHGen + ".SetCurrentStudy(None)";
00742 
00743   // import python files corresponding to plugins
00744   set<string> moduleNameSet;
00745   map<string, GenericHypothesisCreator_i*>::iterator hyp_creator = myHypCreatorMap.begin();
00746   for ( ; hyp_creator != myHypCreatorMap.end(); ++hyp_creator ) {
00747     string moduleName = hyp_creator->second->GetModuleName();
00748     bool newModule = moduleNameSet.insert( moduleName ).second;
00749     if ( newModule )
00750       aScript += helper + "\n\t" + "import " + (char*) moduleName.c_str();
00751   }
00752 
00753   // Dump trace of restored study
00754   if (theSavedTrace.Length() > 0) {
00755     // For the convertion of IDL API calls -> smesh.py API, "smesh" standing for SMESH_Gen
00756     // was replaces with "smeshgen" (==TPythonDump::SMESHGenName()).
00757     // Change "smesh" -> "smeshgen" in the trace saved before passage to smesh.py API
00758     bool isNewVersion =
00759       theSavedTrace.Location( anOldGen + ".", 1, theSavedTrace.Length() );
00760     if ( !isNewVersion ) {
00761       TCollection_AsciiString aSavedTrace( theSavedTrace );
00762       TCollection_AsciiString aSmeshCall ( "smesh." ), gen( "gen" );
00763       int beg, end = aSavedTrace.Length(), from = 1;
00764       while ( from < end && ( beg = aSavedTrace.Location( aSmeshCall, from, end ))) {
00765         char charBefore = ( beg == 1 ) ? ' ' : aSavedTrace.Value( beg - 1 );
00766         if ( isspace( charBefore ) || charBefore == '=' ) { // "smesh." is not a part of a long word
00767           aSavedTrace.Insert( beg + aSmeshCall.Length() - 1, gen );// "smesh" -> "smeshgen"
00768           end += gen.Length();
00769         }
00770         from = beg + aSmeshCall.Length();
00771       }
00772       aScript += helper + "\n" + aSavedTrace;
00773     }
00774     else
00775       // append a saved trace to the script
00776       aScript += helper + "\n" + theSavedTrace;
00777   }
00778 
00779   // Dump trace of API methods calls
00780   TCollection_AsciiString aNewLines = GetNewPythonLines(aStudyID);
00781   if (aNewLines.Length() > 0) {
00782     aScript += helper + "\n" + aNewLines;
00783   }
00784 
00785   // Convert IDL API calls into smesh.py API.
00786   // Some objects are wrapped with python classes and
00787   // Resource_DataMapOfAsciiStringAsciiString holds methods returning wrapped objects
00788   Resource_DataMapOfAsciiStringAsciiString anEntry2AccessorMethod;
00789   aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod, theObjectNames );
00790 
00791   // Find entries to be replaced by names
00792   Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript);
00793   Standard_Integer aLen = aSeq->Length();
00794 
00795   if (aLen == 0)
00796     return aScript;
00797 
00798   // Replace entries by the names
00799   GEOM::GEOM_Gen_ptr geom = GetGeomEngine();
00800   TColStd_SequenceOfAsciiString seqRemoved;
00801   Resource_DataMapOfAsciiStringAsciiString mapRemoved;
00802   Standard_Integer objectCounter = 0, aStart = 1, aScriptLength = aScript.Length();
00803   TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("smeshObj_");
00804 
00805   // Collect names of GEOM objects to exclude same names for SMESH objects
00806   GEOM::string_array_var aGeomNames = geom->GetAllDumpNames();
00807   int ign = 0, nbgn = aGeomNames->length();
00808   for (; ign < nbgn; ign++) {
00809     aName = aGeomNames[ign];
00810     theObjectNames.Bind(aName, "1");
00811   }
00812 
00813   bool importGeom = false;
00814   for (Standard_Integer i = 1; i <= aLen; i += 2) {
00815     anUpdatedScript += aScript.SubString(aStart, aSeq->Value(i) - 1);
00816     anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1));
00817     // is a GEOM object?
00818     aName = geom->GetDumpName( anEntry.ToCString() );
00819     if (aName.IsEmpty()) {
00820       // is a SMESH object
00821       if (theObjectNames.IsBound(anEntry)) {
00822         // The Object is in Study
00823         aName = theObjectNames.Find(anEntry);
00824         // check validity of aName
00825         bool isValidName = fixPythonName( aName );
00826         if (theObjectNames.IsBound(aName) && anEntry != theObjectNames(aName)) {
00827           // diff objects have same name - make a new name by appending a digit
00828           TCollection_AsciiString aName2;
00829           Standard_Integer i = 0;
00830           do {
00831             aName2 = aName + "_" + ++i;
00832           } while (theObjectNames.IsBound(aName2) && anEntry != theObjectNames(aName2));
00833           aName = aName2;
00834           isValidName = false;
00835         }
00836         if ( !isValidName )
00837           theObjectNames(anEntry) = aName;
00838 
00839       } else {
00840         // Removed Object
00841         do {
00842           aName = aBaseName + (++objectCounter);
00843         } while (theObjectNames.IsBound(aName));
00844         seqRemoved.Append(aName);
00845         mapRemoved.Bind(anEntry, "1");
00846         theObjectNames.Bind(anEntry, aName);
00847       }
00848       theObjectNames.Bind(aName, anEntry); // to detect same name of diff objects
00849     }
00850     else
00851     {
00852       importGeom = true;
00853     }
00854     anUpdatedScript += aName;
00855     aStart = aSeq->Value(i + 1) + 1;
00856   }
00857 
00858   // set initial part of aSript
00859   TCollection_AsciiString initPart = "import ";
00860   if ( isMultiFile )
00861     initPart += helper + "salome, ";
00862   initPart += aSmeshpy + ", SMESH, SALOMEDS\n";
00863   if ( importGeom && isMultiFile )
00864   {
00865     initPart += ("\n## import GEOM dump file ## \n"
00866                  "import string, os, sys, re\n"
00867                  "sys.path.insert( 0, os.path.dirname(__file__) )\n"
00868                  "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",__name__)+\" import *\")\n");
00869   }
00870   anUpdatedScript.Insert ( 1, initPart );
00871 
00872   // add final part of aScript
00873   if (aSeq->Value(aLen) < aScriptLength)
00874     anUpdatedScript += aScript.SubString(aSeq->Value(aLen) + 1, aScriptLength);
00875 
00876   // Remove removed objects
00877   if ( seqRemoved.Length() > 0 ) {
00878     anUpdatedScript += "\n\t## some objects were removed";
00879     anUpdatedScript += "\n\taStudyBuilder = theStudy.NewBuilder()";
00880   }
00881   for (int ir = 1; ir <= seqRemoved.Length(); ir++) {
00882     anUpdatedScript += "\n\tSO = theStudy.FindObjectIOR(theStudy.ConvertObjectToIOR(";
00883     anUpdatedScript += seqRemoved.Value(ir);
00884     // for object wrapped by class of smesh.py
00885     anEntry = theObjectNames( seqRemoved.Value(ir) );
00886     if ( anEntry2AccessorMethod.IsBound( anEntry ) )
00887       anUpdatedScript += helper + "." + anEntry2AccessorMethod( anEntry );
00888     anUpdatedScript += "))\n\tif SO is not None: aStudyBuilder.RemoveObjectWithChildren(SO)";
00889   }
00890 
00891   // Set object names
00892   anUpdatedScript += "\n\t## set object names";
00893 //   anUpdatedScript += "\n\t\tsmeshgui = salome.ImportComponentGUI(\"SMESH\")";
00894 //   anUpdatedScript += "\n\t\tsmeshgui.Init(theStudy._get_StudyId())";
00895 //   anUpdatedScript += "\n";
00896 
00897   TCollection_AsciiString aGUIName;
00898   Resource_DataMapOfAsciiStringAsciiString mapEntries;
00899   for (Standard_Integer i = 1; i <= aLen; i += 2)
00900   {
00901     anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1));
00902     aName = geom->GetDumpName( anEntry.ToCString() );
00903     if (aName.IsEmpty() && // Not a GEOM object
00904         theNames.IsBound(anEntry) &&
00905         !mapEntries.IsBound(anEntry) && // Not yet processed
00906         !mapRemoved.IsBound(anEntry)) // Was not removed
00907     {
00908       aName = theObjectNames.Find(anEntry);
00909       aGUIName = theNames.Find(anEntry);
00910       mapEntries.Bind(anEntry, aName);
00911       anUpdatedScript += helper + "\n\t" + aSMESHGen + ".SetName(" + aName;
00912       if ( anEntry2AccessorMethod.IsBound( anEntry ) )
00913         anUpdatedScript += helper + "." + anEntry2AccessorMethod( anEntry );
00914       anUpdatedScript += helper + ", '" + aGUIName + "')";
00915     }
00916   }
00917 
00918   // Issue 0021249: removed (a similar block is dumped by SALOMEDSImpl_Study)
00919   //anUpdatedScript += "\n\tif salome.sg.hasDesktop():";
00920   //anUpdatedScript += "\n\t\tsalome.sg.updateObjBrowser(0)";
00921 
00922   // -----------------------------------------------------------------
00923   // store visual properties of displayed objects
00924   // -----------------------------------------------------------------
00925 
00926   if (isPublished)
00927   {
00928     //Output the script that sets up the visual parameters.
00929     char* script = theStudy->GetDefaultScript(ComponentDataType(), "\t");
00930     if (script && strlen(script) > 0) {
00931       anUpdatedScript += "\n\n\t### Store presentation parameters of displayed objects\n";
00932       anUpdatedScript += script;
00933       CORBA::string_free(script);
00934     }
00935   }
00936 
00937   if( isMultiFile )
00938     anUpdatedScript += "\n\tpass";
00939   anUpdatedScript += "\n";
00940 
00941   if( !isMultiFile ) // remove unnecessary tabulation
00942     RemoveTabulation( anUpdatedScript );
00943 
00944   // -----------------------------------------------------------------
00945   // put string literals describing patterns into separate functions
00946   // -----------------------------------------------------------------
00947 
00948   TCollection_AsciiString aLongString, aFunctionType;
00949   int where = 1;
00950   set< string > functionNameSet;
00951   while ( SMESH::TPythonDump::CutoutLongString( anUpdatedScript, where, aLongString, aFunctionType ))
00952   {
00953     // make a python string literal
00954     aLongString.Prepend(":\n\treturn '''\n");
00955     aLongString += "\n\t'''\n\tpass\n";
00956 
00957     TCollection_AsciiString functionName;
00958 
00959     // check if the function returning this literal is already defined
00960     int posAlready = anUpdatedScript.Location( aLongString, where, anUpdatedScript.Length() );
00961     if ( posAlready ) // already defined
00962     {
00963       // find the function name
00964       int functBeg = posAlready;
00965       char* script = (char*) anUpdatedScript.ToCString() + posAlready - 1; // look at ":" after "def fuction()"
00966       while ( *script != ' ' ) {
00967         script--;
00968         functBeg--;
00969       }
00970       functBeg++; // do not take ' '
00971       posAlready--; // do not take ':'
00972       functionName = anUpdatedScript.SubString( functBeg, posAlready );
00973     }
00974     else // not defined yet
00975     {
00976       // find a unique function name
00977       fixPythonName( aFunctionType );
00978       Standard_Integer nb = 0;
00979       do functionName = aFunctionType + "_" + ( nb++ ) + "()";
00980       while ( !functionNameSet.insert( functionName.ToCString() ).second );
00981 
00982       // define function
00983       TCollection_AsciiString funDef = helper + "def " + functionName + aLongString;
00984       if ( isMultiFile )
00985       {
00986         anUpdatedScript += helper + "\n\n" + funDef;
00987       }
00988       else
00989       {
00990         funDef += "\n\n";
00991         anUpdatedScript.Insert( 1, funDef);
00992         where += funDef.Length();
00993       }
00994     }
00995     anUpdatedScript.InsertBefore( where, functionName ); // call function
00996   }
00997 
00998   aValidScript = true;
00999 
01000   return anUpdatedScript;
01001 }
01002 
01003 //=============================================================================
01007 //=============================================================================
01008 TCollection_AsciiString SMESH_Gen_i::GetNewPythonLines (int theStudyID)
01009 {
01010   TCollection_AsciiString aScript;
01011 
01012   // Dump trace of API methods calls
01013   if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
01014     Handle(TColStd_HSequenceOfAsciiString) aPythonScript = myPythonScripts[theStudyID];
01015     Standard_Integer istr, aLen = aPythonScript->Length();
01016     for (istr = 1; istr <= aLen; istr++) {
01017       aScript += "\n\t";
01018       aScript += aPythonScript->Value(istr);
01019     }
01020     aScript += "\n";
01021   }
01022 
01023   return aScript;
01024 }
01025 
01026 //=============================================================================
01030 //=============================================================================
01031 void SMESH_Gen_i::CleanPythonTrace (int theStudyID)
01032 {
01033   TCollection_AsciiString aScript;
01034 
01035   // Clean trace of API methods calls
01036   if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
01037     myPythonScripts[theStudyID]->Clear();
01038   }
01039 }
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS