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::Filter_i* theArg)
88 theString += TCollection_AsciiString("aFilter_");
89 theString += TCollection_AsciiString(int(theArg));
93 TCollection_AsciiString&
94 operator<<(TCollection_AsciiString& theString,
95 SMESH::Functor_i* theArg)
97 FunctorType aFunctorType = theArg->GetFunctorType();
100 theString += TCollection_AsciiString("anAspectRatio");
102 case FT_AspectRatio3D:
103 theString += TCollection_AsciiString("anAspectRatio3D");
106 theString += TCollection_AsciiString("aWarping");
108 case FT_MinimumAngle:
109 theString += TCollection_AsciiString("aMinimumAngle");
112 theString += TCollection_AsciiString("aTaper");
115 theString += TCollection_AsciiString("aSkew");
118 theString += TCollection_AsciiString("aArea");
121 theString += TCollection_AsciiString("aFreeBorders");
124 theString += TCollection_AsciiString("aFreeEdges");
126 case FT_MultiConnection:
127 theString += TCollection_AsciiString("aMultiConnection");
129 case FT_MultiConnection2D:
130 theString += TCollection_AsciiString("aMultiConnection2D");
133 theString += TCollection_AsciiString("aLength");
136 theString += TCollection_AsciiString("aLength");
138 case FT_BelongToGeom:
139 theString += TCollection_AsciiString("aBelongToGeom");
141 case FT_BelongToPlane:
142 theString += TCollection_AsciiString("aBelongToPlane");
144 case FT_BelongToCylinder:
145 theString += TCollection_AsciiString("aBelongToCylinder");
148 theString += TCollection_AsciiString("aLyingOnGeom");
151 theString += TCollection_AsciiString("aRangeOfIds");
153 case FT_BadOrientedVolume:
154 theString += TCollection_AsciiString("aBadOrientedVolume");
157 theString += TCollection_AsciiString("aLessThan");
160 theString += TCollection_AsciiString("aMoreThan");
163 theString += TCollection_AsciiString("anEqualTo");
166 theString += TCollection_AsciiString("aLogicalNOT");
169 theString += TCollection_AsciiString("aLogicalAND");
172 theString += TCollection_AsciiString("aLogicalOR");
175 theString += TCollection_AsciiString("anUndefined");
178 theString += Standard_CString("_");
179 theString += TCollection_AsciiString(int(theArg));
183 size_t TPythonDump::myCounter = 0;
193 if(--myCounter == 0){
194 SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
195 SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
196 if(!aStudy->_is_nil()){
197 aSMESHGen->AddToPythonScript(aStudy->StudyId(),myString);
203 //=======================================================================
204 //function : DumpPython
206 //=======================================================================
207 Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
208 CORBA::Boolean isPublished,
209 CORBA::Boolean& isValidScript)
211 SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
212 if (CORBA::is_nil(aStudy))
213 return new Engines::TMPFile(0);
215 SALOMEDS::SObject_var aSO = aStudy->FindComponent(ComponentDataType());
216 if (CORBA::is_nil(aSO))
217 return new Engines::TMPFile(0);
219 // Map study entries to object names
220 Resource_DataMapOfAsciiStringAsciiString aMap;
221 TCollection_AsciiString s ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_");
223 SALOMEDS::ChildIterator_var Itr = aStudy->NewChildIterator(aSO);
224 for (Itr->InitEx(true); Itr->More(); Itr->Next()) {
225 SALOMEDS::SObject_var aValue = Itr->Value();
227 TCollection_AsciiString aName (aValue->GetName());
228 if (aName.Length() > 0) {
229 int p, p2 = 1, e = aName.Length();
230 while ((p = aName.FirstLocationNotInSet(s, p2, e))) {
231 aName.SetValue(p, '_');
234 aMap.Bind(TCollection_AsciiString(aValue->GetID()), aName);
238 // Get trace of restored study
239 //SALOMEDS::SObject_var aSO = SMESH_Gen_i::ObjectToSObject(theStudy, _this());
240 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
241 SALOMEDS::GenericAttribute_var anAttr =
242 aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
244 char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
245 TCollection_AsciiString aSavedTrace (oldValue);
247 // Add trace of API methods calls and replace study entries by names
249 //TCollection_AsciiString aScript = myGen.DumpPython
250 TCollection_AsciiString aScript = DumpPython_impl
251 (aStudy->StudyId(), aMap, isPublished, aValidScript, aSavedTrace);
253 int aLen = aScript.Length();
254 unsigned char* aBuffer = new unsigned char[aLen+1];
255 strcpy((char*)aBuffer, aScript.ToCString());
257 CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer;
258 Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1);
259 isValidScript = aValidScript;
261 return aStreamFile._retn();
264 //=============================================================================
268 //=============================================================================
269 void SMESH_Gen_i::AddToPythonScript (int theStudyID, const TCollection_AsciiString& theString)
271 if (myPythonScripts.find(theStudyID) == myPythonScripts.end()) {
272 myPythonScripts[theStudyID] = new TColStd_HSequenceOfAsciiString;
274 myPythonScripts[theStudyID]->Append(theString);
277 //=============================================================================
279 * RemoveLastFromPythonScript
281 //=============================================================================
282 void SMESH_Gen_i::RemoveLastFromPythonScript (int theStudyID)
284 if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
285 int aLen = myPythonScripts[theStudyID]->Length();
286 myPythonScripts[theStudyID]->Remove(aLen);
290 //=======================================================================
291 //function : AddToCurrentPyScript
293 //=======================================================================
295 void SMESH_Gen_i::AddToCurrentPyScript (const TCollection_AsciiString& theString)
297 SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
298 SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
299 if (aStudy->_is_nil()) return;
300 aSMESHGen->AddToPythonScript(aStudy->StudyId(), theString);
304 //=======================================================================
305 //function : AddObject
306 //purpose : add object to script string
307 //=======================================================================
309 TCollection_AsciiString& SMESH_Gen_i::AddObject(TCollection_AsciiString& theStr,
310 CORBA::Object_ptr theObject)
312 SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
313 SALOMEDS::SObject_var aSO =
314 aSMESHGen->ObjectToSObject(aSMESHGen->GetCurrentStudy(), theObject);
315 if ( !aSO->_is_nil() )
316 theStr += aSO->GetID();
317 else if ( !CORBA::is_nil( theObject ) )
318 theStr += GetORB()->object_to_string( theObject );
325 //=======================================================================
326 //function : SavePython
328 //=======================================================================
329 void SMESH_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy)
331 // Dump trace of API methods calls
332 TCollection_AsciiString aScript = GetNewPythonLines(theStudy->StudyId());
334 // Check contents of PythonObject attribute
335 SALOMEDS::SObject_var aSO = theStudy->FindComponent(ComponentDataType());
336 //SALOMEDS::SObject_var aSO = SMESH_Gen_i::ObjectToSObject(theStudy, _this());
337 SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
338 SALOMEDS::GenericAttribute_var anAttr =
339 aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
341 char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
342 TCollection_AsciiString oldScript (oldValue);
344 if (oldScript.Length() > 0) {
346 oldScript += aScript;
351 // Store in PythonObject attribute
352 SALOMEDS::AttributePythonObject::_narrow(anAttr)->SetObject(oldScript.ToCString(), 1);
354 // Clean trace of API methods calls
355 CleanPythonTrace(theStudy->StudyId());
362 //=============================================================================
364 * FindEntries: Returns a sequence of start/end positions of entries in the string
366 //=============================================================================
367 Handle(TColStd_HSequenceOfInteger) FindEntries (TCollection_AsciiString& theString)
369 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
370 Standard_Integer aLen = theString.Length();
371 Standard_Boolean isFound = Standard_False;
373 char* arr = theString.ToCString();
374 Standard_Integer i = 0, j;
379 if(c >= 48 && c <= 57) { //Is digit?
381 isFound = Standard_False;
382 while((j < aLen) && ((c >= 48 && c <= 57) || c == 58) ) { //Check if it is an entry
384 if(c == 58) isFound = Standard_True;
388 int prev = (i < 1) ? 0 : (int)arr[i - 1];
389 // last char should be a diggit,
390 // previous char should not be '"'.
391 if (arr[j-2] != 58 && prev != 34) {
392 aSeq->Append(i+1); // +1 because AsciiString starts from 1
404 //=============================================================================
408 //=============================================================================
409 TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
411 Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
414 const TCollection_AsciiString& theSavedTrace)
416 TCollection_AsciiString aScript;
417 aScript += "import salome\n";
418 aScript += "import geompy\n\n";
419 aScript += "import SMESH\n";
420 aScript += "import StdMeshers\n\n";
421 aScript += "#import GEOM module\n";
422 aScript += "import string\n";
423 aScript += "import os\n";
424 aScript += "import sys\n";
425 aScript += "sys.path.append( os.path.dirname(__file__) )\n";
426 aScript += "exec(\"from \"+string.replace(__name__,\"SMESH\",\"GEOM\")+\" import *\")\n\n";
428 aScript += "def RebuildData(theStudy):";
429 aScript += "\n\tsmesh = salome.lcc.FindOrLoadComponent(\"FactoryServer\", \"SMESH\")";
431 aScript += "\n\tsmesh.SetCurrentStudy(theStudy)";
433 aScript += "\n\tsmesh.SetCurrentStudy(None)";
435 TCollection_AsciiString globalVars;
437 // Dump trace of restored study
438 if (theSavedTrace.Length() > 0) {
440 aScript += theSavedTrace;
443 // Dump trace of API methods calls
444 TCollection_AsciiString aNewLines = GetNewPythonLines(theStudyID);
445 if (aNewLines.Length() > 0) {
447 aScript += aNewLines;
450 // Find entries to be replaced by names
451 Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript);
452 Standard_Integer aLen = aSeq->Length();
457 // Replace entries by the names
458 GEOM::GEOM_Gen_ptr geom = GetGeomEngine();
459 TColStd_SequenceOfAsciiString seqRemoved;
460 Resource_DataMapOfAsciiStringAsciiString mapRemoved;
461 Resource_DataMapOfAsciiStringAsciiString aNames;
462 Standard_Integer objectCounter = 0, aStart = 1, aScriptLength = aScript.Length();
463 TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("smeshObj_");
465 for (Standard_Integer i = 1; i <= aLen; i += 2) {
466 anUpdatedScript += aScript.SubString(aStart, aSeq->Value(i) - 1);
467 anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1));
468 if (theObjectNames.IsBound(anEntry)) {
469 aName = theObjectNames.Find(anEntry);
470 if (theObjectNames.IsBound(aName) && anEntry != theObjectNames(aName)) {
471 // diff objects have same name - make a new name
472 TCollection_AsciiString aName2;
473 Standard_Integer i = 0;
475 aName2 = aName + "_" + ++i;
476 } while (theObjectNames.IsBound(aName2) && anEntry != theObjectNames(aName2));
478 theObjectNames(anEntry) = aName;
482 aName = geom->GetDumpName( anEntry.ToCString() );
483 if ( aName.IsEmpty() ) {
484 // ? Removed Object ?
486 aName = aBaseName + TCollection_AsciiString(++objectCounter);
487 } while (theObjectNames.IsBound(aName));
488 seqRemoved.Append(aName);
489 mapRemoved.Bind(anEntry, "1");
491 theObjectNames.Bind(anEntry, aName);
493 theObjectNames.Bind(aName, anEntry); // to detect same name of diff objects
495 anUpdatedScript += aName;
496 aNames.Bind(aName, "1");
497 aStart = aSeq->Value(i + 1) + 1;
500 // add final part of aScript
501 if (aSeq->Value(aLen) < aScriptLength)
502 anUpdatedScript += aScript.SubString(aSeq->Value(aLen) + 1, aScriptLength);
504 // Remove removed objects
505 anUpdatedScript += "\n\taStudyBuilder = theStudy.NewBuilder()";
506 for (int ir = 1; ir <= seqRemoved.Length(); ir++) {
507 anUpdatedScript += "\n\tSO = theStudy.FindObjectIOR(theStudy.ConvertObjectToIOR(";
508 anUpdatedScript += seqRemoved.Value(ir);
509 anUpdatedScript += "))\n\tif SO is not None: aStudyBuilder.RemoveObjectWithChildren(SO)";
511 anUpdatedScript += "\n";
514 anUpdatedScript += "\n\tisGUIMode = ";
515 anUpdatedScript += isPublished;
516 anUpdatedScript += "\n\tif isGUIMode:";
517 anUpdatedScript += "\n\t\tsmeshgui = salome.ImportComponentGUI(\"SMESH\")";
518 anUpdatedScript += "\n\t\tsmeshgui.Init(theStudy._get_StudyId())";
519 anUpdatedScript += "\n";
521 Resource_DataMapOfAsciiStringAsciiString mapEntries;
522 for (Standard_Integer i = 1; i <= aLen; i += 2) {
523 anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i + 1));
524 if (theObjectNames.IsBound(anEntry) &&
525 !mapEntries.IsBound(anEntry) &&
526 !mapRemoved.IsBound(anEntry)) {
527 aName = theObjectNames.Find(anEntry);
528 mapEntries.Bind(anEntry, aName);
529 anUpdatedScript += "\n\t\tsmeshgui.SetName(salome.ObjectToID(";
530 anUpdatedScript += aName + "), \"" + aName + "\")";
533 anUpdatedScript += "\n\n\t\tsalome.sg.updateObjBrowser(0)";
535 anUpdatedScript += "\n\n\tpass\n";
539 return anUpdatedScript;
542 //=============================================================================
546 //=============================================================================
547 TCollection_AsciiString SMESH_Gen_i::GetNewPythonLines (int theStudyID)
549 TCollection_AsciiString aScript;
551 // Dump trace of API methods calls
552 if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
553 Handle(TColStd_HSequenceOfAsciiString) aPythonScript = myPythonScripts[theStudyID];
554 Standard_Integer istr, aLen = aPythonScript->Length();
555 for (istr = 1; istr <= aLen; istr++) {
557 aScript += aPythonScript->Value(istr);
565 //=============================================================================
569 //=============================================================================
570 void SMESH_Gen_i::CleanPythonTrace (int theStudyID)
572 TCollection_AsciiString aScript;
574 // Clean trace of API methods calls
575 if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) {
576 myPythonScripts[theStudyID]->Clear();