Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/geom.git] / src / GEOM / GEOM_Engine.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 #ifdef WNT
21 #pragma warning( disable:4786 )
22 #endif
23
24 #include "GEOM_Engine.hxx"
25
26 #include "GEOM_Solver.hxx"
27 #include "GEOM_Function.hxx"
28 #include "GEOM_ISubShape.hxx"
29 #include "GEOM_SubShapeDriver.hxx"
30 #include "GEOM_DataMapIteratorOfDataMapOfAsciiStringTransient.hxx"
31 #include "GEOM_PythonDump.hxx"
32
33 #include "utilities.h"
34
35 #include <TDF_Tool.hxx>
36 #include <TDF_Data.hxx>
37 #include <TDF_LabelSequence.hxx>
38 #include <TDataStd_Integer.hxx>
39 #include <TDataStd_ChildNodeIterator.hxx>
40 #include <TFunction_Driver.hxx>
41 #include <TFunction_DriverTable.hxx>
42
43 #include <TopExp.hxx>
44 #include <TopTools_IndexedMapOfShape.hxx>
45
46 #include <TCollection_AsciiString.hxx>
47 #include <TCollection_ExtendedString.hxx>
48 #include <TColStd_SequenceOfAsciiString.hxx>
49 #include <TColStd_MapOfTransient.hxx>
50 #include <TColStd_HSequenceOfInteger.hxx>
51
52 #include <Interface_DataMapIteratorOfDataMapOfIntegerTransient.hxx>
53 #include <Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString.hxx>
54
55 #include <map>
56 #include <string>
57
58 #include <Standard_Failure.hxx>
59 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
60
61 static GEOM_Engine* TheEngine = NULL;
62
63 static TCollection_AsciiString BuildIDFromObject(Handle(GEOM_Object)& theObject)
64 {
65   TCollection_AsciiString anID(theObject->GetDocID()), anEntry;
66   TDF_Tool::Entry(theObject->GetEntry(), anEntry);
67   anID+=(TCollection_AsciiString("_")+anEntry);
68   return anID;
69 }
70
71 static TCollection_AsciiString BuildID(Standard_Integer theDocID, char* theEntry)
72 {
73   TCollection_AsciiString anID(theDocID);
74   anID+=(TCollection_AsciiString("_")+theEntry);
75   return anID;
76 }
77
78 static Standard_Integer ExtractDocID(TCollection_AsciiString& theID)
79 {
80   TCollection_AsciiString aDocID = theID.Token("_");
81   if(aDocID.Length() < 1) return -1;
82   return aDocID.IntegerValue();
83 }
84
85 void ProcessFunction(Handle(GEOM_Function)& theFunction, 
86                      TCollection_AsciiString& theScript,
87                      TColStd_MapOfTransient& theProcessed);
88
89 Handle(TColStd_HSequenceOfInteger) FindEntries(TCollection_AsciiString& theString);
90
91 //=============================================================================
92 /*!
93  *  GetEngine
94  */
95 //=============================================================================
96 GEOM_Engine* GEOM_Engine::GetEngine() { return TheEngine; }
97
98
99 //=============================================================================
100 /*!
101  *  SetEngine
102  */
103 //=============================================================================
104 void GEOM_Engine::SetEngine(GEOM_Engine* theEngine) { TheEngine = theEngine; }
105
106 //=============================================================================
107 /*!
108  *  Constructor
109  */
110 //=============================================================================
111 GEOM_Engine::GEOM_Engine()
112 {
113   TFunction_DriverTable::Get()->AddDriver(GEOM_Object::GetSubShapeID(), new GEOM_SubShapeDriver());
114
115   _OCAFApp = new GEOM_Application();
116   _UndoLimit = 10;
117 }
118
119 /*!
120  *  Destructor
121  */
122 GEOM_Engine::~GEOM_Engine()
123
124   GEOM_DataMapIteratorOfDataMapOfAsciiStringTransient It(_objects);
125   for(; It.More(); It.Next()) 
126     {
127       RemoveObject(Handle(GEOM_Object)::DownCast(It.Value()));
128     }
129
130   //Close all documents not closed
131   for(Interface_DataMapIteratorOfDataMapOfIntegerTransient anItr(_mapIDDocument); anItr.More(); anItr.Next())
132     Close(anItr.Key());
133
134   _mapIDDocument.Clear();
135   _objects.Clear();
136 }
137
138 //=============================================================================
139 /*!
140  *  GetDocument
141  */
142 //=============================================================================
143 Handle(TDocStd_Document) GEOM_Engine::GetDocument(int theDocID)
144 {
145   Handle(TDocStd_Document) aDoc;
146   if(!_mapIDDocument.IsBound(theDocID)) {
147     _OCAFApp->NewDocument("SALOME_GEOM", aDoc);
148     aDoc->SetUndoLimit(_UndoLimit);
149     _mapIDDocument.Bind(theDocID, aDoc);
150     TDataStd_Integer::Set(aDoc->Main(), theDocID);
151   }
152
153   return Handle(TDocStd_Document)::DownCast(_mapIDDocument(theDocID));
154 }
155
156 //=============================================================================
157 /*!
158  *  GetDocID
159  */
160 //=============================================================================
161 int GEOM_Engine::GetDocID(Handle(TDocStd_Document) theDocument)
162 {
163   if(theDocument.IsNull()) return -1;
164   for(Interface_DataMapIteratorOfDataMapOfIntegerTransient anItr(_mapIDDocument); anItr.More(); anItr.Next())
165     if(anItr.Value() == theDocument) return anItr.Key();
166
167   return -1;
168
169 }
170
171 //=============================================================================
172 /*!
173  *  GetObject
174  */
175 //=============================================================================
176 Handle(GEOM_Object) GEOM_Engine::GetObject(int theDocID, char* theEntry)
177 {
178   TCollection_AsciiString anID = BuildID(theDocID, theEntry);
179   if(_objects.IsBound(anID)) return Handle(GEOM_Object)::DownCast(_objects(anID));
180
181   TDF_Label aLabel;
182   Handle(TDocStd_Document) aDoc = GetDocument(theDocID);
183   TDF_Tool::Label(aDoc->Main().Data(), theEntry, aLabel, Standard_True);
184   Handle(GEOM_Object) anObject = new GEOM_Object(aLabel);
185
186   _objects.Bind(anID, anObject);
187
188   return anObject;
189 }
190
191 //=============================================================================
192 /*!
193  *  AddObject
194  */
195 //=============================================================================
196 Handle(GEOM_Object) GEOM_Engine::AddObject(int theDocID, int theType)
197 {
198   Handle(TDocStd_Document) aDoc = GetDocument(theDocID);
199   Handle(TDataStd_TreeNode) aRoot = TDataStd_TreeNode::Set(aDoc->Main());
200
201   // NPAL18604: use existing label to decrease memory usage,
202   //            if this label has been freed (object deleted)
203   bool useExisting = false;
204   TDF_Label aChild;
205   if (!_lastCleared.IsNull()) {
206     if (_lastCleared.Root() == aDoc->Main().Root()) {
207       useExisting = true;
208       aChild = _lastCleared;
209       _lastCleared.Nullify();
210     }
211   }
212   if (!useExisting) {
213     // create new label
214     aChild = TDF_TagSource::NewChild(aDoc->Main());
215   }
216
217   Handle(GEOM_Object) anObject = new GEOM_Object(aChild, theType);
218
219   //Put an object in the map of created objects
220   TCollection_AsciiString anID = BuildIDFromObject(anObject);
221   if(_objects.IsBound(anID)) _objects.UnBind(anID);
222   _objects.Bind(anID, anObject);
223
224   return anObject;
225 }
226
227 //=============================================================================
228 /*!
229  *  AddSubShape
230  */
231 //=============================================================================
232 Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, 
233                                              Handle(TColStd_HArray1OfInteger) theIndices,
234                                              bool isStandaloneOperation)
235 {
236   if(theMainShape.IsNull() || theIndices.IsNull()) return NULL;
237
238   Handle(TDocStd_Document) aDoc = GetDocument(theMainShape->GetDocID());
239   Handle(TDataStd_TreeNode) aRoot = TDataStd_TreeNode::Set(aDoc->Main());
240
241   // NPAL18604: use existing label to decrease memory usage,
242   //            if this label has been freed (object deleted)
243   bool useExisting = false;
244   TDF_Label aChild;
245   if (!_lastCleared.IsNull()) {
246     if (_lastCleared.Root() == aDoc->Main().Root()) {
247       useExisting = true;
248       aChild = _lastCleared;
249       _lastCleared.Nullify();
250     }
251   }
252   if (!useExisting) {
253     // create new label
254     aChild = TDF_TagSource::NewChild(aDoc->Main());
255   }
256
257   Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
258   Handle(GEOM_Object) anObject = new GEOM_Object(aChild, 28); //28 is SUBSHAPE type
259   Handle(GEOM_Function) aFunction = anObject->AddFunction(GEOM_Object::GetSubShapeID(), 1);
260
261   GEOM_ISubShape aSSI(aFunction);
262   aSSI.SetMainShape(aMainShape);
263   aSSI.SetIndices(theIndices);
264
265   try {
266 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
267     OCC_CATCH_SIGNALS;
268 #endif
269     GEOM_Solver aSolver (GEOM_Engine::GetEngine());
270     if (!aSolver.ComputeFunction(aFunction)) {
271       MESSAGE("GEOM_Engine::AddSubShape Error: Can't build a sub shape");
272       return NULL;
273     }
274   }
275   catch (Standard_Failure) {
276     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
277     MESSAGE("GEOM_Engine::AddSubShape Error: " << aFail->GetMessageString());
278     return NULL;
279   }
280
281   //Put an object in the map of created objects
282   TCollection_AsciiString anID = BuildIDFromObject(anObject);
283   if(_objects.IsBound(anID)) _objects.UnBind(anID);
284   _objects.Bind(anID, anObject);
285
286   GEOM::TPythonDump pd (aFunction);
287  
288   if (isStandaloneOperation) {
289     pd << anObject << " = geompy.GetSubShape(" << theMainShape << ", [";
290     Standard_Integer i = theIndices->Lower(), up = theIndices->Upper();
291     for (; i <= up - 1; i++) {
292       pd << theIndices->Value(i) << ", ";
293     }
294     pd << theIndices->Value(up) << "])";
295   }
296   else
297     pd << "None";
298
299   return anObject;
300 }
301
302 //=============================================================================
303 /*!
304  *  RemoveObject
305  */
306 //=============================================================================
307 bool GEOM_Engine::RemoveObject(Handle(GEOM_Object) theObject)
308 {
309   if (!theObject) return false;
310
311   //Remove an object from the map of available objects
312   TCollection_AsciiString anID = BuildIDFromObject(theObject);
313   if (_objects.IsBound(anID)) _objects.UnBind(anID);
314
315   int nb = theObject->GetNbFunctions();
316   Handle(TDataStd_TreeNode) aNode;
317   for (int i = 1; i<=nb; i++) {
318     Handle(GEOM_Function) aFunction = theObject->GetFunction(i);
319     if (aFunction->GetEntry().FindAttribute(GEOM_Function::GetFunctionTreeID(), aNode)) 
320       aNode->Remove();
321   }
322
323   TDF_Label aLabel = theObject->GetEntry();
324   aLabel.ForgetAllAttributes(Standard_True);
325   _lastCleared = aLabel;
326
327   theObject.Nullify();
328
329   return true;
330 }
331
332 //=============================================================================
333 /*!
334  *  Undo
335  */
336 //=============================================================================
337 void GEOM_Engine::Undo(int theDocID)
338 {
339   GetDocument(theDocID)->Undo();
340 }
341
342 //=============================================================================
343 /*!
344  *  Redo
345  */
346 //=============================================================================
347 void GEOM_Engine::Redo(int theDocID)
348 {
349   GetDocument(theDocID)->Redo();
350 }
351
352 //=============================================================================
353 /*!
354  *  Save
355  */
356 //=============================================================================
357 bool GEOM_Engine::Save(int theDocID, char* theFileName)
358 {
359   if(!_mapIDDocument.IsBound(theDocID)) return false;
360   Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(_mapIDDocument(theDocID));
361
362   _OCAFApp->SaveAs(aDoc, theFileName);
363
364   return true;
365 }
366
367 //=============================================================================
368 /*!
369  *  Load
370  */
371 //=============================================================================
372 bool GEOM_Engine::Load(int theDocID, char* theFileName)
373 {
374   Handle(TDocStd_Document) aDoc;
375   if(_OCAFApp->Open(theFileName, aDoc) != CDF_RS_OK) {
376     return false;
377   }
378
379   aDoc->SetUndoLimit(_UndoLimit);
380
381   if(_mapIDDocument.IsBound(theDocID)) _mapIDDocument.UnBind(theDocID);
382   _mapIDDocument.Bind(theDocID, aDoc);
383
384   TDataStd_Integer::Set(aDoc->Main(), theDocID);
385
386   return true;
387 }
388
389 //=============================================================================
390 /*!
391  *  Close
392  */
393 //=============================================================================
394 void GEOM_Engine::Close(int theDocID)
395 {
396   if (_mapIDDocument.IsBound(theDocID)) {
397     Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(_mapIDDocument(theDocID));
398
399     //Remove all GEOM Objects associated to the given document
400     TColStd_SequenceOfAsciiString aSeq;
401     GEOM_DataMapIteratorOfDataMapOfAsciiStringTransient It (_objects);
402     for (; It.More(); It.Next()) {
403       TCollection_AsciiString anObjID (It.Key());
404       Standard_Integer anID = ExtractDocID(anObjID);
405       if (theDocID == anID) aSeq.Append(It.Key());
406     }
407     for (Standard_Integer i=1; i<=aSeq.Length(); i++) _objects.UnBind(aSeq.Value(i));
408
409     _lastCleared.Nullify();
410
411     _mapIDDocument.UnBind(theDocID);
412     _OCAFApp->Close(aDoc);
413     aDoc.Nullify();
414   }
415 }
416
417 //=============================================================================
418 /*!
419  *  DumpPython
420  */
421 //=============================================================================
422 TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, 
423                                                 Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
424                                                 bool isPublished, 
425                                                 bool& aValidScript)
426 {
427   TCollection_AsciiString aScript;
428   Handle(TDocStd_Document) aDoc = GetDocument(theDocID);
429   
430   if(aDoc.IsNull()) return TCollection_AsciiString("def RebuildData(theStudy): pass\n");
431  
432   aScript = "import geompy\n";
433   aScript += "import math\n";
434   aScript += "import SALOMEDS\n\n";
435   aScript += "def RebuildData(theStudy):";
436   aScript += "\n\tgeompy.init_geom(theStudy)";
437   
438   Standard_Integer posToInertGlobalVars = aScript.Length() + 1;
439
440   Handle(TDataStd_TreeNode) aNode, aRoot;
441   Handle(GEOM_Function) aFunction;
442   TColStd_MapOfTransient aMap;
443
444   if(aDoc->Main().FindAttribute(GEOM_Function::GetFunctionTreeID(), aRoot)) {
445     TDataStd_ChildNodeIterator Itr(aRoot);
446     for(; Itr.More(); Itr.Next()) {
447       aNode = Itr.Value();
448       aFunction = GEOM_Function::GetFunction(aNode->Label());
449       if(aFunction.IsNull()) {
450         cout << "Null function !!!!" << endl;
451         continue;
452       }
453       ProcessFunction(aFunction, aScript, aMap);
454     }
455   }
456
457   Resource_DataMapOfAsciiStringAsciiString aEntry2StEntry, aStEntry2Entry;
458   Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString anEntryToNameIt;
459   // build maps entry <-> studyEntry
460   for (anEntryToNameIt.Initialize( theObjectNames );
461        anEntryToNameIt.More();
462        anEntryToNameIt.Next())
463   {
464     const TCollection_AsciiString& aEntry = anEntryToNameIt.Key();
465     // look for an object by entry
466     TDF_Label L;
467     TDF_Tool::Label( aDoc->GetData(), aEntry, L );
468     if ( L.IsNull() ) continue;
469     Handle(GEOM_Object) obj = GEOM_Object::GetObject( L );
470     // fill maps
471     if ( !obj.IsNull() ) {
472       TCollection_AsciiString aStudyEntry (obj->GetAuxData());
473       aEntry2StEntry.Bind( aEntry,  aStudyEntry);
474       aStEntry2Entry.Bind( aStudyEntry, aEntry );
475     }
476   }
477
478   Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript);
479   Standard_Integer aLen = aSeq->Length(), objectCounter = 0, aStart = 1, aScriptLength = aScript.Length();
480   Resource_DataMapOfAsciiStringAsciiString aNameToEntry, anEntryToBadName;
481
482   //Replace entries by the names
483   TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("geomObj_"),
484     allowedChars ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_");
485   if(aLen == 0) anUpdatedScript = aScript;
486
487   for(Standard_Integer i = 1; i <= aLen; i+=2) {
488     anUpdatedScript += aScript.SubString(aStart, aSeq->Value(i)-1);
489     anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i+1));
490     if(theObjectNames.IsBound(anEntry)) {
491       aName = theObjectNames.Find(anEntry);
492       // check validity of aName
493       bool isValidName = true;
494       if ( aName.IsIntegerValue() ) { // aName must not start with a digit
495         aName.Insert( 1, 'a' );
496         isValidName = false;
497       }
498       int p, p2=1; // replace not allowed chars
499       while ((p = aName.FirstLocationNotInSet(allowedChars, p2, aName.Length()))) {
500         aName.SetValue(p, '_');
501         p2=p;
502         isValidName = false;
503       }
504       if ( aNameToEntry.IsBound( aName ) && anEntry != aNameToEntry( aName ))
505       {  // diff objects have same name - make a new name by appending a digit
506         TCollection_AsciiString aName2;
507         Standard_Integer i = 0;
508         do {
509           aName2 = aName + "_" + ++i;
510         } while ( aNameToEntry.IsBound( aName2 ) && anEntry != aNameToEntry( aName2 ));
511         aName = aName2;
512         isValidName = false;
513       }
514       if ( !isValidName ) {
515         if ( isPublished )
516           anEntryToBadName.Bind( anEntry, theObjectNames.Find(anEntry) );
517         theObjectNames( anEntry ) = aName;
518       }
519     }
520     else {
521       do {
522         aName = aBaseName + TCollection_AsciiString(++objectCounter);
523       } while(aNameToEntry.IsBound(aName));
524       theObjectNames.Bind(anEntry, aName);
525     }
526     aNameToEntry.Bind(aName, anEntry); // to detect same name of diff objects
527
528     anUpdatedScript += aName;
529     aStart = aSeq->Value(i+1) + 1;
530   }
531
532   //Add final part of the script
533   if(aLen && aSeq->Value(aLen) < aScriptLength)  anUpdatedScript += aScript.SubString(aSeq->Value(aLen)+1, aScriptLength); // mkr : IPAL11865
534  
535   // ouv : NPAL12872
536   for (anEntryToNameIt.Initialize( theObjectNames );
537        anEntryToNameIt.More();
538        anEntryToNameIt.Next())
539   {
540     const TCollection_AsciiString& aEntry = anEntryToNameIt.Key();
541     const TCollection_AsciiString& aName = anEntryToNameIt.Value();
542
543     TDF_Label L;
544     TDF_Tool::Label( aDoc->GetData(), aEntry, L );
545     if ( L.IsNull() )
546       continue;
547
548     Handle(GEOM_Object) obj = GEOM_Object::GetObject( L );
549     if ( obj.IsNull() )
550       continue;
551
552     bool anAutoColor = obj->GetAutoColor();
553     if ( anAutoColor )
554     {
555       TCollection_AsciiString aCommand( "\n\t" );
556       aCommand += aName + ".SetAutoColor(1)";
557       anUpdatedScript += aCommand.ToCString();
558     }
559
560     SALOMEDS::Color aColor = obj->GetColor();
561     if ( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 )
562     {
563       TCollection_AsciiString aCommand( "\n\t" );
564       aCommand += aName + ".SetColor(SALOMEDS.Color(" + aColor.R + "," + aColor.G + "," + aColor.B + "))";
565       anUpdatedScript += aCommand.ToCString();
566     }
567   }
568
569   // Make script to publish in study
570   if ( isPublished )
571   {
572     std::map< int, std::string > anEntryToCommandMap; // sort publishing commands by object entry
573     for (anEntryToNameIt.Initialize( theObjectNames );
574          anEntryToNameIt.More();
575          anEntryToNameIt.Next())
576     {
577       const TCollection_AsciiString& aEntry = anEntryToNameIt.Key();
578       const TCollection_AsciiString& aName = anEntryToNameIt.Value();
579       if ( !aEntry2StEntry.IsBound( aEntry ))
580         continue; // was not published
581       TCollection_AsciiString aCommand("\n\tgeompy."), aFatherEntry;
582
583       // find a father entry
584       const TCollection_AsciiString& aStudyEntry = aEntry2StEntry( aEntry );
585       TCollection_AsciiString aFatherStudyEntry =
586         aStudyEntry.SubString( 1, aStudyEntry.SearchFromEnd(":") - 1 );
587       if ( aStEntry2Entry.IsBound( aFatherStudyEntry ))
588         aFatherEntry = aStEntry2Entry( aFatherStudyEntry );
589
590       // make a command
591       if ( !aFatherEntry.IsEmpty() && theObjectNames.IsBound( aFatherEntry )) {
592         aCommand += "addToStudyInFather( ";
593         aCommand += theObjectNames( aFatherEntry ) + ", ";
594       }
595       else
596         aCommand += "addToStudy( ";
597       if ( anEntryToBadName.IsBound( aEntry ))
598         aCommand += aName + ", \"" + anEntryToBadName( aEntry ) + "\" )";
599       else 
600         aCommand += aName + ", \"" + aName + "\" )";
601
602       // bind a command to the last digit of the entry
603       int tag =
604         aEntry.SubString( aEntry.SearchFromEnd(":")+1, aEntry.Length() ).IntegerValue();
605       anEntryToCommandMap.insert( std::make_pair( tag, aCommand.ToCString() ));
606     }
607
608     // add publishing commands to the script
609     std::map< int, std::string >::iterator anEntryToCommand = anEntryToCommandMap.begin();
610     for ( ; anEntryToCommand != anEntryToCommandMap.end(); ++anEntryToCommand ) {
611       anUpdatedScript += (char*)anEntryToCommand->second.c_str();
612     }
613   }
614
615   anUpdatedScript += "\n\tpass\n";
616   aValidScript = true;
617
618   // fill _studyEntry2NameMap and build globalVars
619   TCollection_AsciiString globalVars;
620   _studyEntry2NameMap.Clear();
621   Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString aStEntryToEntryIt;
622   for (aStEntryToEntryIt.Initialize( aStEntry2Entry );
623        aStEntryToEntryIt.More();
624        aStEntryToEntryIt.Next() )
625   {
626     const TCollection_AsciiString & name = theObjectNames( aStEntryToEntryIt.Value() );
627     _studyEntry2NameMap.Bind (aStEntryToEntryIt.Key(), name );
628     if ( !globalVars.IsEmpty() )
629       globalVars += ", ";
630     globalVars += name;
631   }
632   if ( !globalVars.IsEmpty() ) {
633     globalVars.Insert( 1, "\n\tglobal " );
634     anUpdatedScript.Insert( posToInertGlobalVars, globalVars );
635   }
636   
637   return anUpdatedScript;
638 }
639
640 //=======================================================================
641 //function : GetDumpName
642 //purpose  : 
643 //=======================================================================
644
645 const char* GEOM_Engine::GetDumpName (const char* theStudyEntry) const
646 {
647   if ( _studyEntry2NameMap.IsBound( (char*)theStudyEntry ))
648     return _studyEntry2NameMap( (char*)theStudyEntry ).ToCString();
649
650   return NULL;
651 }
652
653 //=======================================================================
654 //function : GetAllDumpNames
655 //purpose  : 
656 //=======================================================================
657
658 Handle(TColStd_HSequenceOfAsciiString) GEOM_Engine::GetAllDumpNames() const
659 {
660   Handle(TColStd_HSequenceOfAsciiString) aRetSeq = new TColStd_HSequenceOfAsciiString;
661
662   Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString it (_studyEntry2NameMap);
663   for (; it.More(); it.Next()) {
664     aRetSeq->Append(it.Value());
665   }
666
667   return aRetSeq;
668 }
669
670
671 //===========================================================================
672 //                     Internal functions
673 //===========================================================================
674 void ProcessFunction(Handle(GEOM_Function)& theFunction, 
675                      TCollection_AsciiString& theScript,
676                      TColStd_MapOfTransient& theProcessed)
677 {
678   if(theFunction.IsNull() || theProcessed.Contains(theFunction)) return;
679
680 /*
681   TDF_LabelSequence aSeq;
682   theFunction->GetDependency(aSeq);
683   Standard_Integer aLen = aSeq.Length();
684   for(Standard_Integer i = 1; i<= aLen; i++) {
685     Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(aSeq.Value(i));
686     if(aFunction.IsNull()) continue;
687     ProcessFunction(aFunction, theScript, theProcessed);
688   }
689 */
690
691   TCollection_AsciiString aDescr = theFunction->GetDescription();
692   if(aDescr.Length() == 0) {
693     //cout << "Warning: the function has no description" << endl;
694     return;
695   }
696   //Check if its internal function which doesn't requires dumping
697   if(aDescr == "None") return;
698
699   theScript += "\n\t";
700   theScript += aDescr;
701  
702   theProcessed.Add(theFunction);
703   return;
704 }
705
706 //=============================================================================
707 /*!
708  *  FindEntries: Returns a sequence of start/end positions of entries in the string
709  */
710 //=============================================================================
711 Handle(TColStd_HSequenceOfInteger) FindEntries(TCollection_AsciiString& theString)
712 {
713   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
714   Standard_Integer aLen = theString.Length();
715   Standard_Boolean isFound = Standard_False;
716
717   char* arr = theString.ToCString();
718   Standard_Integer i = 0, j;
719
720   while(i < aLen) {
721     int c = (int)arr[i];
722     j = i+1;
723     if(c >= 48 && c <= 57) { //Is digit?
724  
725       isFound = Standard_False;
726       while((j < aLen) && ((c >= 48 && c <= 57) || c == 58) ) { //Check if it is an entry
727         c = (int)arr[j++];  
728         if(c == 58) isFound = Standard_True;
729       }
730       
731       if(isFound && arr[j-2] != 58) { // last char should be a diggit
732         aSeq->Append(i+1); // +1 because AsciiString starts from 1
733         aSeq->Append(j-1);
734       }
735     }
736      
737     i = j;
738   }
739
740   return aSeq;
741 }