1 // File : SMESH_Gen_i_DumpPython.cxx
2 // Created : Thu Mar 24 17:17:59 2005
3 // Author : Julia DOROVSKIKH
7 #include "SMESH_PythonDump.hxx"
8 #include "SMESH_Gen_i.hxx"
9 #include "SMESH_Filter_i.hxx"
11 #include <TColStd_HSequenceOfInteger.hxx>
15 TCollection_AsciiString&
16 operator<<(TCollection_AsciiString& theString, const char* theArg){
17 theString += Standard_CString(theArg);
21 TCollection_AsciiString&
22 operator<<(TCollection_AsciiString& theString, int theArg){
23 theString += TCollection_AsciiString(theArg);
27 TCollection_AsciiString&
28 operator<<(TCollection_AsciiString& theString, float theArg){
29 theString += TCollection_AsciiString(theArg);
33 TCollection_AsciiString&
34 operator<<(TCollection_AsciiString& theString,
35 const SMESH::long_array& theArg)
38 CORBA::Long i = 1, iEnd = theArg.length();
39 for(; i <= iEnd; i++) {
40 theString<<int(theArg[i-1]);
49 TCollection_AsciiString&
50 operator<<(TCollection_AsciiString& theString,
51 CORBA::Object_ptr theArg)
53 CORBA::String_var aString("None");
54 SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
55 SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
56 SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
57 if(!aSObject->_is_nil()){
58 aString = aSObject->GetID();
59 }else if(!CORBA::is_nil(theArg)){
60 aString = SMESH_Gen_i::GetORB()->object_to_string(theArg);
62 theString<<aString.in();
66 TCollection_AsciiString&
67 operator<<(TCollection_AsciiString& theString,
68 SMESH::FilterLibrary_i* theArg)
70 theString += TCollection_AsciiString("aFilterLibrary_");
71 theString += TCollection_AsciiString(int(theArg));
75 TCollection_AsciiString&
76 operator<<(TCollection_AsciiString& theString,
77 SMESH::FilterManager_i* theArg)
79 theString += TCollection_AsciiString("aFilterManager_");
80 theString += TCollection_AsciiString(int(theArg));
84 TCollection_AsciiString&
85 operator<<(TCollection_AsciiString& theString,
86 SMESH::Functor_i* theArg)
88 FunctorType aFunctorType = theArg->GetFunctorType();
91 theString += TCollection_AsciiString("anAspectRatio");
93 case FT_AspectRatio3D:
94 theString += TCollection_AsciiString("anAspectRatio3D");
97 theString += TCollection_AsciiString("aWarping");
100 theString += TCollection_AsciiString("aMinimumAngle");
103 theString += TCollection_AsciiString("aTaper");
106 theString += TCollection_AsciiString("aSkew");
109 theString += TCollection_AsciiString("aArea");
112 theString += TCollection_AsciiString("aFreeBorders");
115 theString += TCollection_AsciiString("aFreeEdges");
117 case FT_MultiConnection:
118 theString += TCollection_AsciiString("aMultiConnection");
120 case FT_MultiConnection2D:
121 theString += TCollection_AsciiString("aMultiConnection2D");
124 theString += TCollection_AsciiString("aLength");
127 theString += TCollection_AsciiString("aLength");
129 case FT_BelongToGeom:
130 theString += TCollection_AsciiString("aBelongToGeom");
132 case FT_BelongToPlane:
133 theString += TCollection_AsciiString("aBelongToPlane");
135 case FT_BelongToCylinder:
136 theString += TCollection_AsciiString("aBelongToCylinder");
139 theString += TCollection_AsciiString("aLyingOnGeom");
142 theString += TCollection_AsciiString("aRangeOfIds");
144 case FT_BadOrientedVolume:
145 theString += TCollection_AsciiString("aBadOrientedVolume");
148 theString += TCollection_AsciiString("aLessThan");
151 theString += TCollection_AsciiString("aMoreThan");
154 theString += TCollection_AsciiString("anEqualTo");
157 theString += TCollection_AsciiString("aLogicalNOT");
160 theString += TCollection_AsciiString("aLogicalAND");
163 theString += TCollection_AsciiString("aLogicalOR");
166 theString += TCollection_AsciiString("anUndefined");
169 theString += Standard_CString("_");
170 theString += TCollection_AsciiString(int(theArg));
177 SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
178 SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
179 if(!aStudy->_is_nil()){
180 aSMESHGen->AddToPythonScript(aStudy->StudyId(),myString);
185 //=======================================================================
186 //function : DumpPython
188 //=======================================================================
189 Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
190 CORBA::Boolean isPublished,
191 CORBA::Boolean& isValidScript)
193 SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
194 if (CORBA::is_nil(aStudy))
195 return new Engines::TMPFile(0);
197 SALOMEDS::SObject_var aSO = aStudy->FindComponent(ComponentDataType());
198 if (CORBA::is_nil(aSO))
199 return new Engines::TMPFile(0);
201 // Map study entries to object names
202 Resource_DataMapOfAsciiStringAsciiString aMap;
203 TCollection_AsciiString s ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_");
205 SALOMEDS::ChildIterator_var Itr = aStudy->NewChildIterator(aSO);
206 for (Itr->InitEx(true); Itr->More(); Itr->Next()) {
207 SALOMEDS::SObject_var aValue = Itr->Value();
209 TCollection_AsciiString aName (aValue->GetName());
210 if (aName.Length() > 0) {
211 int p, p2 = 1, e = aName.Length();
212 while ((p = aName.FirstLocationNotInSet(s, p2, e))) {
213 aName.SetValue(p, '_');
216 aMap.Bind(TCollection_AsciiString(aValue->GetID()), aName);
220 // Get trace of restored study
221 //SALOMEDS::SObject_var aSO = SMESH_Gen_i::ObjectToSObject(theStudy, _this());
222 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
223 SALOMEDS::GenericAttribute_var anAttr =
224 aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
226 char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
227 TCollection_AsciiString aSavedTrace (oldValue);
229 // Add trace of API methods calls and replace study entries by names
231 //TCollection_AsciiString aScript = myGen.DumpPython
232 TCollection_AsciiString aScript = DumpPython_impl
233 (aStudy->StudyId(), aMap, isPublished, aValidScript, aSavedTrace);
235 int aLen = aScript.Length();
236 unsigned char* aBuffer = new unsigned char[aLen+1];
237 strcpy((char*)aBuffer, aScript.ToCString());
239 CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer;
240 Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1);
241 isValidScript = aValidScript;
243 return aStreamFile._retn();
246 //=============================================================================
250 //=============================================================================
251 void SMESH_Gen_i::AddToPythonScript (int theStudyID, const TCollection_AsciiString& theString)
253 if (myPythonScripts.find(theStudyID) == myPythonScripts.end()) {
254 myPythonScripts[theStudyID] = new TColStd_HSequenceOfAsciiString;
256 myPythonScripts[theStudyID]->Append(theString);
259 //=============================================================================
261 * RemoveLastFromPythonScript
263 //=============================================================================
264 void SMESH_Gen_i::RemoveLastFromPythonScript (int theStudyID)
266 if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
267 int aLen = myPythonScripts[theStudyID]->Length();
268 myPythonScripts[theStudyID]->Remove(aLen);
272 //=======================================================================
273 //function : AddToCurrentPyScript
275 //=======================================================================
277 void SMESH_Gen_i::AddToCurrentPyScript (const TCollection_AsciiString& theString)
279 SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
280 SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
281 if (aStudy->_is_nil()) return;
282 aSMESHGen->AddToPythonScript(aStudy->StudyId(), theString);
286 //=======================================================================
287 //function : AddObject
288 //purpose : add object to script string
289 //=======================================================================
291 TCollection_AsciiString& SMESH_Gen_i::AddObject(TCollection_AsciiString& theStr,
292 CORBA::Object_ptr theObject)
294 SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
295 SALOMEDS::SObject_var aSO =
296 aSMESHGen->ObjectToSObject(aSMESHGen->GetCurrentStudy(), theObject);
297 if ( !aSO->_is_nil() )
298 theStr += aSO->GetID();
299 else if ( !CORBA::is_nil( theObject ) )
300 theStr += GetORB()->object_to_string( theObject );
307 //=======================================================================
308 //function : SavePython
310 //=======================================================================
311 void SMESH_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy)
313 // Dump trace of API methods calls
314 TCollection_AsciiString aScript = GetNewPythonLines(theStudy->StudyId());
316 // Check contents of PythonObject attribute
317 SALOMEDS::SObject_var aSO = theStudy->FindComponent(ComponentDataType());
318 //SALOMEDS::SObject_var aSO = SMESH_Gen_i::ObjectToSObject(theStudy, _this());
319 SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
320 SALOMEDS::GenericAttribute_var anAttr =
321 aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
323 char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
324 TCollection_AsciiString oldScript (oldValue);
326 if (oldScript.Length() > 0) {
328 oldScript += aScript;
333 // Store in PythonObject attribute
334 SALOMEDS::AttributePythonObject::_narrow(anAttr)->SetObject(oldScript.ToCString(), 1);
336 // Clean trace of API methods calls
337 CleanPythonTrace(theStudy->StudyId());
344 //=============================================================================
346 * FindEntries: Returns a sequence of start/end positions of entries in the string
348 //=============================================================================
349 Handle(TColStd_HSequenceOfInteger) FindEntries (TCollection_AsciiString& theString)
351 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
352 Standard_Integer aLen = theString.Length();
353 Standard_Boolean isFound = Standard_False;
355 char* arr = theString.ToCString();
356 Standard_Integer i = 0, j;
361 if(c >= 48 && c <= 57) { //Is digit?
363 isFound = Standard_False;
364 while((j < aLen) && ((c >= 48 && c <= 57) || c == 58) ) { //Check if it is an entry
366 if(c == 58) isFound = Standard_True;
370 int prev = (i < 1) ? 0 : (int)arr[i - 1];
371 // last char should be a diggit,
372 // previous char should not be '"'.
373 if (arr[j-2] != 58 && prev != 34) {
374 aSeq->Append(i+1); // +1 because AsciiString starts from 1
386 //=============================================================================
390 //=============================================================================
391 TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
393 Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
396 const TCollection_AsciiString& theSavedTrace)
398 TCollection_AsciiString aScript;
399 aScript += "import salome\n";
400 aScript += "import geompy\n\n";
401 aScript += "import SMESH\n";
402 aScript += "import StdMeshers\n\n";
403 aScript += "#import GEOM module\n";
404 aScript += "import string\n";
405 aScript += "import os\n";
406 aScript += "import sys\n";
407 aScript += "sys.path.append( os.path.dirname(__file__) )\n";
408 aScript += "exec(\"from \"+string.replace(__name__,\"SMESH\",\"GEOM\")+\" import *\")\n\n";
410 aScript += "def RebuildData(theStudy):";
411 aScript += "\n\tsmesh = salome.lcc.FindOrLoadComponent(\"FactoryServer\", \"SMESH\")";
413 aScript += "\n\tsmesh.SetCurrentStudy(theStudy)";
415 aScript += "\n\tsmesh.SetCurrentStudy(None)";
417 Standard_Integer posToInertGlobalVars = aScript.Length();
418 TCollection_AsciiString globalVars;
420 // Dump trace of restored study
421 if (theSavedTrace.Length() > 0) {
423 aScript += theSavedTrace;
426 // Dump trace of API methods calls
427 TCollection_AsciiString aNewLines = GetNewPythonLines(theStudyID);
428 if (aNewLines.Length() > 0) {
430 aScript += aNewLines;
433 // Find entries to be replaced by names
434 Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript);
435 Standard_Integer aLen = aSeq->Length();
440 // Replace entries by the names
441 GEOM::GEOM_Gen_ptr geom = GetGeomEngine();
442 TColStd_SequenceOfAsciiString seqRemoved;
443 Resource_DataMapOfAsciiStringAsciiString mapRemoved;
444 Resource_DataMapOfAsciiStringAsciiString aNames;
445 Standard_Integer objectCounter = 0, aStart = 1, aScriptLength = aScript.Length();
446 TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("smeshObj_");
448 for (Standard_Integer i = 1; i <= aLen; i += 2) {
449 anUpdatedScript += aScript.SubString(aStart, aSeq->Value(i) - 1);
450 anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1));
451 if (theObjectNames.IsBound(anEntry)) {
452 aName = theObjectNames.Find(anEntry);
453 if (theObjectNames.IsBound(aName) && anEntry != theObjectNames(aName)) {
454 // diff objects have same name - make a new name
455 TCollection_AsciiString aName2;
456 Standard_Integer i = 0;
458 aName2 = aName + "_" + ++i;
459 } while (theObjectNames.IsBound(aName2) && anEntry != theObjectNames(aName2));
461 theObjectNames(anEntry) = aName;
465 aName = geom->GetDumpName( anEntry.ToCString() );
466 if ( aName.IsEmpty() ) {
467 // ? Removed Object ?
469 aName = aBaseName + TCollection_AsciiString(++objectCounter);
470 } while (theObjectNames.IsBound(aName));
471 seqRemoved.Append(aName);
472 mapRemoved.Bind(anEntry, "1");
474 theObjectNames.Bind(anEntry, aName);
476 theObjectNames.Bind(aName, anEntry); // to detect same name of diff objects
478 anUpdatedScript += aName;
479 aNames.Bind(aName, "1");
480 aStart = aSeq->Value(i + 1) + 1;
483 // add final part of aScript
484 if (aSeq->Value(aLen) < aScriptLength)
485 anUpdatedScript += aScript.SubString(aSeq->Value(aLen) + 1, aScriptLength);
487 // Remove removed objects
488 anUpdatedScript += "\n\taStudyBuilder = theStudy.NewBuilder()";
489 for (int ir = 1; ir <= seqRemoved.Length(); ir++) {
490 anUpdatedScript += "\n\tSO = theStudy.FindObjectIOR(theStudy.ConvertObjectToIOR(";
491 anUpdatedScript += seqRemoved.Value(ir);
492 anUpdatedScript += "))\n\tif SO is not None: aStudyBuilder.RemoveObjectWithChildren(SO)";
494 anUpdatedScript += "\n";
497 anUpdatedScript += "\n\tisGUIMode = ";
498 anUpdatedScript += isPublished;
499 anUpdatedScript += "\n\tif isGUIMode:";
500 anUpdatedScript += "\n\t\tsmeshgui = salome.ImportComponentGUI(\"SMESH\")";
501 anUpdatedScript += "\n\t\tsmeshgui.Init(theStudy._get_StudyId())";
502 anUpdatedScript += "\n";
504 Resource_DataMapOfAsciiStringAsciiString mapEntries;
505 for (Standard_Integer i = 1; i <= aLen; i += 2) {
506 anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1));
507 if (theObjectNames.IsBound(anEntry) &&
508 !mapEntries.IsBound(anEntry) &&
509 !mapRemoved.IsBound(anEntry)) {
510 aName = theObjectNames.Find(anEntry);
511 mapEntries.Bind(anEntry, aName);
512 anUpdatedScript += "\n\t\tsmeshgui.SetName(salome.ObjectToID(";
513 anUpdatedScript += aName + "), \"" + aName + "\")";
516 anUpdatedScript += "\n\n\t\tsalome.sg.updateObjBrowser(0)";
518 anUpdatedScript += "\n\n\tpass\n";
522 return anUpdatedScript;
525 //=============================================================================
529 //=============================================================================
530 TCollection_AsciiString SMESH_Gen_i::GetNewPythonLines (int theStudyID)
532 TCollection_AsciiString aScript;
534 // Dump trace of API methods calls
535 if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
536 Handle(TColStd_HSequenceOfAsciiString) aPythonScript = myPythonScripts[theStudyID];
537 Standard_Integer istr, aLen = aPythonScript->Length();
538 for (istr = 1; istr <= aLen; istr++) {
540 aScript += aPythonScript->Value(istr);
548 //=============================================================================
552 //=============================================================================
553 void SMESH_Gen_i::CleanPythonTrace (int theStudyID)
555 TCollection_AsciiString aScript;
557 // Clean trace of API methods calls
558 if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
559 myPythonScripts[theStudyID]->Clear();