Salome HOME
SMH: Preparation version 3.0.0 - merge (HEAD+POLYWORK)
[modules/smesh.git] / src / SMESH_I / SMESH_DumpPython.cxx
1 // File    : SMESH_Gen_i_DumpPython.cxx
2 // Created : Thu Mar 24 17:17:59 2005
3 // Author  : Julia DOROVSKIKH
4 // Module  : SMESH
5 // $Header : $
6
7 #include "SMESH_PythonDump.hxx"
8 #include "SMESH_Gen_i.hxx"
9 #include "SMESH_Filter_i.hxx"
10
11 #include <TColStd_HSequenceOfInteger.hxx>
12 #include <TCollection_AsciiString.hxx>
13
14
15 #ifdef _DEBUG_
16 static int MYDEBUG = 0;
17 #else
18 static int MYDEBUG = 0;
19 #endif
20
21 static TCollection_AsciiString NotPublishedObjectName()
22 {
23   return "__NOT__Published__Object__";
24 }
25
26 namespace SMESH
27 {
28
29   size_t TPythonDump::myCounter = 0;
30
31   TPythonDump::
32   TPythonDump()
33   {
34     ++myCounter;
35   }
36   TPythonDump::
37   ~TPythonDump()
38   {
39     if(--myCounter == 0){
40       SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
41       SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
42       if(!aStudy->_is_nil()){
43         std::string aString = myStream.str();
44         TCollection_AsciiString aCollection(Standard_CString(aString.c_str()));
45         aSMESHGen->AddToPythonScript(aStudy->StudyId(),aCollection);
46         if(MYDEBUG) MESSAGE(aString);
47       }
48     }
49   }
50
51   TPythonDump& 
52   TPythonDump::
53   operator<<(long int theArg){
54     myStream<<theArg;
55     return *this;
56   }
57
58   TPythonDump& 
59   TPythonDump::
60   operator<<(int theArg){
61     myStream<<theArg;
62     return *this;
63   }
64
65   TPythonDump& 
66   TPythonDump::
67   operator<<(double theArg){
68     myStream<<theArg;
69     return *this;
70   }
71
72   TPythonDump& 
73   TPythonDump::
74   operator<<(float theArg){
75     myStream<<theArg;
76     return *this;
77   }
78
79   TPythonDump& 
80   TPythonDump::
81   operator<<(const void* theArg){
82     myStream<<theArg;
83     return *this;
84   }
85
86   TPythonDump& 
87   TPythonDump::
88   operator<<(const char* theArg){
89     myStream<<theArg;
90     return *this;
91   }
92
93   TPythonDump& 
94   TPythonDump::
95   operator<<(const SMESH::ElementType& theArg)
96   {
97     myStream<<"SMESH.";
98     switch(theArg){
99     case ALL: 
100       myStream<<"ALL"; 
101       break;
102     case NODE: 
103       myStream<<"NODE"; 
104       break;
105     case EDGE: 
106       myStream<<"EDGE"; 
107       break;
108     case FACE: 
109       myStream<<"FACE"; 
110       break;
111     case VOLUME: 
112       myStream<<"VOLUME"; 
113       break;
114     }
115     return *this;
116   }
117
118
119   TPythonDump& 
120   TPythonDump::
121   operator<<(const SMESH::long_array& theArg)
122   {
123     myStream<<"[ ";
124     CORBA::Long i = 1, iEnd = theArg.length();
125     for(; i <= iEnd; i++) {
126       myStream<<theArg[i-1];
127       if(i < iEnd)
128         myStream<< ", ";
129     }
130     myStream<<" ]";
131     return *this;
132   }
133
134
135   TPythonDump& 
136   TPythonDump::
137   operator<<(CORBA::Object_ptr theArg)
138   {
139     TCollection_AsciiString aString("None");
140     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
141     SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
142     SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
143     if(!aSObject->_is_nil()){
144       aString = aSObject->GetID();
145     }else if(!CORBA::is_nil(theArg)){
146       aString = "smeshObj_";
147       if ( aSMESHGen->CanPublishInStudy( theArg )) // not published SMESH object
148         aString += (int) theArg;
149       else
150         aString = NotPublishedObjectName();
151     }
152     myStream<<aString.ToCString();
153     return *this;
154   }
155
156   TPythonDump& 
157   TPythonDump::
158   operator<<(SMESH::FilterLibrary_i* theArg)
159   {
160     myStream<<"aFilterLibrary"<<theArg;
161     return *this;
162   }
163
164   TPythonDump& 
165   TPythonDump::
166   operator<<(SMESH::FilterManager_i* theArg)
167   {
168     myStream<<"aFilterManager";
169     return *this;
170   }
171
172   TPythonDump& 
173   TPythonDump::
174   operator<<(SMESH::Filter_i* theArg)
175   {
176     myStream<<"aFilter"<<theArg;
177     return *this;
178   }
179
180   TPythonDump& 
181   TPythonDump::
182   operator<<(SMESH::Functor_i* theArg)
183   {
184     FunctorType aFunctorType = theArg->GetFunctorType();
185     switch(aFunctorType){
186     case FT_AspectRatio:
187       myStream<<"anAspectRatio";
188       break;
189     case FT_AspectRatio3D:
190       myStream<<"anAspectRatio3D";
191       break;
192     case FT_Warping:
193       myStream<<"aWarping";
194       break;
195     case FT_MinimumAngle:
196       myStream<<"aMinimumAngle";
197       break;
198     case FT_Taper:
199       myStream<<"aTaper";
200       break;
201     case FT_Skew:
202       myStream<<"aSkew";
203       break;
204     case FT_Area:
205       myStream<<"aArea";
206       break;
207     case FT_FreeBorders:
208       myStream<<"aFreeBorders";
209       break;
210     case FT_FreeEdges:
211       myStream<<"aFreeEdges";
212       break;
213     case FT_MultiConnection:
214       myStream<<"aMultiConnection";
215       break;
216     case FT_MultiConnection2D:
217       myStream<<"aMultiConnection2D";
218       break;
219     case FT_Length:
220       myStream<<"aLength";
221       break;
222     case FT_Length2D:
223       myStream<<"aLength";
224       break;
225     case FT_BelongToGeom:
226       myStream<<"aBelongToGeom";
227       break;
228     case FT_BelongToPlane:
229       myStream<<"aBelongToPlane";
230       break;
231     case FT_BelongToCylinder:
232       myStream<<"aBelongToCylinder";
233       break;
234     case FT_LyingOnGeom:
235       myStream<<"aLyingOnGeom";
236       break;
237     case FT_RangeOfIds:
238       myStream<<"aRangeOfIds";
239       break;
240     case FT_BadOrientedVolume:
241       myStream<<"aBadOrientedVolume";
242       break;
243     case FT_LessThan:
244       myStream<<"aLessThan";
245       break;
246     case FT_MoreThan:
247       myStream<<"aMoreThan";
248       break;
249     case FT_EqualTo:
250       myStream<<"anEqualTo";
251       break;
252     case FT_LogicalNOT:
253       myStream<<"aLogicalNOT";
254       break;
255     case FT_LogicalAND:
256       myStream<<"aLogicalAND";
257       break;
258     case FT_LogicalOR:
259       myStream<<"aLogicalOR";
260       break;
261     case FT_Undefined:
262       myStream<<"anUndefined";
263       break;
264     }
265     myStream<<theArg;
266     return *this;
267   }
268 }
269
270 //=======================================================================
271 //function : DumpPython
272 //purpose  : 
273 //=======================================================================
274 Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
275                                            CORBA::Boolean isPublished,
276                                            CORBA::Boolean& isValidScript)
277 {
278   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
279   if (CORBA::is_nil(aStudy))
280     return new Engines::TMPFile(0);
281
282   SALOMEDS::SObject_var aSO = aStudy->FindComponent(ComponentDataType());
283   if (CORBA::is_nil(aSO))
284     return new Engines::TMPFile(0);
285
286   // Map study entries to object names
287   Resource_DataMapOfAsciiStringAsciiString aMap;
288   Resource_DataMapOfAsciiStringAsciiString aMapNames;
289   TCollection_AsciiString s ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_");
290
291   SALOMEDS::ChildIterator_var Itr = aStudy->NewChildIterator(aSO);
292   for (Itr->InitEx(true); Itr->More(); Itr->Next()) {
293     SALOMEDS::SObject_var aValue = Itr->Value();
294     CORBA::String_var anID = aValue->GetID();
295     CORBA::String_var aName = aValue->GetName();
296     TCollection_AsciiString aGUIName ( (char*) aName.in() );
297     TCollection_AsciiString anEnrty ( (char*) anID.in() );
298     if (aGUIName.Length() > 0) {
299       aMapNames.Bind( anEnrty, aGUIName );
300       aMap.Bind( anEnrty, aGUIName );
301     }
302   }
303
304   // Get trace of restored study
305   //SALOMEDS::SObject_var aSO = SMESH_Gen_i::ObjectToSObject(theStudy, _this());
306   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
307   SALOMEDS::GenericAttribute_var anAttr =
308     aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
309
310   char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
311   TCollection_AsciiString aSavedTrace (oldValue);
312
313   // Add trace of API methods calls and replace study entries by names
314   //TCollection_AsciiString aScript =
315   //  SALOMEDSImpl_Study::GetDumpStudyComment("SMESH") + "\n\n" +
316   //    DumpPython_impl(aStudy->StudyId(), aMap, aMapNames, isPublished, isValidScript, aSavedTrace);
317   TCollection_AsciiString aScript =
318     "### This file is generated by SALOME automatically by dump python functionality of SMESH component\n\n";
319   aScript += DumpPython_impl(aStudy->StudyId(), aMap, aMapNames,
320                              isPublished, isValidScript, aSavedTrace);
321
322   int aLen = aScript.Length(); 
323   unsigned char* aBuffer = new unsigned char[aLen+1];
324   strcpy((char*)aBuffer, aScript.ToCString());
325
326   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
327   Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1); 
328
329   bool hasNotPublishedObjects = aScript.Location( NotPublishedObjectName(), 1, aLen);
330   isValidScript = isValidScript && !hasNotPublishedObjects;
331
332   return aStreamFile._retn(); 
333 }
334
335 //=============================================================================
336 /*!
337  *  AddToPythonScript
338  */
339 //=============================================================================
340 void SMESH_Gen_i::AddToPythonScript (int theStudyID, const TCollection_AsciiString& theString)
341 {
342   if (myPythonScripts.find(theStudyID) == myPythonScripts.end()) {
343     myPythonScripts[theStudyID] = new TColStd_HSequenceOfAsciiString;
344   }
345   myPythonScripts[theStudyID]->Append(theString);
346 }
347
348 //=============================================================================
349 /*!
350  *  RemoveLastFromPythonScript
351  */
352 //=============================================================================
353 void SMESH_Gen_i::RemoveLastFromPythonScript (int theStudyID)
354 {
355   if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
356     int aLen = myPythonScripts[theStudyID]->Length();
357     myPythonScripts[theStudyID]->Remove(aLen);
358   }
359 }
360
361 //=======================================================================
362 //function : AddToCurrentPyScript
363 //purpose  : 
364 //=======================================================================
365
366 void SMESH_Gen_i::AddToCurrentPyScript (const TCollection_AsciiString& theString)
367 {
368   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
369   SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
370   if (aStudy->_is_nil()) return;
371   aSMESHGen->AddToPythonScript(aStudy->StudyId(), theString);
372 }
373
374
375 //=======================================================================
376 //function : AddObject
377 //purpose  : add object to script string
378 //=======================================================================
379
380 TCollection_AsciiString& SMESH_Gen_i::AddObject(TCollection_AsciiString& theStr,
381                                                 CORBA::Object_ptr        theObject)
382 {
383   TCollection_AsciiString aString("None");
384   SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
385   SALOMEDS::SObject_var aSObject =
386     aSMESHGen->ObjectToSObject(aSMESHGen->GetCurrentStudy(), theObject);
387   if ( !aSObject->_is_nil() ) {
388     aString = aSObject->GetID();
389   } else if ( !CORBA::is_nil( theObject )) {
390     aString = "smeshObj_";
391     if ( aSMESHGen->CanPublishInStudy( theObject )) // not published SMESH object
392       aString += (int) theObject;
393     else
394       aString = NotPublishedObjectName();
395   }
396   theStr += aString;
397   return theStr;
398 }
399
400 //=======================================================================
401 //function : SavePython
402 //purpose  : 
403 //=======================================================================
404 void SMESH_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy)
405 {
406   // Dump trace of API methods calls
407   TCollection_AsciiString aScript = GetNewPythonLines(theStudy->StudyId());
408
409   // Check contents of PythonObject attribute
410   SALOMEDS::SObject_var aSO = theStudy->FindComponent(ComponentDataType());
411   //SALOMEDS::SObject_var aSO = SMESH_Gen_i::ObjectToSObject(theStudy, _this());
412   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
413   SALOMEDS::GenericAttribute_var anAttr =
414     aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
415
416   char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
417   TCollection_AsciiString oldScript (oldValue);
418
419   if (oldScript.Length() > 0) {
420     oldScript += "\n";
421     oldScript += aScript;
422   } else {
423     oldScript = aScript;
424   }
425
426   // Store in PythonObject attribute
427   SALOMEDS::AttributePythonObject::_narrow(anAttr)->SetObject(oldScript.ToCString(), 1);
428
429   // Clean trace of API methods calls
430   CleanPythonTrace(theStudy->StudyId());
431 }
432
433
434 // impl
435
436
437 //=============================================================================
438 /*!
439  *  FindEntries: Returns a sequence of start/end positions of entries in the string
440  */
441 //=============================================================================
442 Handle(TColStd_HSequenceOfInteger) FindEntries (TCollection_AsciiString& theString)
443 {
444   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
445   Standard_Integer aLen = theString.Length();
446   Standard_Boolean isFound = Standard_False;
447
448   char* arr = theString.ToCString();
449   Standard_Integer i = 0, j;
450
451   while(i < aLen) {
452     int c = (int)arr[i];
453     j = i+1;
454     if(c >= 48 && c <= 57) { //Is digit?
455  
456       isFound = Standard_False;
457       while((j < aLen) && ((c >= 48 && c <= 57) || c == 58) ) { //Check if it is an entry
458         c = (int)arr[j++];  
459         if(c == 58) isFound = Standard_True;
460       }
461
462       if (isFound) {
463         int prev = (i < 1) ? 0 : (int)arr[i - 1];
464         // last char should be a diggit,
465         // previous char should not be '"'.
466         if (arr[j-2] != 58 && prev != 34) {
467           aSeq->Append(i+1); // +1 because AsciiString starts from 1
468           aSeq->Append(j-1);
469         }
470       }
471     }
472
473     i = j;
474   }
475
476   return aSeq;
477 }
478
479 //=============================================================================
480 /*!
481  *  DumpPython
482  */
483 //=============================================================================
484 TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
485                         (int theStudyID, 
486                          Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
487                          Resource_DataMapOfAsciiStringAsciiString& theNames,
488                          bool isPublished, 
489                          bool& aValidScript,
490                          const TCollection_AsciiString& theSavedTrace)
491 {
492   TCollection_AsciiString aScript;
493   aScript = "def RebuildData(theStudy):";
494   aScript += "\n\tsmesh = salome.lcc.FindOrLoadComponent(\"FactoryServer\", \"SMESH\")";
495   aScript += "\n\taFilterManager = smesh.CreateFilterManager()";
496   if ( isPublished )
497     aScript += "\n\tsmesh.SetCurrentStudy(theStudy)";
498   else
499     aScript += "\n\tsmesh.SetCurrentStudy(None)";
500
501   // Dump trace of restored study
502   if (theSavedTrace.Length() > 0) {
503     aScript += "\n";
504     aScript += theSavedTrace;
505   }
506
507   // Dump trace of API methods calls
508   TCollection_AsciiString aNewLines = GetNewPythonLines(theStudyID);
509   if (aNewLines.Length() > 0) {
510     aScript += "\n";
511     aScript += aNewLines;
512   }
513
514   // Find entries to be replaced by names
515   Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript);
516   Standard_Integer aLen = aSeq->Length();
517
518   if (aLen == 0)
519     return aScript;
520
521   // Replace entries by the names
522   GEOM::GEOM_Gen_ptr geom = GetGeomEngine();
523   TColStd_SequenceOfAsciiString seqRemoved;
524   Resource_DataMapOfAsciiStringAsciiString mapRemoved;
525   Standard_Integer objectCounter = 0, aStart = 1, aScriptLength = aScript.Length();
526   TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("smeshObj_"),
527     allowedChars ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_");
528
529   // Collect names of GEOM objects to exclude same names for SMESH objects
530   GEOM::string_array_var aGeomNames = geom->GetAllDumpNames();
531   int ign = 0, nbgn = aGeomNames->length();
532   for (; ign < nbgn; ign++) {
533     aName = aGeomNames[ign];
534     theObjectNames.Bind(aName, "1");
535   }
536
537   bool importGeom = false;
538   for (Standard_Integer i = 1; i <= aLen; i += 2) {
539     anUpdatedScript += aScript.SubString(aStart, aSeq->Value(i) - 1);
540     anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1));
541     // is a GEOM object?
542     aName = geom->GetDumpName( anEntry.ToCString() );
543     if (aName.IsEmpty()) {
544       // is a SMESH object
545       if (theObjectNames.IsBound(anEntry)) {
546         // The Object is in Study
547         aName = theObjectNames.Find(anEntry);
548         // check validity of aName
549         bool isValidName = true;
550         if ( aName.IsIntegerValue() ) { // aName must not start with a digit
551           aName.Insert( 1, 'a' );
552           isValidName = false;
553         }
554         int p, p2=1; // replace not allowed chars
555         while ((p = aName.FirstLocationNotInSet(allowedChars, p2, aName.Length()))) {
556           aName.SetValue(p, '_');
557           p2=p;
558           isValidName = false;
559         }
560         if (theObjectNames.IsBound(aName) && anEntry != theObjectNames(aName)) {
561           // diff objects have same name - make a new name by appending a digit
562           TCollection_AsciiString aName2;
563           Standard_Integer i = 0;
564           do {
565             aName2 = aName + "_" + ++i;
566           } while (theObjectNames.IsBound(aName2) && anEntry != theObjectNames(aName2));
567           aName = aName2;
568           isValidName = false;
569         }
570         if ( !isValidName )
571           theObjectNames(anEntry) = aName;
572
573       } else {
574         // Removed Object
575         do {
576           aName = aBaseName + TCollection_AsciiString(++objectCounter);
577         } while (theObjectNames.IsBound(aName));
578         seqRemoved.Append(aName);
579         mapRemoved.Bind(anEntry, "1");
580         theObjectNames.Bind(anEntry, aName);
581       }
582       theObjectNames.Bind(aName, anEntry); // to detect same name of diff objects
583     }
584     else
585     {
586       importGeom = true;
587     }
588     anUpdatedScript += aName;
589     aStart = aSeq->Value(i + 1) + 1;
590   }
591
592   // set initial part of aSript
593   TCollection_AsciiString initPart = "import salome, SMESH, StdMeshers\n\n";
594   if ( importGeom )
595   {
596     initPart += ("import string, os, sys, re\n"
597                  "sys.path.insert( 0, os.path.dirname(__file__) )\n"
598                  "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",__name__)+\" import *\")\n\n");
599   }
600   anUpdatedScript.Insert ( 1, initPart );
601
602   // add final part of aScript
603   if (aSeq->Value(aLen) < aScriptLength)
604     anUpdatedScript += aScript.SubString(aSeq->Value(aLen) + 1, aScriptLength);
605
606   // Remove removed objects
607   anUpdatedScript += "\n\taStudyBuilder = theStudy.NewBuilder()";
608   for (int ir = 1; ir <= seqRemoved.Length(); ir++) {
609     anUpdatedScript += "\n\tSO = theStudy.FindObjectIOR(theStudy.ConvertObjectToIOR(";
610     anUpdatedScript += seqRemoved.Value(ir);
611     anUpdatedScript += "))\n\tif SO is not None: aStudyBuilder.RemoveObjectWithChildren(SO)";
612   }
613
614   // Set object names
615   anUpdatedScript += "\n\n\tisGUIMode = ";
616   anUpdatedScript += isPublished;
617   anUpdatedScript += "\n\tif isGUIMode:";
618   anUpdatedScript += "\n\t\tsmeshgui = salome.ImportComponentGUI(\"SMESH\")";
619   anUpdatedScript += "\n\t\tsmeshgui.Init(theStudy._get_StudyId())";
620   anUpdatedScript += "\n";
621
622   TCollection_AsciiString aGUIName;
623   Resource_DataMapOfAsciiStringAsciiString mapEntries;
624   for (Standard_Integer i = 1; i <= aLen; i += 2) {
625     anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1));
626     aName = geom->GetDumpName( anEntry.ToCString() );
627     if (aName.IsEmpty() && // Not a GEOM object
628         theNames.IsBound(anEntry) &&
629         !mapEntries.IsBound(anEntry) && // Not yet processed
630         !mapRemoved.IsBound(anEntry)) { // Was not removed
631       aName = theObjectNames.Find(anEntry);
632       aGUIName = theNames.Find(anEntry);
633       mapEntries.Bind(anEntry, aName);
634       anUpdatedScript += "\n\t\tsmeshgui.SetName(salome.ObjectToID(";
635       anUpdatedScript += aName + "), \"" + aGUIName + "\")";
636     }
637   }
638   anUpdatedScript += "\n\n\t\tsalome.sg.updateObjBrowser(0)";
639
640   anUpdatedScript += "\n\n\tpass\n";
641
642   aValidScript = true;
643
644   return anUpdatedScript;
645 }
646
647 //=============================================================================
648 /*!
649  *  GetNewPythonLines
650  */
651 //=============================================================================
652 TCollection_AsciiString SMESH_Gen_i::GetNewPythonLines (int theStudyID)
653 {
654   TCollection_AsciiString aScript;
655
656   // Dump trace of API methods calls
657   if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
658     Handle(TColStd_HSequenceOfAsciiString) aPythonScript = myPythonScripts[theStudyID];
659     Standard_Integer istr, aLen = aPythonScript->Length();
660     for (istr = 1; istr <= aLen; istr++) {
661       aScript += "\n\t";
662       aScript += aPythonScript->Value(istr);
663     }
664     aScript += "\n";
665   }
666
667   return aScript;
668 }
669
670 //=============================================================================
671 /*!
672  *  CleanPythonTrace
673  */
674 //=============================================================================
675 void SMESH_Gen_i::CleanPythonTrace (int theStudyID)
676 {
677   TCollection_AsciiString aScript;
678
679   // Clean trace of API methods calls
680   if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
681     myPythonScripts[theStudyID]->Clear();
682   }
683 }