Salome HOME
0021014: EDF 1583 SMESH: Improvement of the Python Dump for the creation of groups
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
24 // File      : SMESH_2smeshpy.cxx
25 // Created   : Fri Nov 18 13:20:10 2005
26 // Author    : Edward AGAPOV (eap)
27 //
28 #include "SMESH_2smeshpy.hxx"
29
30 #include "utilities.h"
31 #include "SMESH_PythonDump.hxx"
32 #include "SMESH_NoteBook.hxx"
33 #include "SMESH_Filter_i.hxx"
34
35 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
36
37 #include "SMESH_Gen_i.hxx"
38 /* SALOME headers that include CORBA headers that include windows.h 
39  * that defines GetObject symbol as GetObjectA should stand before SALOME headers
40  * that declare methods named GetObject - to apply the same rules of GetObject renaming
41  * and thus to avoid mess with GetObject symbol on Windows */
42
43 IMPLEMENT_STANDARD_HANDLE (_pyObject          ,Standard_Transient);
44 IMPLEMENT_STANDARD_HANDLE (_pyCommand         ,Standard_Transient);
45 IMPLEMENT_STANDARD_HANDLE (_pyGen             ,_pyObject);
46 IMPLEMENT_STANDARD_HANDLE (_pyMesh            ,_pyObject);
47 IMPLEMENT_STANDARD_HANDLE (_pySubMesh         ,_pyObject);
48 IMPLEMENT_STANDARD_HANDLE (_pyMeshEditor      ,_pyObject);
49 IMPLEMENT_STANDARD_HANDLE (_pyHypothesis      ,_pyObject);
50 IMPLEMENT_STANDARD_HANDLE (_pySelfEraser      ,_pyObject);
51 IMPLEMENT_STANDARD_HANDLE (_pyGroup           ,_pyObject);
52 IMPLEMENT_STANDARD_HANDLE (_pyFilter          ,_pyObject);
53 IMPLEMENT_STANDARD_HANDLE (_pyAlgorithm       ,_pyHypothesis);
54 IMPLEMENT_STANDARD_HANDLE (_pyComplexParamHypo,_pyHypothesis);
55 IMPLEMENT_STANDARD_HANDLE (_pyNumberOfSegmentsHyp,_pyHypothesis);
56
57 IMPLEMENT_STANDARD_RTTIEXT(_pyObject          ,Standard_Transient);
58 IMPLEMENT_STANDARD_RTTIEXT(_pyCommand         ,Standard_Transient);
59 IMPLEMENT_STANDARD_RTTIEXT(_pyGen             ,_pyObject);
60 IMPLEMENT_STANDARD_RTTIEXT(_pyMesh            ,_pyObject);
61 IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh         ,_pyObject);
62 IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor      ,_pyObject);
63 IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis      ,_pyObject);
64 IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser      ,_pyObject);
65 IMPLEMENT_STANDARD_RTTIEXT(_pyGroup           ,_pyObject);
66 IMPLEMENT_STANDARD_RTTIEXT(_pyFilter          ,_pyObject);
67 IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm       ,_pyHypothesis);
68 IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
69 IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
70 IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
71 IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
72
73 using namespace std;
74 using SMESH::TPythonDump;
75
76 /*!
77  * \brief Container of commands into which the initial script is split.
78  *        It also contains data coresponding to SMESH_Gen contents
79  */
80 static Handle(_pyGen) theGen;
81
82 static TCollection_AsciiString theEmptyString;
83
84 //#define DUMP_CONVERSION
85
86 #if !defined(_DEBUG_) && defined(DUMP_CONVERSION)
87 #undef DUMP_CONVERSION
88 #endif
89
90
91 namespace {
92
93   //================================================================================
94   /*!
95    * \brief Set of TCollection_AsciiString initialized by C array of C strings
96    */
97   //================================================================================
98
99   struct TStringSet: public set<TCollection_AsciiString>
100   {
101     /*!
102      * \brief Filling. The last string must be ""
103      */
104     void Insert(const char* names[]) {
105       for ( int i = 0; names[i][0] ; ++i )
106         insert( (char*) names[i] );
107     }
108     /*!
109      * \brief Check if a string is in
110      */
111     bool Contains(const TCollection_AsciiString& name ) {
112       return find( name ) != end();
113     }
114   };
115 }
116
117 //================================================================================
118 /*!
119  * \brief Convert python script using commands of smesh.py
120   * \param theScript - Input script
121   * \retval TCollection_AsciiString - Convertion result
122   *
123   * Class SMESH_2smeshpy declared in SMESH_PythonDump.hxx
124  */
125 //================================================================================
126
127 TCollection_AsciiString
128 SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
129                               Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
130                               Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
131 {
132   theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames );
133
134   // split theScript into separate commands
135
136   SMESH_NoteBook * aNoteBook = new SMESH_NoteBook();
137   
138   int from = 1, end = theScript.Length(), to;
139   while ( from < end && ( to = theScript.Location( "\n", from, end )))
140   {
141     if ( to != from )
142         // cut out and store a command
143         aNoteBook->AddCommand( theScript.SubString( from, to - 1 ));
144       from = to + 1;
145   }
146   
147   aNoteBook->ReplaceVariables();
148
149   TCollection_AsciiString aNoteScript = aNoteBook->GetResultScript();
150   delete aNoteBook;
151   aNoteBook = 0;
152   
153   // split theScript into separate commands
154   from = 1, end = aNoteScript.Length();
155   while ( from < end && ( to = aNoteScript.Location( "\n", from, end )))
156   {
157     if ( to != from )
158       // cut out and store a command
159       theGen->AddCommand( aNoteScript.SubString( from, to - 1 ));
160     from = to + 1;
161   }
162
163   // finish conversion
164   theGen->Flush();
165 #ifdef DUMP_CONVERSION
166   MESSAGE_BEGIN ( std::endl << " ######## RESULT ######## " << std::endl<< std::endl );
167 #endif
168
169   // reorder commands after conversion
170   list< Handle(_pyCommand) >::iterator cmd;
171   bool orderChanges;
172   do {
173     orderChanges = false;
174     for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd )
175       if ( (*cmd)->SetDependentCmdsAfter() )
176         orderChanges = true;
177   } while ( orderChanges );
178   
179   // concat commands back into a script
180   TCollection_AsciiString aScript;
181   for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd )
182   {
183 #ifdef DUMP_CONVERSION
184     MESSAGE_ADD ( "## COM " << (*cmd)->GetOrderNb() << ": "<< (*cmd)->GetString() << std::endl );
185 #endif
186     if ( !(*cmd)->IsEmpty() ) {
187       aScript += "\n";
188       aScript += (*cmd)->GetString();
189     }
190   }
191   aScript += "\n";
192
193   theGen.Nullify();
194
195   return aScript;
196 }
197
198 //================================================================================
199 /*!
200  * \brief _pyGen constructor
201  */
202 //================================================================================
203
204 _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
205                Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
206   : _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )),
207     myNbCommands( 0 ),
208     myID2AccessorMethod( theEntry2AccessorMethod ),
209     myObjectNames( theObjectNames ),
210     myNbFilters( 0 )
211 {
212   // make that GetID() to return TPythonDump::SMESHGenName()
213   GetCreationCmd()->GetString() += "=";
214 }
215
216 //================================================================================
217 /*!
218  * \brief name of SMESH_Gen in smesh.py
219  */
220 //================================================================================
221
222 const char* _pyGen::AccessorMethod() const
223 {
224   return SMESH_2smeshpy::GenName();
225 }
226
227 //================================================================================
228 /*!
229  * \brief Convert a command using a specific converter
230   * \param theCommand - the command to convert
231  */
232 //================================================================================
233
234 Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
235 {
236   // store theCommand in the sequence
237   myCommands.push_back( new _pyCommand( theCommand, ++myNbCommands ));
238
239   Handle(_pyCommand) aCommand = myCommands.back();
240 #ifdef DUMP_CONVERSION
241   MESSAGE ( "## COM " << myNbCommands << ": "<< aCommand->GetString() );
242 #endif
243
244   _pyID objID = aCommand->GetObject();
245
246   if ( objID.IsEmpty() )
247     return aCommand;
248
249   // Find an object to process theCommand
250
251   // SMESH_Gen method?
252   if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName()) {
253     this->Process( aCommand );
254     return aCommand;
255   }
256
257   // SMESH_Mesh method?
258   map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
259   if ( id_mesh != myMeshes.end() )
260   {
261     // check for mesh editor object
262     if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
263       _pyID editorID = aCommand->GetResultValue();
264       Handle(_pyMeshEditor) editor = new _pyMeshEditor( aCommand );
265       myMeshEditors.insert( make_pair( editorID, editor ));
266       return aCommand;
267     } 
268     // check for SubMesh objects
269     else if ( aCommand->GetMethod() == "GetSubMesh" ) { // SubMesh creation
270       _pyID subMeshID = aCommand->GetResultValue();
271       Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
272       myObjects.insert( make_pair( subMeshID, subMesh ));
273     }
274     
275     id_mesh->second->Process( aCommand );
276     return aCommand;
277   }
278
279   // SMESH_MeshEditor method?
280   map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID );
281   if ( id_editor != myMeshEditors.end() )
282   {
283     id_editor->second->Process( aCommand );
284     TCollection_AsciiString processedCommand = aCommand->GetString();
285     // some commands of SMESH_MeshEditor create meshes
286     if ( aCommand->GetMethod().Search("MakeMesh") != -1 ) {
287       Handle(_pyMesh) mesh = new _pyMesh( aCommand, aCommand->GetResultValue() );
288       aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
289       myMeshes.insert( make_pair( mesh->GetID(), mesh ));
290     }
291     if ( aCommand->GetMethod() == "MakeBoundaryMesh") {
292       _pyID meshID = aCommand->GetResultValue(0);
293       if ( !myMeshes.count( meshID ) )
294       {
295         Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID );
296         aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
297         myMeshes.insert( make_pair( meshID, mesh ));
298       }
299     }
300     return aCommand;
301   }
302   // SMESH_Hypothesis method?
303   list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
304   for ( ; hyp != myHypos.end(); ++hyp )
305     if ( !(*hyp)->IsAlgo() && objID == (*hyp)->GetID() ) {
306       (*hyp)->Process( aCommand );
307       return aCommand;
308     }
309
310   // aFilterManager.CreateFilter() ?
311   if ( aCommand->GetMethod() == "CreateFilter" )
312   {
313     // Set a more human readable name to a filter
314     // aFilter0x7fbf6c71cfb0 -> aFilter_nb
315     _pyID newID, filterID = aCommand->GetResultValue();
316     int pos = filterID.Search( "0x" );
317     if ( pos > 1 )
318       newID = (filterID.SubString(1,pos-1) + "_") + _pyID( ++myNbFilters );
319
320     Handle(_pyObject) filter( new _pyFilter( aCommand, newID ));
321     AddObject( filter );
322   }
323
324   // other object method?
325   map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.find( objID );
326   if ( id_obj != myObjects.end() ) {
327     id_obj->second->Process( aCommand );
328     return aCommand;
329   }
330
331   // Add access to a wrapped mesh
332   AddMeshAccessorMethod( aCommand );
333
334   // Add access to a wrapped algorithm
335   //  AddAlgoAccessorMethod( aCommand ); // ??? what if algo won't be wrapped at all ???
336
337   // PAL12227. PythonDump was not updated at proper time; result is
338   //     aCriteria.append(SMESH.Filter.Criterion(17,26,0,'L1',26,25,1e-07,SMESH.EDGE,-1))
339   // TypeError: __init__() takes exactly 11 arguments (10 given)
340   const char wrongCommand[] = "SMESH.Filter.Criterion(";
341   if ( int beg = theCommand.Location( wrongCommand, 1, theCommand.Length() ))
342   {
343     _pyCommand tmpCmd( theCommand.SubString( beg, theCommand.Length() ), -1);
344     // there must be 10 arguments, 5-th arg ThresholdID is missing,
345     const int wrongNbArgs = 9, missingArg = 5;
346     if ( tmpCmd.GetNbArgs() == wrongNbArgs )
347     {
348       for ( int i = wrongNbArgs; i > missingArg; --i )
349         tmpCmd.SetArg( i + 1, tmpCmd.GetArg( i ));
350       tmpCmd.SetArg(  missingArg, "''");
351       aCommand->GetString().Trunc( beg - 1 );
352       aCommand->GetString() += tmpCmd.GetString();
353     }
354     // IMP issue 0021014
355     // set GetCriterion(elementType,CritType,Compare,Treshold,UnaryOp,BinaryOp,Tolerance)
356     //                  1           2        3       4        5       6        7
357     // instead of "SMESH.Filter.Criterion(
358     // Type,Compare,Threshold,ThresholdStr,ThresholdID,UnaryOp,BinaryOp,Tolerance,TypeOfElement,Precision)
359     // 1    2       3         4            5           6       7        8         9             10
360     // in order to avoid the problem of type mismatch of long and FunctorType
361     const TCollection_AsciiString
362       SMESH("SMESH."), dfltFunctor = "SMESH.FT_Undefined", dftlTol = "1e-07", dftlPreci = "-1";
363     TCollection_AsciiString
364       Type          = aCommand->GetArg(1),  // long
365       Compare       = aCommand->GetArg(2),  // long
366       Threshold     = aCommand->GetArg(3),  // double
367       ThresholdStr  = aCommand->GetArg(4),  // string
368       ThresholdID   = aCommand->GetArg(5),  // string
369       UnaryOp       = aCommand->GetArg(6),  // long
370       BinaryOp      = aCommand->GetArg(7),  // long
371       Tolerance     = aCommand->GetArg(8),  // double
372       TypeOfElement = aCommand->GetArg(9),  // ElementType
373       Precision     = aCommand->GetArg(10); // long
374     Type     = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Type.IntegerValue() ));
375     Compare  = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Compare.IntegerValue() ));
376     UnaryOp  = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( UnaryOp.IntegerValue() ));
377     BinaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( BinaryOp.IntegerValue() ));
378
379     aCommand->RemoveArgs();
380     aCommand->SetObject( SMESH_2smeshpy::GenName() );
381     aCommand->SetMethod( "GetCriterion" );
382
383     aCommand->SetArg( 1, TypeOfElement );
384     aCommand->SetArg( 2, Type );
385     aCommand->SetArg( 3, Compare );
386
387     if ( Type == "SMESH.FT_ElemGeomType" && Threshold.IsIntegerValue() )
388     {
389       // set SMESH.GeometryType instead of a numerical Threshold
390       const char* types[SMESH::Geom_POLYHEDRA+1] = {
391         "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
392         "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_POLYHEDRA"
393       };
394       int iGeom = Threshold.IntegerValue();
395       if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 )
396         Threshold = SMESH + types[ iGeom ];
397     }
398     if ( ThresholdStr.Length() != 2 ) // not '' or ""
399       aCommand->SetArg( 4, ThresholdStr );
400     else if ( ThresholdID.Length() != 2 )
401       aCommand->SetArg( 4, ThresholdID );
402     else
403       aCommand->SetArg( 4, Threshold );
404     // find the last not default arg
405     int lastDefault = 8;
406     if ( Tolerance == dftlTol ) {
407       lastDefault = 7;
408       if ( BinaryOp == dfltFunctor ) {
409         lastDefault = 6;
410         if ( UnaryOp == dfltFunctor )
411           lastDefault = 5;
412       }
413     }
414     if ( 5 < lastDefault ) aCommand->SetArg( 5, UnaryOp );
415     if ( 6 < lastDefault ) aCommand->SetArg( 6, BinaryOp );
416     if ( 7 < lastDefault ) aCommand->SetArg( 7, Tolerance );
417     if ( Precision != dftlPreci )
418     {
419       TCollection_AsciiString crit = aCommand->GetResultValue();
420       aCommand->GetString() += "; ";
421       aCommand->GetString() += crit + ".Precision = " + Precision;
422     }
423   }
424   return aCommand;
425 }
426
427 //================================================================================
428 /*!
429  * \brief Convert the command or remember it for later conversion
430   * \param theCommand - The python command calling a method of SMESH_Gen
431  */
432 //================================================================================
433
434 void _pyGen::Process( const Handle(_pyCommand)& theCommand )
435 {
436   // there are methods to convert:
437   // CreateMesh( shape )
438   // Concatenate( [mesh1, ...], ... )
439   // CreateHypothesis( theHypType, theLibName )
440   // Compute( mesh, geom )
441   // Evaluate( mesh, geom )
442   // mesh creation
443   TCollection_AsciiString method = theCommand->GetMethod();
444
445   if ( method == "CreateMesh" || method == "CreateEmptyMesh")
446   {
447     Handle(_pyMesh) mesh = new _pyMesh( theCommand );
448     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
449     return;
450   }
451   if ( method == "CreateMeshesFromUNV" ||
452        method == "CreateMeshesFromSTL" ||
453        method == "CreateMeshesFromCGNS" ||
454        method == "CopyMesh" )
455   {
456     Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
457     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
458     return;
459   }
460   if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV")
461   {
462     for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
463     {
464       Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind));
465       myMeshes.insert( make_pair( theCommand->GetResultValue(ind), mesh ));
466     }
467   }
468
469   // CreateHypothesis()
470   if ( method == "CreateHypothesis" )
471   {
472     // issue 199929, remove standard library name (default parameter)
473     const TCollection_AsciiString & aLibName = theCommand->GetArg( 2 );
474     if ( aLibName.Search( "StdMeshersEngine" ) != -1 ) {
475       // keep first argument
476       TCollection_AsciiString arg = theCommand->GetArg( 1 );
477       theCommand->RemoveArgs();
478       theCommand->SetArg( 1, arg );
479     }
480
481     myHypos.push_back( _pyHypothesis::NewHypothesis( theCommand ));
482     return;
483   }
484
485   // smeshgen.Compute( mesh, geom ) --> mesh.Compute()
486   if ( method == "Compute" )
487   {
488     const _pyID& meshID = theCommand->GetArg( 1 );
489     map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
490     if ( id_mesh != myMeshes.end() ) {
491       theCommand->SetObject( meshID );
492       theCommand->RemoveArgs();
493       id_mesh->second->Flush();
494       return;
495     }
496   }
497
498   // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom)
499   if ( method == "Evaluate" )
500   {
501     const _pyID& meshID = theCommand->GetArg( 1 );
502     map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
503     if ( id_mesh != myMeshes.end() ) {
504       theCommand->SetObject( meshID );
505       _pyID geom = theCommand->GetArg( 2 );
506       theCommand->RemoveArgs();
507       theCommand->SetArg( 1, geom );
508       return;
509     }
510   }
511
512   // objects erasing creation command if no more it's commands invoked:
513   // SMESH_Pattern, FilterManager
514   if ( method == "GetPattern" ||
515        method == "CreateFilterManager" ||
516        method == "CreateMeasurements" ) {
517     Handle(_pyObject) obj = new _pySelfEraser( theCommand );
518     if ( !myObjects.insert( make_pair( obj->GetID(), obj )).second )
519       theCommand->Clear(); // already created
520   }
521
522   // Concatenate( [mesh1, ...], ... )
523   if ( method == "Concatenate" || method == "ConcatenateWithGroups")
524   {
525     if ( method == "ConcatenateWithGroups" ) {
526       theCommand->SetMethod( "Concatenate" );
527       theCommand->SetArg( theCommand->GetNbArgs() + 1, "True" );
528     }
529     Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
530     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
531     AddMeshAccessorMethod( theCommand );
532   }
533
534   // Replace name of SMESH_Gen
535
536   // names of SMESH_Gen methods fully equal to methods defined in smesh.py
537   static TStringSet smeshpyMethods;
538   if ( smeshpyMethods.empty() ) {
539     const char * names[] =
540       { "SetEmbeddedMode","IsEmbeddedMode","SetCurrentStudy","GetCurrentStudy",
541         "GetPattern","GetSubShapesId",
542         "" }; // <- mark of array end
543     smeshpyMethods.Insert( names );
544   }
545   if ( smeshpyMethods.Contains( theCommand->GetMethod() ))
546     // smeshgen.Method() --> smesh.Method()
547     theCommand->SetObject( SMESH_2smeshpy::SmeshpyName() );
548   else
549     // smeshgen.Method() --> smesh.smesh.Method()
550     theCommand->SetObject( SMESH_2smeshpy::GenName() );
551 }
552
553 //================================================================================
554 /*!
555  * \brief Convert the remembered commands
556  */
557 //================================================================================
558
559 void _pyGen::Flush()
560 {
561   // create empty command
562   myLastCommand = new _pyCommand();
563
564   map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin();
565   for ( ; id_mesh != myMeshes.end(); ++id_mesh )
566     if ( ! id_mesh->second.IsNull() )
567       id_mesh->second->Flush();
568
569   list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
570   for ( ; hyp != myHypos.end(); ++hyp )
571     if ( !hyp->IsNull() ) {
572       (*hyp)->Flush();
573       // smeshgen.CreateHypothesis() --> smesh.smesh.CreateHypothesis()
574       if ( !(*hyp)->IsWrapped() )
575         (*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() );
576     }
577
578   map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.begin();
579   for ( ; id_obj != myObjects.end(); ++id_obj )
580     if ( ! id_obj->second.IsNull() )
581       id_obj->second->Flush();
582
583   myLastCommand->SetOrderNb( ++myNbCommands );
584   myCommands.push_back( myLastCommand );
585 }
586
587 //================================================================================
588 /*!
589  * \brief Add access method to mesh that is an argument
590   * \param theCmd - command to add access method
591   * \retval bool - true if added
592  */
593 //================================================================================
594
595 bool _pyGen::AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const
596 {
597   bool added = false;
598   map< _pyID, Handle(_pyMesh) >::const_iterator id_mesh = myMeshes.begin();
599   for ( ; id_mesh != myMeshes.end(); ++id_mesh ) {
600     if ( theCmd->AddAccessorMethod( id_mesh->first, id_mesh->second->AccessorMethod() ))
601       added = true;
602   }
603   return added;
604 }
605
606 //================================================================================
607 /*!
608  * \brief Add access method to algo that is an object or an argument
609   * \param theCmd - command to add access method
610   * \retval bool - true if added
611  */
612 //================================================================================
613
614 bool _pyGen::AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const
615 {
616   bool added = false;
617   list< Handle(_pyHypothesis) >::const_iterator hyp = myHypos.begin();
618   for ( ; hyp != myHypos.end(); ++hyp ) {
619     if ( (*hyp)->IsAlgo() && /*(*hyp)->IsWrapped() &&*/
620          theCmd->AddAccessorMethod( (*hyp)->GetID(), (*hyp)->AccessorMethod() ))
621       added = true;
622   }
623   return added;
624 }
625
626 //================================================================================
627 /*!
628  * \brief Find hypothesis by ID (entry)
629   * \param theHypID - The hypothesis ID
630   * \retval Handle(_pyHypothesis) - The found hypothesis
631  */
632 //================================================================================
633
634 Handle(_pyHypothesis) _pyGen::FindHyp( const _pyID& theHypID )
635 {
636   list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
637   for ( ; hyp != myHypos.end(); ++hyp )
638     if ( !hyp->IsNull() && theHypID == (*hyp)->GetID() )
639       return *hyp;
640   return Handle(_pyHypothesis)();
641 }
642
643 //================================================================================
644 /*!
645  * \brief Find algorithm the created algorithm
646   * \param theGeom - The shape ID the algorithm was created on
647   * \param theMesh - The mesh ID that created the algorithm
648   * \param dim - The algo dimension
649   * \retval Handle(_pyHypothesis) - The found algo
650  */
651 //================================================================================
652
653 Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
654                                         const Handle(_pyHypothesis)& theHypothesis )
655 {
656   list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
657   for ( ; hyp != myHypos.end(); ++hyp )
658     if ( !hyp->IsNull() &&
659          (*hyp)->IsAlgo() &&
660          theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) &&
661          (*hyp)->GetGeom() == theGeom &&
662          (*hyp)->GetMesh() == theMesh )
663       return *hyp;
664   return 0;
665 }
666
667 //================================================================================
668 /*!
669  * \brief Find subMesh by ID (entry)
670   * \param theSubMeshID - The subMesh ID
671   * \retval Handle(_pySubMesh) - The found subMesh
672  */
673 //================================================================================
674
675 Handle(_pySubMesh) _pyGen::FindSubMesh( const _pyID& theSubMeshID )
676 {
677   map< _pyID, Handle(_pyObject) >::iterator id_subMesh = myObjects.find(theSubMeshID);
678   if ( id_subMesh != myObjects.end() )
679     return Handle(_pySubMesh)::DownCast( id_subMesh->second );
680   return Handle(_pySubMesh)();
681 }
682
683
684 //================================================================================
685 /*!
686  * \brief Change order of commands in the script
687   * \param theCmd1 - One command
688   * \param theCmd2 - Another command
689  */
690 //================================================================================
691
692 void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 )
693 {
694   list< Handle(_pyCommand) >::iterator pos1, pos2;
695   pos1 = find( myCommands.begin(), myCommands.end(), theCmd1 );
696   pos2 = find( myCommands.begin(), myCommands.end(), theCmd2 );
697   myCommands.insert( pos1, theCmd2 );
698   myCommands.insert( pos2, theCmd1 );
699   myCommands.erase( pos1 );
700   myCommands.erase( pos2 );
701
702   int nb1 = theCmd1->GetOrderNb();
703   theCmd1->SetOrderNb( theCmd2->GetOrderNb() );
704   theCmd2->SetOrderNb( nb1 );
705 //   cout << "BECOME " << theCmd1->GetOrderNb() << "\t" << theCmd1->GetString() << endl
706 //        << "BECOME " << theCmd2->GetOrderNb() << "\t" << theCmd2->GetString() << endl << endl;
707 }
708
709 //================================================================================
710 /*!
711  * \brief Set one command after the other
712   * \param theCmd - Command to move
713   * \param theAfterCmd - Command ater which to insert the first one
714  */
715 //================================================================================
716
717 void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd )
718 {
719   setNeighbourCommand( theCmd, theAfterCmd, true );
720 }
721
722 //================================================================================
723 /*!
724  * \brief Set one command before the other
725   * \param theCmd - Command to move
726   * \param theBeforeCmd - Command before which to insert the first one
727  */
728 //================================================================================
729
730 void _pyGen::SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) theBeforeCmd )
731 {
732   setNeighbourCommand( theCmd, theBeforeCmd, false );
733 }
734
735 //================================================================================
736 /*!
737  * \brief Set one command before or after the other
738   * \param theCmd - Command to move
739   * \param theOtherCmd - Command ater or before which to insert the first one
740  */
741 //================================================================================
742
743 void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd,
744                                   Handle(_pyCommand)& theOtherCmd,
745                                   const bool theIsAfter )
746 {
747   list< Handle(_pyCommand) >::iterator pos;
748   pos = find( myCommands.begin(), myCommands.end(), theCmd );
749   myCommands.erase( pos );
750   pos = find( myCommands.begin(), myCommands.end(), theOtherCmd );
751   myCommands.insert( (theIsAfter ? ++pos : pos), theCmd );
752
753   int i = 1;
754   for ( pos = myCommands.begin(); pos != myCommands.end(); ++pos)
755     (*pos)->SetOrderNb( i++ );
756 }
757
758 //================================================================================
759 /*!
760  * \brief Set command be last in list of commands
761   * \param theCmd - Command to be last
762  */
763 //================================================================================
764
765 Handle(_pyCommand)& _pyGen::GetLastCommand()
766 {
767   return myLastCommand;
768 }
769
770 //================================================================================
771 /*!
772  * \brief Set method to access to object wrapped with python class
773   * \param theID - The wrapped object entry
774   * \param theMethod - The accessor method
775  */
776 //================================================================================
777
778 void _pyGen::SetAccessorMethod(const _pyID& theID, const char* theMethod )
779 {
780   myID2AccessorMethod.Bind( theID, (char*) theMethod );
781 }
782
783 //================================================================================
784 /*!
785  * \brief Generated new ID for object and assign with existing name
786   * \param theID - ID of existing object
787  */
788 //================================================================================
789
790 _pyID _pyGen::GenerateNewID( const _pyID& theID )
791 {
792   int index = 1;
793   _pyID aNewID;
794   do {
795     aNewID = theID + _pyID( ":" ) + _pyID( index++ );
796   }
797   while ( myObjectNames.IsBound( aNewID ) );
798
799   myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID )
800                       ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
801                       : _pyID( "A" ) + aNewID );
802   return aNewID;
803 }
804
805 //================================================================================
806 /*!
807  * \brief Stores theObj in myObjects
808  */
809 //================================================================================
810
811 void _pyGen::AddObject( Handle(_pyObject)& theObj )
812 {
813   myObjects.insert( make_pair( theObj->GetID(), theObj ));
814 }
815
816 //================================================================================
817 /*!
818  * \brief Finds a _pyObject by ID
819  */
820 //================================================================================
821
822 Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID )  const
823 {
824   std::map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.find( theObjID );
825   return ( id_obj == myObjects.end() ) ? Handle(_pyObject)() : id_obj->second;
826 }
827   
828 //================================================================================
829 /*!
830  * \brief Find out type of geom group
831   * \param grpID - The geom group entry
832   * \retval int - The type
833  */
834 //================================================================================
835
836 // static bool sameGroupType( const _pyID&                   grpID,
837 //                            const TCollection_AsciiString& theType)
838 // {
839 //   // define group type as smesh.Mesh.Group() does
840 //   int type = -1;
841 //   SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
842 //   SALOMEDS::SObject_var aSObj = study->FindObjectID( grpID.ToCString() );
843 //   if ( !aSObj->_is_nil() ) {
844 //     GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aSObj->GetObject() );
845 //     if ( !aGeomObj->_is_nil() ) {
846 //       switch ( aGeomObj->GetShapeType() ) {
847 //       case GEOM::VERTEX: type = SMESH::NODE; break;
848 //       case GEOM::EDGE:   type = SMESH::EDGE; break;
849 //       case GEOM::FACE:   type = SMESH::FACE; break;
850 //       case GEOM::SOLID:
851 //       case GEOM::SHELL:  type = SMESH::VOLUME; break;
852 //       case GEOM::COMPOUND: {
853 //         GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine();
854 //         if ( !aGeomGen->_is_nil() ) {
855 //           GEOM::GEOM_IGroupOperations_var aGrpOp =
856 //             aGeomGen->GetIGroupOperations( study->StudyId() );
857 //           if ( !aGrpOp->_is_nil() ) {
858 //             switch ( aGrpOp->GetType( aGeomObj )) {
859 //             case TopAbs_VERTEX: type = SMESH::NODE; break;
860 //             case TopAbs_EDGE:   type = SMESH::EDGE; break;
861 //             case TopAbs_FACE:   type = SMESH::FACE; break;
862 //             case TopAbs_SOLID:  type = SMESH::VOLUME; break;
863 //             default:;
864 //             }
865 //           }
866 //         }
867 //       }
868 //       default:;
869 //       }
870 //     }
871 //   }
872 //   if ( type < 0 ) {
873 //     MESSAGE("Type of the group " << grpID << " not found");
874 //     return false;
875 //   }
876 //   if ( theType.IsIntegerValue() )
877 //     return type == theType.IntegerValue();
878
879 //   switch ( type ) {
880 //   case SMESH::NODE:   return theType.Location( "NODE", 1, theType.Length() );
881 //   case SMESH::EDGE:   return theType.Location( "EDGE", 1, theType.Length() );
882 //   case SMESH::FACE:   return theType.Location( "FACE", 1, theType.Length() );
883 //   case SMESH::VOLUME: return theType.Location( "VOLUME", 1, theType.Length() );
884 //   default:;
885 //   }
886 //   return false;
887 // }
888
889 //================================================================================
890 /*!
891  * \brief
892   * \param theCreationCmd -
893  */
894 //================================================================================
895
896 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd)
897   : _pyObject(theCreationCmd), myHasEditor(false)
898 {
899   // convert my creation command
900   Handle(_pyCommand) creationCmd = GetCreationCmd();
901   //TCollection_AsciiString str = creationCmd->GetMethod();
902 //   if(str != "CreateMeshesFromUNV" &&
903 //      str != "CreateMeshesFromMED" &&
904 //      str != "CreateMeshesFromSTL")
905   creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
906   creationCmd->SetMethod( "Mesh" );
907
908   theGen->SetAccessorMethod( GetID(), "GetMesh()" );
909 }
910
911 //================================================================================
912 /*!
913  * \brief
914   * \param theCreationCmd -
915  */
916 //================================================================================
917 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString& id):
918   _pyObject(theCreationCmd), myHasEditor(false)
919 {
920   // convert my creation command
921   Handle(_pyCommand) creationCmd = GetCreationCmd();
922   creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
923   theGen->SetAccessorMethod( id, "GetMesh()" );
924 }
925
926 //================================================================================
927 /*!
928  * \brief Convert an IDL API command of SMESH::SMESH_Mesh to a method call of python Mesh
929   * \param theCommand - Engine method called for this mesh
930  */
931 //================================================================================
932
933 void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
934 {
935   // some methods of SMESH_Mesh interface needs special conversion
936   // to methods of Mesh python class
937   //
938   // 1. GetSubMesh(geom, name) + AddHypothesis(geom, algo)
939   //     --> in Mesh_Algorithm.Create(mesh, geom, hypo, so)
940   // 2. AddHypothesis(geom, hyp)
941   //     --> in Mesh_Algorithm.Hypothesis(hyp, args, so)
942   // 3. CreateGroupFromGEOM(type, name, grp)
943   //     --> in Mesh.Group(grp, name="")
944   // 4. ExportToMED(f, auto_groups, version)
945   //     --> in Mesh.ExportMED( f, auto_groups, version )
946   // 5. etc
947
948   const TCollection_AsciiString method = theCommand->GetMethod();
949   // ----------------------------------------------------------------------
950   if ( method == "GetSubMesh" ) { // collect submeshes of the mesh
951     Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
952     if ( !subMesh.IsNull() ) {
953       subMesh->SetCreator( this );
954       mySubmeshes.push_back( subMesh );
955     }
956   }
957   // ----------------------------------------------------------------------
958   else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
959     myAddHypCmds.push_back( theCommand );
960     // set mesh to hypo
961     const _pyID& hypID = theCommand->GetArg( 2 );
962     Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
963     if ( !hyp.IsNull() ) {
964       myHypos.push_back( hyp );
965       if ( hyp->GetMesh().IsEmpty() )
966         hyp->SetMesh( this->GetID() );
967     }
968   }
969   // ----------------------------------------------------------------------
970   else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp)
971     _pyID grp = theCommand->GetArg( 3 );
972     // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump
973     // next if(){...} section is commented
974     //if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp)
975     //  theCommand->SetMethod( "Group" );
976     //  theCommand->RemoveArgs();
977     //  theCommand->SetArg( 1, grp );
978     //}
979     //else {
980     // ------------------------->>>>> GroupOnGeom( grp, name, typ )
981       _pyID type = theCommand->GetArg( 1 );
982       _pyID name = theCommand->GetArg( 2 );
983       theCommand->SetMethod( "GroupOnGeom" );
984       theCommand->RemoveArgs();
985       theCommand->SetArg( 1, grp );
986       theCommand->SetArg( 2, name );
987       theCommand->SetArg( 3, type );
988     //}
989   }
990   // ----------------------------------------------------------------------
991   else if ( method == "CreateGroupFromFilter" ) // --> GroupOnFilter()
992   {
993     theCommand->SetMethod( "GroupOnFilter" );
994     // GroupOnFilter(typ, name, aFilter0x4743dc0 -> aFilter_1)
995     _pyID filterID = theCommand->GetArg(3);
996     Handle(_pyObject) filter = theGen->FindObject( filterID );
997     if ( !filter.IsNull() && filter->IsKind(STANDARD_TYPE(_pyFilter)))
998       filter->Process( theCommand );
999   }
1000   // ----------------------------------------------------------------------
1001   else if ( method == "GetIdsFromFilter" )
1002   {
1003     // GetIdsFromFilter( aFilter0x4743dc0) -> GetIdsFromFilter( aFilter_1)
1004     _pyID filterID = theCommand->GetArg(1);
1005     Handle(_pyObject) filter = theGen->FindObject( filterID );
1006     if ( !filter.IsNull() && filter->IsKind(STANDARD_TYPE(_pyFilter)))
1007       filter->Process( theCommand );
1008   }
1009   // ----------------------------------------------------------------------
1010   else if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup()
1011   {
1012     theCommand->SetMethod( "CreateEmptyGroup" );
1013     Handle(_pyGroup) group = new _pyGroup( theCommand );
1014     theGen->AddObject( group );
1015   }
1016   // ----------------------------------------------------------------------
1017   else if ( method == "ExportToMED" ||   // ExportToMED()  --> ExportMED()
1018             method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
1019     theCommand->SetMethod( "ExportMED" );
1020   }
1021   // ----------------------------------------------------------------------
1022   else if ( method == "ExportCGNS" )
1023   { // ExportCGNS(part, ...) -> ExportCGNS(..., part)
1024     _pyID partID = theCommand->GetArg( 1 );
1025     int nbArgs = theCommand->GetNbArgs();
1026     for ( int i = 2; i <= nbArgs; ++i )
1027       theCommand->SetArg( i-1, theCommand->GetArg( i ));
1028     theCommand->SetArg( nbArgs, partID );
1029   }
1030   // ----------------------------------------------------------------------
1031   else if ( method.Location( "ExportPartTo", 1, method.Length() ) == 1 )
1032   { // ExportPartTo*(part, ...) -> Export*(..., part)
1033     //
1034     // remove "PartTo" from the method
1035     TCollection_AsciiString newMethod = method;
1036     newMethod.Remove( 7, 6 );
1037     theCommand->SetMethod( newMethod );
1038     // make the 1st arg be the last one
1039     _pyID partID = theCommand->GetArg( 1 );
1040     int nbArgs = theCommand->GetNbArgs();
1041     for ( int i = 2; i <= nbArgs; ++i )
1042       theCommand->SetArg( i-1, theCommand->GetArg( i ));
1043     theCommand->SetArg( nbArgs, partID );
1044   }
1045   // ----------------------------------------------------------------------
1046   else if ( method == "RemoveHypothesis" ) // (geom, hyp)
1047   {
1048     _pyID hypID = theCommand->GetArg( 2 );
1049
1050     // check if this mesh still has corresponding addition command
1051     bool hasAddCmd = false;
1052     list< Handle(_pyCommand) >::iterator cmd = myAddHypCmds.begin();
1053     while ( cmd != myAddHypCmds.end() )
1054     {
1055       // AddHypothesis(geom, hyp)
1056       if ( hypID == (*cmd)->GetArg( 2 )) { // erase both (add and remove) commands
1057         theCommand->Clear();
1058         (*cmd)->Clear();
1059         cmd = myAddHypCmds.erase( cmd );
1060         hasAddCmd = true;
1061       }
1062       else {
1063         ++cmd;
1064       }
1065     }
1066     Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
1067     if ( ! hasAddCmd && hypID.Length() != 0 ) { // hypo addition already wrapped
1068       // RemoveHypothesis(geom, hyp) --> RemoveHypothesis( hyp, geom=0 )
1069       _pyID geom = theCommand->GetArg( 1 );
1070       theCommand->RemoveArgs();
1071       theCommand->SetArg( 1, hypID );
1072       if ( geom != GetGeom() )
1073         theCommand->SetArg( 2, geom );
1074     }
1075     // remove hyp from myHypos
1076     myHypos.remove( hyp );
1077   }
1078   // check for SubMesh order commands
1079   else if ( theCommand->GetMethod() == "GetMeshOrder" ||
1080             theCommand->GetMethod() == "SetMeshOrder" )
1081   {
1082     // make commands GetSubMesh() returning sub-meshes be before using sub-meshes
1083     // by GetMeshOrder() and SetMeshOrder(), since by defalut GetSubMesh()
1084     // commands are moved at the end of the script
1085     const bool isArg = theCommand->GetMethod() == "SetMeshOrder";
1086     const TCollection_AsciiString& cmdStr = theCommand->GetString();
1087     int begPos = (/*isArg ? cmdStr.Search( "(" ) :*/ cmdStr.Search( "[" )) + 1;
1088     int endPos = (isArg ? cmdStr.Search( ")" ) : cmdStr.Search( "=" )) - 1;
1089     if ( begPos != -1 && begPos < endPos && endPos <= cmdStr.Length() ) {
1090       TCollection_AsciiString aSubStr = cmdStr.SubString( begPos, endPos );
1091       Standard_Integer index = 1;
1092       TCollection_AsciiString anIDStr = aSubStr.Token("\t ,[]", index++);
1093       while ( !anIDStr.IsEmpty() ) {
1094         Handle(_pySubMesh) subMesh = theGen->FindSubMesh( anIDStr );
1095         if ( !subMesh.IsNull() )
1096           subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand
1097         anIDStr = aSubStr.Token("\t ,[]", index++);
1098       }
1099     }
1100   }
1101   // add accessor method if necessary
1102   else
1103   {
1104     if ( NeedMeshAccess( theCommand ))
1105       // apply theCommand to the mesh wrapped by smeshpy mesh
1106       AddMeshAccess( theCommand );
1107   }
1108 }
1109
1110 //================================================================================
1111 /*!
1112  * \brief Return True if addition of accesor method is needed
1113  */
1114 //================================================================================
1115
1116 bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
1117 {
1118   // names of SMESH_Mesh methods fully equal to methods of python class Mesh,
1119   // so no conversion is needed for them at all:
1120   static TStringSet sameMethods;
1121   if ( sameMethods.empty() ) {
1122     const char * names[] =
1123       { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents",
1124         "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog",
1125         "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements",
1126         "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles",
1127         "NbTrianglesOfOrder","NbQuadrangles","NbQuadranglesOfOrder","NbPolygons","NbVolumes",
1128         "NbVolumesOfOrder","NbTetras","NbTetrasOfOrder","NbHexas","NbHexasOfOrder",
1129         "NbPyramids","NbPyramidsOfOrder","NbPrisms","NbPrismsOfOrder","NbPolyhedrons",
1130         "NbSubMesh","GetElementsId","GetElementsByType","GetNodesId","GetElementType",
1131         "GetSubMeshElementsId","GetSubMeshNodesId","GetSubMeshElementType","Dump","GetNodeXYZ",
1132         "GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes",
1133         "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces",
1134         "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor",
1135         "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder"
1136         ,"" }; // <- mark of end
1137     sameMethods.Insert( names );
1138   }
1139
1140   return !sameMethods.Contains( theCommand->GetMethod() );
1141 }
1142
1143 //================================================================================
1144 /*!
1145  * \brief Convert creation and addition of all algos and hypos
1146  */
1147 //================================================================================
1148
1149 void _pyMesh::Flush()
1150 {
1151   list < Handle(_pyCommand) >::iterator cmd;
1152
1153   // try to convert algo addition like this:
1154   // mesh.AddHypothesis(geom, ALGO ) --> ALGO = mesh.Algo()
1155   for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
1156   {
1157     Handle(_pyCommand) addCmd = *cmd;
1158
1159     _pyID algoID = addCmd->GetArg( 2 );
1160     Handle(_pyHypothesis) algo = theGen->FindHyp( algoID );
1161     if ( algo.IsNull() || !algo->IsAlgo() )
1162       continue;
1163
1164     // check and create new algorithm instance if it is already wrapped
1165     if ( algo->IsWrapped() ) {
1166       _pyID localAlgoID = theGen->GenerateNewID( algoID );
1167       TCollection_AsciiString aNewCmdStr = localAlgoID +
1168         TCollection_AsciiString( " = " ) + theGen->GetID() +
1169         TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
1170         TCollection_AsciiString( "\" )" );
1171
1172       Handle(_pyCommand) newCmd = theGen->AddCommand( aNewCmdStr );
1173       Handle(_pyAlgorithm) newAlgo = Handle(_pyAlgorithm)::DownCast(theGen->FindHyp( localAlgoID ));
1174       if ( !newAlgo.IsNull() ) {
1175         newAlgo->Assign( algo, this->GetID() );
1176         newAlgo->SetCreationCmd( newCmd );
1177         algo = newAlgo;
1178         // set algorithm creation
1179         theGen->SetCommandBefore( newCmd, addCmd );
1180       }
1181       else
1182         newCmd->Clear();
1183     }
1184     _pyID geom = addCmd->GetArg( 1 );
1185     bool isLocalAlgo = ( geom != GetGeom() );
1186
1187     // try to convert
1188     if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK
1189     {
1190       // wrapped algo is created atfer mesh creation
1191       GetCreationCmd()->AddDependantCmd( addCmd );
1192
1193       if ( isLocalAlgo ) {
1194         // mesh.AddHypothesis(geom, ALGO ) --> mesh.AlgoMethod(geom)
1195         addCmd->SetArg( addCmd->GetNbArgs() + 1,
1196                         TCollection_AsciiString( "geom=" ) + geom );
1197         // sm = mesh.GetSubMesh(geom, name) --> sm = ALGO.GetSubMesh()
1198         list < Handle(_pySubMesh) >::iterator smIt;
1199         for ( smIt = mySubmeshes.begin(); smIt != mySubmeshes.end(); ++smIt ) {
1200           Handle(_pySubMesh) subMesh = *smIt;
1201           Handle(_pyCommand) subCmd = subMesh->GetCreationCmd();
1202           if ( geom == subCmd->GetArg( 1 )) {
1203             subCmd->SetObject( algo->GetID() );
1204             subCmd->RemoveArgs();
1205             subMesh->SetCreator( algo );
1206           }
1207         }
1208       }
1209     }
1210     else // KO - ALGO was already created
1211     {
1212       // mesh.AddHypothesis(geom, ALGO) --> mesh.AddHypothesis(ALGO, geom=0)
1213       addCmd->RemoveArgs();
1214       addCmd->SetArg( 1, algoID );
1215       if ( isLocalAlgo )
1216         addCmd->SetArg( 2, geom );
1217     }
1218   }
1219
1220   // try to convert hypo addition like this:
1221   // mesh.AddHypothesis(geom, HYPO ) --> HYPO = algo.Hypo()
1222   for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
1223   {
1224     Handle(_pyCommand) addCmd = *cmd;
1225     _pyID hypID = addCmd->GetArg( 2 );
1226     Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
1227     if ( hyp.IsNull() || hyp->IsAlgo() )
1228       continue;
1229     bool converted = hyp->Addition2Creation( addCmd, this->GetID() );
1230     if ( !converted ) {
1231       // mesh.AddHypothesis(geom, HYP) --> mesh.AddHypothesis(HYP, geom=0)
1232       _pyID geom = addCmd->GetArg( 1 );
1233       addCmd->RemoveArgs();
1234       addCmd->SetArg( 1, hypID );
1235       if ( geom != GetGeom() )
1236         addCmd->SetArg( 2, geom );
1237     }
1238   }
1239
1240   // sm = mesh.GetSubMesh(geom, name) --> sm = mesh.GetMesh().GetSubMesh(geom, name)
1241 //   for ( cmd = mySubmeshes.begin(); cmd != mySubmeshes.end(); ++cmd ) {
1242 //     Handle(_pyCommand) subCmd = *cmd;
1243 //     if ( subCmd->GetNbArgs() > 0 )
1244 //       AddMeshAccess( subCmd );
1245 //   }
1246   myAddHypCmds.clear();
1247   mySubmeshes.clear();
1248
1249   // flush hypotheses
1250   list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
1251   for ( ; hyp != myHypos.end(); ++hyp )
1252     (*hyp)->Flush();
1253 }
1254
1255 //================================================================================
1256 /*!
1257  * \brief MeshEditor convert its commands to ones of mesh
1258  */
1259 //================================================================================
1260
1261 _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd):
1262   _pyObject( theCreationCmd )
1263 {
1264   myMesh = theCreationCmd->GetObject();
1265   myCreationCmdStr = theCreationCmd->GetString();
1266   theCreationCmd->Clear();
1267 }
1268
1269 //================================================================================
1270 /*!
1271  * \brief convert its commands to ones of mesh
1272  */
1273 //================================================================================
1274
1275 void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
1276 {
1277   // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so
1278   // commands calling this methods are converted to calls of methods of Mesh
1279   static TStringSet sameMethods;
1280   if ( sameMethods.empty() ) {
1281     const char * names[] = {
1282       "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace",
1283       "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
1284       "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject",
1285       "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
1286       "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
1287       "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
1288       "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
1289       "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathX",
1290       "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
1291       "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
1292       "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements",
1293       "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
1294       "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
1295       "GetLastCreatedElems",
1296       "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
1297       "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh"
1298       ,"" }; // <- mark of the end
1299     sameMethods.Insert( names );
1300   }
1301
1302   // names of SMESH_MeshEditor methods which differ from methods of class Mesh
1303   // only by last two arguments
1304   static TStringSet diffLastTwoArgsMethods;
1305   if (diffLastTwoArgsMethods.empty() ) {
1306     const char * names[] = {
1307       "MirrorMakeGroups","MirrorObjectMakeGroups",
1308       "TranslateMakeGroups","TranslateObjectMakeGroups",
1309       "RotateMakeGroups","RotateObjectMakeGroups",
1310       ""};// <- mark of the end
1311     diffLastTwoArgsMethods.Insert( names );
1312   }
1313
1314   const TCollection_AsciiString & method = theCommand->GetMethod();
1315   bool isPyMeshMethod = sameMethods.Contains( method );
1316   if ( !isPyMeshMethod )
1317   {
1318     //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh
1319     //functions with the flag "theMakeGroups = True" like:
1320     //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
1321     int pos = method.Search("MakeGroups");
1322     if( pos != -1)
1323     {
1324       isPyMeshMethod = true;
1325
1326       // 1. Remove "MakeGroups" from the Command
1327       TCollection_AsciiString aMethod = theCommand->GetMethod();
1328       int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1;
1329       aMethod.Trunc(pos-1);
1330       theCommand->SetMethod(aMethod);
1331
1332       // 2. And add last "True" argument(s)
1333       while(nbArgsToAdd--)
1334         theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
1335     }
1336   }
1337
1338   // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
1339   if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
1340   {
1341     isPyMeshMethod=true;
1342     theCommand->SetMethod("ExtrusionAlongPathX");
1343   }
1344
1345   // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
1346   if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
1347   {
1348     isPyMeshMethod=true;
1349     theCommand->SetMethod("FindCoincidentNodesOnPart");
1350   }
1351   // DoubleNodeElemGroupNew() -> DoubleNodeElemGroup()
1352   // DoubleNodeGroupNew() -> DoubleNodeGroup()
1353   // DoubleNodeGroupsNew() -> DoubleNodeGroups()
1354   // DoubleNodeElemGroupsNew() -> DoubleNodeElemGroups()
1355   if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew"  ||
1356                             method == "DoubleNodeElemGroupsNew" ||
1357                             method == "DoubleNodeGroupNew"      ||
1358                             method == "DoubleNodeGroupsNew"))
1359   {
1360     isPyMeshMethod=true;
1361     theCommand->SetMethod( method.SubString( 1, method.Length()-3));
1362     theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
1363   }
1364   // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj)
1365   // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj)
1366   if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" ||
1367                             method == "ConvertFromQuadraticObject" ))
1368   {
1369     isPyMeshMethod=true;
1370     theCommand->SetMethod( method.SubString( 1, method.Length()-6));
1371     // prevent moving creation of the converted sub-mesh to the end of the script
1372     bool isFromQua = ( method.Value( 8 ) == 'F' );
1373     Handle(_pySubMesh) sm = theGen->FindSubMesh( theCommand->GetArg( isFromQua ? 1 : 2 ));
1374     if ( !sm.IsNull() )
1375       sm->Process( theCommand );
1376   }
1377   // FindAmongElementsByPoint(meshPart, x, y, z, elementType) ->
1378   // FindElementsByPoint(x, y, z, elementType, meshPart)
1379   if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" )
1380   {
1381     isPyMeshMethod=true;
1382     theCommand->SetMethod( "FindElementsByPoint" );
1383     // make the 1st arg be the last one
1384     _pyID partID = theCommand->GetArg( 1 );
1385     int nbArgs = theCommand->GetNbArgs();
1386     for ( int i = 2; i <= nbArgs; ++i )
1387       theCommand->SetArg( i-1, theCommand->GetArg( i ));
1388     theCommand->SetArg( nbArgs, partID );
1389   }
1390
1391   // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
1392   // so let _pyMesh care of it (TMP?)
1393   //     if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
1394   //       _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
1395   if ( isPyMeshMethod )
1396   {
1397     theCommand->SetObject( myMesh );
1398   }
1399   else
1400   {
1401     // editor creation command is needed only if any editor function is called
1402     theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
1403     if ( !myCreationCmdStr.IsEmpty() ) {
1404       GetCreationCmd()->GetString() = myCreationCmdStr;
1405       myCreationCmdStr.Clear();
1406     }
1407   }
1408 }
1409
1410 //================================================================================
1411 /*!
1412  * \brief _pyHypothesis constructor
1413   * \param theCreationCmd -
1414  */
1415 //================================================================================
1416
1417 _pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd):
1418   _pyObject( theCreationCmd )
1419 {
1420   myIsAlgo = myIsWrapped = /*myIsConverted = myIsLocal = myDim = */false;
1421 }
1422
1423 //================================================================================
1424 /*!
1425  * \brief Creates algorithm or hypothesis
1426   * \param theCreationCmd - The engine command creating a hypothesis
1427   * \retval Handle(_pyHypothesis) - Result _pyHypothesis
1428  */
1429 //================================================================================
1430
1431 Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& theCreationCmd)
1432 {
1433   // theCreationCmd: CreateHypothesis( "theHypType", "theLibName" )
1434   ASSERT (( theCreationCmd->GetMethod() == "CreateHypothesis"));
1435
1436   Handle(_pyHypothesis) hyp, algo;
1437
1438   // "theHypType"
1439   const TCollection_AsciiString & hypTypeQuoted = theCreationCmd->GetArg( 1 );
1440   if ( hypTypeQuoted.IsEmpty() )
1441     return hyp;
1442   // theHypType
1443   TCollection_AsciiString  hypType =
1444     hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
1445
1446   algo = new _pyAlgorithm( theCreationCmd );
1447   hyp  = new _pyHypothesis( theCreationCmd );
1448
1449   // 1D Regular_1D ----------
1450   if ( hypType == "Regular_1D" ) {
1451     // set mesh's method creating algo,
1452     // i.e. convertion result will be "regular1d = Mesh.Segment()",
1453     // and set hypType by which algo creating a hypothesis is searched for
1454     algo->SetConvMethodAndType("Segment", hypType.ToCString());
1455   }
1456   else if ( hypType == "CompositeSegment_1D" ) {
1457     algo->SetConvMethodAndType("Segment", "Regular_1D");
1458     algo->myArgs.Append( "algo=smesh.COMPOSITE");
1459   }
1460   else if ( hypType == "LocalLength" ) {
1461     // set algo's method creating hyp, and algo type
1462     hyp->SetConvMethodAndType( "LocalLength", "Regular_1D");
1463     // set method whose 1 arg will become the 1-st arg of hyp creation command
1464     // i.e. convertion result will be "locallength = regular1d.LocalLength(<arg of SetLength()>)"
1465     hyp->AddArgMethod( "SetLength" );
1466   }
1467   else if ( hypType == "MaxLength" ) {
1468     // set algo's method creating hyp, and algo type
1469     hyp->SetConvMethodAndType( "MaxSize", "Regular_1D");
1470     // set method whose 1 arg will become the 1-st arg of hyp creation command
1471     // i.e. convertion result will be "maxsize = regular1d.MaxSize(<arg of SetLength()>)"
1472     hyp->AddArgMethod( "SetLength" );
1473   }
1474   else if ( hypType == "NumberOfSegments" ) {
1475     hyp = new _pyNumberOfSegmentsHyp( theCreationCmd );
1476     hyp->SetConvMethodAndType( "NumberOfSegments", "Regular_1D");
1477     // arg of SetNumberOfSegments() will become the 1-st arg of hyp creation command
1478     hyp->AddArgMethod( "SetNumberOfSegments" );
1479     // arg of SetScaleFactor() will become the 2-nd arg of hyp creation command
1480     hyp->AddArgMethod( "SetScaleFactor" );
1481     hyp->AddArgMethod( "SetReversedEdges" );
1482   }
1483   else if ( hypType == "Arithmetic1D" ) {
1484     hyp = new _pyComplexParamHypo( theCreationCmd );
1485     hyp->SetConvMethodAndType( "Arithmetic1D", "Regular_1D");
1486     hyp->AddArgMethod( "SetStartLength" );
1487     hyp->AddArgMethod( "SetEndLength" );
1488     hyp->AddArgMethod( "SetReversedEdges" );
1489   }
1490   else if ( hypType == "StartEndLength" ) {
1491     hyp = new _pyComplexParamHypo( theCreationCmd );
1492     hyp->SetConvMethodAndType( "StartEndLength", "Regular_1D");
1493     hyp->AddArgMethod( "SetStartLength" );
1494     hyp->AddArgMethod( "SetEndLength" );
1495     hyp->AddArgMethod( "SetReversedEdges" );
1496   }
1497   else if ( hypType == "Deflection1D" ) {
1498     hyp->SetConvMethodAndType( "Deflection1D", "Regular_1D");
1499     hyp->AddArgMethod( "SetDeflection" );
1500   }
1501   else if ( hypType == "Propagation" ) {
1502     hyp->SetConvMethodAndType( "Propagation", "Regular_1D");
1503   }
1504   else if ( hypType == "QuadraticMesh" ) {
1505     hyp->SetConvMethodAndType( "QuadraticMesh", "Regular_1D");
1506   }
1507   else if ( hypType == "AutomaticLength" ) {
1508     hyp->SetConvMethodAndType( "AutomaticLength", "Regular_1D");
1509     hyp->AddArgMethod( "SetFineness");
1510   }
1511   else if ( hypType == "SegmentLengthAroundVertex" ) {
1512     hyp = new _pySegmentLengthAroundVertexHyp( theCreationCmd );
1513     hyp->SetConvMethodAndType( "LengthNearVertex", "Regular_1D" );
1514     hyp->AddArgMethod( "SetLength" );
1515   }
1516   // 1D Python_1D ----------
1517   else if ( hypType == "Python_1D" ) {
1518     algo->SetConvMethodAndType( "Segment", hypType.ToCString());
1519     algo->myArgs.Append( "algo=smesh.PYTHON");
1520   }
1521   else if ( hypType == "PythonSplit1D" ) {
1522     hyp->SetConvMethodAndType( "PythonSplit1D", "Python_1D");
1523     hyp->AddArgMethod( "SetNumberOfSegments");
1524     hyp->AddArgMethod( "SetPythonLog10RatioFunction");
1525   }
1526   // MEFISTO_2D ----------
1527   else if ( hypType == "MEFISTO_2D" ) { // MEFISTO_2D
1528     algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
1529   }
1530   else if ( hypType == "MaxElementArea" ) {
1531     hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D");
1532     hyp->SetConvMethodAndType( "MaxElementArea", "NETGEN_2D_ONLY");
1533     hyp->AddArgMethod( "SetMaxElementArea");
1534   }
1535   else if ( hypType == "LengthFromEdges" ) {
1536     hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D");
1537     hyp->SetConvMethodAndType( "LengthFromEdges", "NETGEN_2D_ONLY");
1538   }
1539   // Quadrangle_2D ----------
1540   else if ( hypType == "Quadrangle_2D" ) {
1541     algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
1542   }
1543   else if ( hypType == "QuadranglePreference" ) {
1544     hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D");
1545     hyp->SetConvMethodAndType( "SetQuadAllowed", "NETGEN_2D_ONLY");
1546   }
1547   else if ( hypType == "TrianglePreference" ) {
1548     hyp->SetConvMethodAndType( "TrianglePreference", "Quadrangle_2D");
1549   }
1550   // RadialQuadrangle_1D2D ----------
1551   else if ( hypType == "RadialQuadrangle_1D2D" ) {
1552     algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
1553     algo->myArgs.Append( "algo=smesh.RADIAL_QUAD" );
1554   }
1555   else if ( hypType == "NumberOfLayers2D" ) {
1556     hyp->SetConvMethodAndType( "NumberOfLayers", "RadialQuadrangle_1D2D");
1557     hyp->AddArgMethod( "SetNumberOfLayers" );
1558   }
1559   else if ( hypType == "LayerDistribution2D" ) {
1560     hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get2DHypothesis" );
1561     hyp->SetConvMethodAndType( "LayerDistribution", "RadialQuadrangle_1D2D");
1562   }
1563   // BLSURF ----------
1564   else if ( hypType == "BLSURF" ) {
1565     algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
1566     algo->myArgs.Append( "algo=smesh.BLSURF" );
1567   }
1568   else if ( hypType == "BLSURF_Parameters") {
1569     hyp->SetConvMethodAndType( "Parameters", "BLSURF");
1570   }
1571   // NETGEN ----------
1572   else if ( hypType == "NETGEN_2D") { // 1D-2D
1573     algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
1574     algo->myArgs.Append( "algo=smesh.NETGEN" );
1575   }
1576   else if ( hypType == "NETGEN_Parameters_2D") {
1577     hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D");
1578   }
1579   else if ( hypType == "NETGEN_SimpleParameters_2D") {
1580     hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D");
1581     hyp->myArgs.Append( "which=smesh.SIMPLE" );
1582   }
1583   else if ( hypType == "NETGEN_2D3D") { // 1D-2D-3D
1584     algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
1585     algo->myArgs.Append( "algo=smesh.FULL_NETGEN" );
1586   }
1587   else if ( hypType == "NETGEN_Parameters") {
1588     hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D3D");
1589   }
1590   else if ( hypType == "NETGEN_SimpleParameters_3D") {
1591     hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D3D");
1592     hyp->myArgs.Append( "which=smesh.SIMPLE" );
1593   }
1594   else if ( hypType == "NETGEN_2D_ONLY") { // 2D
1595     algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
1596     algo->myArgs.Append( "algo=smesh.NETGEN_2D" );
1597   }
1598   else if ( hypType == "NETGEN_3D") { // 3D
1599     algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
1600     algo->myArgs.Append( "algo=smesh.NETGEN" );
1601   }
1602   else if ( hypType == "MaxElementVolume") {
1603     hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D");
1604     hyp->AddArgMethod( "SetMaxElementVolume" );
1605   }
1606   // GHS3D_3D ----------
1607   else if ( hypType == "GHS3D_3D" ) {
1608     algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString());
1609     algo->myArgs.Append( "algo=smesh.GHS3D" );
1610   }
1611   else if ( hypType == "GHS3D_Parameters") {
1612     hyp->SetConvMethodAndType( "Parameters", "GHS3D_3D");
1613   }
1614   // Hexa_3D ---------
1615   else if ( hypType == "BLSURF" ) {
1616     algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString());
1617   }
1618   // Repetitive Projection_1D ---------
1619   else if ( hypType == "Projection_1D" ) {
1620     algo->SetConvMethodAndType( "Projection1D", hypType.ToCString());
1621   }
1622   else if ( hypType == "ProjectionSource1D" ) {
1623     hyp->SetConvMethodAndType( "SourceEdge", "Projection_1D");
1624     hyp->AddArgMethod( "SetSourceEdge");
1625     hyp->AddArgMethod( "SetSourceMesh");
1626     // 2 args of SetVertexAssociation() will become the 3-th and 4-th args of hyp creation command
1627     hyp->AddArgMethod( "SetVertexAssociation", 2 );
1628   }
1629   // Projection_2D ---------
1630   else if ( hypType == "Projection_2D" ) {
1631     algo->SetConvMethodAndType( "Projection2D", hypType.ToCString());
1632   }
1633   else if ( hypType == "Projection_1D2D" ) {
1634     algo->SetConvMethodAndType( "Projection1D2D", hypType.ToCString());
1635   }
1636   else if ( hypType == "ProjectionSource2D" ) {
1637     hyp->SetConvMethodAndType( "SourceFace", "Projection_2D");
1638     hyp->AddArgMethod( "SetSourceFace");
1639     hyp->AddArgMethod( "SetSourceMesh");
1640     hyp->AddArgMethod( "SetVertexAssociation", 4 );
1641   }
1642   // Projection_3D ---------
1643   else if ( hypType == "Projection_3D" ) {
1644     algo->SetConvMethodAndType( "Projection3D", hypType.ToCString());
1645   }
1646   else if ( hypType == "ProjectionSource3D" ) {
1647     hyp->SetConvMethodAndType( "SourceShape3D", "Projection_3D");
1648     hyp->AddArgMethod( "SetSource3DShape");
1649     hyp->AddArgMethod( "SetSourceMesh");
1650     hyp->AddArgMethod( "SetVertexAssociation", 4 );
1651   }
1652   // Prism_3D ---------
1653   else if ( hypType == "Prism_3D" ) {
1654     algo->SetConvMethodAndType( "Prism", hypType.ToCString());
1655   }
1656   // RadialPrism_3D ---------
1657   else if ( hypType == "RadialPrism_3D" ) {
1658     algo->SetConvMethodAndType( "Prism", hypType.ToCString());
1659   }
1660   else if ( hypType == "NumberOfLayers" ) {
1661     hyp->SetConvMethodAndType( "NumberOfLayers", "RadialPrism_3D");
1662     hyp->AddArgMethod( "SetNumberOfLayers" );
1663   }
1664   else if ( hypType == "LayerDistribution" ) {
1665     hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get3DHypothesis" );
1666     hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
1667   }
1668
1669   return algo->IsValid() ? algo : hyp;
1670 }
1671
1672 //================================================================================
1673 /*!
1674  * \brief Convert the command adding a hypothesis to mesh into a smesh command
1675   * \param theCmd - The command like mesh.AddHypothesis( geom, hypo )
1676   * \param theAlgo - The algo that can create this hypo
1677   * \retval bool - false if the command cant be converted
1678  */
1679 //================================================================================
1680
1681 bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
1682                                        const _pyID&              theMesh)
1683 {
1684   ASSERT(( theCmd->GetMethod() == "AddHypothesis" ));
1685
1686   if ( !IsWrappable( theMesh ))
1687     return false;
1688
1689   myGeom = theCmd->GetArg( 1 );
1690
1691   Handle(_pyHypothesis) algo;
1692   if ( !IsAlgo() ) {
1693     // find algo created on myGeom in theMesh
1694     algo = theGen->FindAlgo( myGeom, theMesh, this );
1695     if ( algo.IsNull() )
1696       return false;
1697     // attach hypothesis creation command to be after algo creation command
1698     // because it can be new created instance of algorithm
1699     algo->GetCreationCmd()->AddDependantCmd( theCmd );
1700   }
1701   myIsWrapped = true;
1702
1703   // mesh.AddHypothesis(geom,hyp) --> hyp = <theMesh or algo>.myCreationMethod(args)
1704   theCmd->SetResultValue( GetID() );
1705   theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID());
1706   theCmd->SetMethod( IsAlgo() ? GetAlgoCreationMethod() : GetCreationMethod( algo->GetAlgoType() ));
1707   // set args
1708   theCmd->RemoveArgs();
1709   for ( int i = 1; i <= myArgs.Length(); ++i ) {
1710     if ( !myArgs( i ).IsEmpty() )
1711       theCmd->SetArg( i, myArgs( i ));
1712     else
1713       theCmd->SetArg( i, "[]");
1714   }
1715   // set a new creation command
1716   GetCreationCmd()->Clear();
1717   // replace creation command by wrapped instance
1718   // please note, that hypothesis attaches to algo creation command (see upper)
1719   SetCreationCmd( theCmd );
1720
1721
1722   // clear commands setting arg values
1723   list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
1724   for ( ; argCmd != myArgCommands.end(); ++argCmd )
1725     (*argCmd)->Clear();
1726
1727   // set unknown arg commands after hypo creation
1728   Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd();
1729   list<Handle(_pyCommand)>::iterator cmd = myUnknownCommands.begin();
1730   for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
1731     afterCmd->AddDependantCmd( *cmd );
1732   }
1733
1734   return myIsWrapped;
1735 }
1736
1737 //================================================================================
1738 /*!
1739  * \brief Remember hypothesis parameter values
1740  * \param theCommand - The called hypothesis method
1741  */
1742 //================================================================================
1743
1744 void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
1745 {
1746   ASSERT( !myIsAlgo );
1747   // set args
1748   int nbArgs = 0;
1749   for ( int i = 1; i <= myArgMethods.Length(); ++i ) {
1750     if ( myArgMethods( i ) == theCommand->GetMethod() ) {
1751       while ( myArgs.Length() < nbArgs + myNbArgsByMethod( i ))
1752         myArgs.Append( "[]" );
1753       for ( int iArg = 1; iArg <= myNbArgsByMethod( i ); ++iArg )
1754         myArgs( nbArgs + iArg ) = theCommand->GetArg( iArg ); // arg value
1755       myArgCommands.push_back( theCommand );
1756       return;
1757     }
1758     nbArgs += myNbArgsByMethod( i );
1759   }
1760   myUnknownCommands.push_back( theCommand );
1761 }
1762
1763 //================================================================================
1764 /*!
1765  * \brief Finish conversion
1766  */
1767 //================================================================================
1768
1769 void _pyHypothesis::Flush()
1770 {
1771   if ( IsWrapped() ) {
1772   }
1773   else {
1774     list < Handle(_pyCommand) >::iterator cmd = myArgCommands.begin();
1775     for ( ; cmd != myArgCommands.end(); ++cmd ) {
1776       // Add access to a wrapped mesh
1777       theGen->AddMeshAccessorMethod( *cmd );
1778       // Add access to a wrapped algorithm
1779       theGen->AddAlgoAccessorMethod( *cmd );
1780     }
1781     cmd = myUnknownCommands.begin();
1782     for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
1783       // Add access to a wrapped mesh
1784       theGen->AddMeshAccessorMethod( *cmd );
1785       // Add access to a wrapped algorithm
1786       theGen->AddAlgoAccessorMethod( *cmd );
1787     }
1788   }
1789   // forget previous hypothesis modifications
1790   myArgCommands.clear();
1791   myUnknownCommands.clear();
1792 }
1793
1794 //================================================================================
1795 /*!
1796  * \brief clear creation, arg and unkown commands
1797  */
1798 //================================================================================
1799
1800 void _pyHypothesis::ClearAllCommands()
1801 {
1802   GetCreationCmd()->Clear();
1803   list<Handle(_pyCommand)>::iterator cmd = myArgCommands.begin();
1804   for ( ; cmd != myArgCommands.end(); ++cmd )
1805     ( *cmd )->Clear();
1806   cmd = myUnknownCommands.begin();
1807   for ( ; cmd != myUnknownCommands.end(); ++cmd )
1808     ( *cmd )->Clear();
1809 }
1810
1811
1812 //================================================================================
1813 /*!
1814  * \brief Assign fields of theOther to me except myIsWrapped
1815  */
1816 //================================================================================
1817
1818 void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
1819                             const _pyID&                 theMesh )
1820 {
1821   myIsWrapped = false;
1822   myMesh = theMesh;
1823
1824   // myCreationCmd = theOther->myCreationCmd;
1825   myIsAlgo = theOther->myIsAlgo;
1826   myGeom = theOther->myGeom;
1827   myType2CreationMethod = theOther->myType2CreationMethod;
1828   myArgs = theOther->myArgs;
1829   myArgMethods = theOther->myArgMethods;
1830   myNbArgsByMethod = theOther->myNbArgsByMethod;
1831   myArgCommands = theOther->myArgCommands;
1832   myUnknownCommands = theOther->myUnknownCommands;
1833 }
1834
1835 //================================================================================
1836 /*!
1837  * \brief Remember hypothesis parameter values
1838   * \param theCommand - The called hypothesis method
1839  */
1840 //================================================================================
1841
1842 void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand)
1843 {
1844   if( theCommand->GetMethod() == "SetLength" )
1845   {
1846     // NOW it becomes OBSOLETE
1847     // ex: hyp.SetLength(start, 1)
1848     //     hyp.SetLength(end,   0)
1849     ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() ));
1850     int i = 2 - theCommand->GetArg( 2 ).IntegerValue();
1851     while ( myArgs.Length() < i )
1852       myArgs.Append( "[]" );
1853     myArgs( i ) = theCommand->GetArg( 1 ); // arg value
1854     myArgCommands.push_back( theCommand );
1855   }
1856   else
1857   {
1858     _pyHypothesis::Process( theCommand );
1859   }
1860 }
1861 //================================================================================
1862 /*!
1863  * \brief Clear SetObjectEntry() as it is called by methods of Mesh_Segment
1864  */
1865 //================================================================================
1866
1867 void _pyComplexParamHypo::Flush()
1868 {
1869   if ( IsWrapped() )
1870   {
1871     list < Handle(_pyCommand) >::iterator cmd = myUnknownCommands.begin();
1872     for ( ; cmd != myUnknownCommands.end(); ++cmd )
1873       if ((*cmd)->GetMethod() == "SetObjectEntry" )
1874         (*cmd)->Clear();
1875   }
1876 }
1877
1878 //================================================================================
1879 /*!
1880  * \brief Convert methods of 1D hypotheses to my own methods
1881   * \param theCommand - The called hypothesis method
1882  */
1883 //================================================================================
1884
1885 void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
1886 {
1887   if ( theCommand->GetMethod() != "SetLayerDistribution" )
1888     return;
1889
1890   _pyID newName; // name for 1D hyp = "HypType" + "_Distribution"
1891
1892   const _pyID& hyp1dID = theCommand->GetArg( 1 );
1893   Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID );
1894   if ( hyp1d.IsNull() ) // apparently hypId changed at study restoration
1895     hyp1d = my1dHyp;
1896   else if ( !my1dHyp.IsNull() && hyp1dID != my1dHyp->GetID() ) {
1897     // 1D hypo is already set, so distribution changes and the old
1898     // 1D hypo is thrown away
1899     my1dHyp->ClearAllCommands();
1900   }
1901   my1dHyp = hyp1d;
1902
1903   if ( !myArgCommands.empty() )
1904     myArgCommands.front()->Clear();
1905   myArgCommands.push_back( theCommand );
1906 }
1907
1908 //================================================================================
1909 /*!
1910  * \brief
1911   * \param theAdditionCmd - command to be converted
1912   * \param theMesh - mesh instance
1913   * \retval bool - status
1914  */
1915 //================================================================================
1916
1917 bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
1918                                                   const _pyID&              theMesh)
1919 {
1920   myIsWrapped = false;
1921
1922   if ( my1dHyp.IsNull() )
1923     return false;
1924
1925   // set "SetLayerDistribution()" after addition cmd
1926   theAdditionCmd->AddDependantCmd( myArgCommands.front() );
1927
1928   _pyID geom = theAdditionCmd->GetArg( 1 );
1929
1930   Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this );
1931   if ( !algo.IsNull() )
1932   {
1933     my1dHyp->SetMesh( theMesh );
1934     my1dHyp->SetConvMethodAndType(my1dHyp->GetAlgoCreationMethod().ToCString(),
1935                                   algo->GetAlgoType().ToCString());
1936     if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh ))
1937       return false;
1938
1939     // clear "SetLayerDistribution()" cmd
1940     myArgCommands.back()->Clear();
1941
1942     // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis()
1943
1944     // find RadialPrism algo created on <geom> for theMesh
1945     GetCreationCmd()->SetObject( algo->GetID() );
1946     GetCreationCmd()->SetMethod( myAlgoMethod );
1947     GetCreationCmd()->RemoveArgs();
1948     theAdditionCmd->AddDependantCmd( GetCreationCmd() );
1949     myIsWrapped = true;
1950   }
1951   return myIsWrapped;
1952 }
1953
1954 //================================================================================
1955 /*!
1956  * \brief
1957  */
1958 //================================================================================
1959
1960 void _pyLayerDistributionHypo::Flush()
1961 {
1962   // as creation of 1D hyp was written later then it's edition,
1963   // we need to find all it's edition calls and process them
1964   if ( !my1dHyp.IsNull() )
1965   {
1966     _pyID hyp1dID = my1dHyp->GetCreationCmd()->GetResultValue();
1967
1968     // make a new name for 1D hyp = "HypType" + "_Distribution"
1969     _pyID newName;
1970     if ( my1dHyp->IsWrapped() ) {
1971       newName = my1dHyp->GetCreationCmd()->GetMethod();
1972     }
1973     else {
1974       TCollection_AsciiString hypTypeQuoted = my1dHyp->GetCreationCmd()->GetArg(1);
1975       newName = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
1976     }
1977     newName += "_Distribution";
1978     my1dHyp->GetCreationCmd()->SetResultValue( newName );
1979
1980     list< Handle(_pyCommand) >& cmds = theGen->GetCommands();
1981     list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin();
1982     for ( ; cmdIt != cmds.end(); ++cmdIt ) {
1983       const _pyID& objID = (*cmdIt)->GetObject();
1984       if ( objID == hyp1dID ) {
1985         my1dHyp->Process( *cmdIt );
1986         my1dHyp->GetCreationCmd()->AddDependantCmd( *cmdIt );
1987         ( *cmdIt )->SetObject( newName );
1988       }
1989     }
1990     // Set new hyp name to SetLayerDistribution() cmd
1991     if ( !myArgCommands.empty() && !myArgCommands.back()->IsEmpty() )
1992       myArgCommands.back()->SetArg( 1, newName );
1993   }
1994 }
1995
1996 //================================================================================
1997 /*!
1998  * \brief additionally to Addition2Creation, clears SetDistrType() command
1999   * \param theCmd - AddHypothesis() command
2000   * \param theMesh - mesh to which a hypothesis is added
2001   * \retval bool - convertion result
2002  */
2003 //================================================================================
2004
2005 bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
2006                                                 const _pyID&              theMesh)
2007 {
2008   if ( IsWrappable( theMesh ) && myArgs.Length() > 1 ) {
2009     // scale factor (2-nd arg) is provided: clear SetDistrType(1) command
2010     bool scaleDistrType = false;
2011     list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
2012     for ( ; cmd != myUnknownCommands.rend(); ++cmd ) {
2013       if ( (*cmd)->GetMethod() == "SetDistrType" ) {
2014         if ( (*cmd)->GetArg( 1 ) == "1" ) {
2015           scaleDistrType = true;
2016           (*cmd)->Clear();
2017         }
2018         else if ( !scaleDistrType ) {
2019           // distribution type changed: remove scale factor from args
2020           myArgs.Remove( 2, myArgs.Length() );
2021           break;
2022         }
2023       }
2024     }
2025   }
2026   return _pyHypothesis::Addition2Creation( theCmd, theMesh );
2027 }
2028
2029 //================================================================================
2030 /*!
2031  * \brief remove repeated commands defining distribution
2032  */
2033 //================================================================================
2034
2035 void _pyNumberOfSegmentsHyp::Flush()
2036 {
2037   // find number of the last SetDistrType() command
2038   list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
2039   int distrTypeNb = 0;
2040   for ( ; !distrTypeNb && cmd != myUnknownCommands.rend(); ++cmd )
2041     if ( (*cmd)->GetMethod() == "SetDistrType" )
2042       distrTypeNb = (*cmd)->GetOrderNb();
2043     else if (IsWrapped() && (*cmd)->GetMethod() == "SetObjectEntry" )
2044       (*cmd)->Clear();
2045
2046   // clear commands before the last SetDistrType()
2047   list<Handle(_pyCommand)> * cmds[2] = { &myArgCommands, &myUnknownCommands };
2048   for ( int i = 0; i < 2; ++i ) {
2049     set<TCollection_AsciiString> uniqueMethods;
2050     list<Handle(_pyCommand)> & cmdList = *cmds[i];
2051     for ( cmd = cmdList.rbegin(); cmd != cmdList.rend(); ++cmd )
2052     {
2053       bool clear = ( (*cmd)->GetOrderNb() < distrTypeNb );
2054       const TCollection_AsciiString& method = (*cmd)->GetMethod();
2055       if ( !clear || method == "SetNumberOfSegments" ) {
2056         bool isNewInSet = uniqueMethods.insert( method ).second;
2057         clear = !isNewInSet;
2058       }
2059       if ( clear )
2060         (*cmd)->Clear();
2061     }
2062     cmdList.clear();
2063   }
2064 }
2065
2066 //================================================================================
2067 /*!
2068  * \brief Convert the command adding "SegmentLengthAroundVertex" to mesh
2069  * into regular1D.LengthNearVertex( length, vertex )
2070   * \param theCmd - The command like mesh.AddHypothesis( vertex, SegmentLengthAroundVertex )
2071   * \param theMesh - The mesh needing this hypo
2072   * \retval bool - false if the command cant be converted
2073  */
2074 //================================================================================
2075
2076 bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
2077                                                          const _pyID&              theMeshID)
2078 {
2079   if ( IsWrappable( theMeshID )) {
2080
2081     _pyID vertex = theCmd->GetArg( 1 );
2082
2083     // the problem here is that segment algo will not be found
2084     // by pyHypothesis::Addition2Creation() for <vertex>, so we try to find
2085     // geometry where segment algorithm is assigned
2086     Handle(_pyHypothesis) algo;
2087     _pyID geom = vertex;
2088     while ( algo.IsNull() && !geom.IsEmpty()) {
2089       // try to find geom as a father of <vertex>
2090       geom = FatherID( geom );
2091       algo = theGen->FindAlgo( geom, theMeshID, this );
2092     }
2093     if ( algo.IsNull() )
2094       return false; // also possible to find geom as brother of veretex...
2095     // set geom instead of vertex
2096     theCmd->SetArg( 1, geom );
2097
2098     // set vertex as a second arg
2099     if ( myArgs.Length() < 1) myArgs.Append( "1" ); // :(
2100     myArgs.Append( vertex );
2101
2102     // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) -->
2103     // theMeshID.LengthNearVertex( length, vertex )
2104     return _pyHypothesis::Addition2Creation( theCmd, theMeshID );
2105   }
2106   return false;
2107 }
2108
2109 //================================================================================
2110 /*!
2111  * \brief _pyAlgorithm constructor
2112  * \param theCreationCmd - The command like "algo = smeshgen.CreateHypothesis(type,lib)"
2113  */
2114 //================================================================================
2115
2116 _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd)
2117   : _pyHypothesis( theCreationCmd )
2118 {
2119   myIsAlgo = true;
2120 }
2121
2122 //================================================================================
2123 /*!
2124  * \brief Convert the command adding an algorithm to mesh
2125   * \param theCmd - The command like mesh.AddHypothesis( geom, algo )
2126   * \param theMesh - The mesh needing this algo
2127   * \retval bool - false if the command cant be converted
2128  */
2129 //================================================================================
2130
2131 bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd,
2132                                       const _pyID&              theMeshID)
2133 {
2134   // mesh.AddHypothesis(geom,algo) --> theMeshID.myCreationMethod()
2135   if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) {
2136     theGen->SetAccessorMethod( GetID(), "GetAlgorithm()" );
2137     return true;
2138   }
2139   return false;
2140 }
2141
2142 //================================================================================
2143 /*!
2144  * \brief Return starting position of a part of python command
2145   * \param thePartIndex - The index of command part
2146   * \retval int - Part position
2147  */
2148 //================================================================================
2149
2150 int _pyCommand::GetBegPos( int thePartIndex )
2151 {
2152   if ( IsEmpty() )
2153     return EMPTY;
2154   if ( myBegPos.Length() < thePartIndex )
2155     return UNKNOWN;
2156   return myBegPos( thePartIndex );
2157 }
2158
2159 //================================================================================
2160 /*!
2161  * \brief Store starting position of a part of python command
2162   * \param thePartIndex - The index of command part
2163   * \param thePosition - Part position
2164  */
2165 //================================================================================
2166
2167 void _pyCommand::SetBegPos( int thePartIndex, int thePosition )
2168 {
2169   while ( myBegPos.Length() < thePartIndex )
2170     myBegPos.Append( UNKNOWN );
2171   myBegPos( thePartIndex ) = thePosition;
2172 }
2173
2174 //================================================================================
2175 /*!
2176  * \brief Returns whitespace symbols at the line beginning
2177   * \retval TCollection_AsciiString - result
2178  */
2179 //================================================================================
2180
2181 TCollection_AsciiString _pyCommand::GetIndentation()
2182 {
2183   int end = 1;
2184   if ( GetBegPos( RESULT_IND ) == UNKNOWN )
2185     GetWord( myString, end, true );
2186   else
2187     end = GetBegPos( RESULT_IND );
2188   return myString.SubString( 1, end - 1 );
2189 }
2190
2191 //================================================================================
2192 /*!
2193  * \brief Return substring of python command looking like ResultValue = Obj.Meth()
2194   * \retval const TCollection_AsciiString & - ResultValue substring
2195  */
2196 //================================================================================
2197
2198 const TCollection_AsciiString & _pyCommand::GetResultValue()
2199 {
2200   if ( GetBegPos( RESULT_IND ) == UNKNOWN )
2201   {
2202     int begPos = myString.Location( "=", 1, Length() );
2203     if ( begPos )
2204       myRes = GetWord( myString, begPos, false );
2205     else
2206       begPos = EMPTY;
2207     SetBegPos( RESULT_IND, begPos );
2208   }
2209   return myRes;
2210 }
2211
2212 //================================================================================
2213 /*!
2214  * \brief Return number of python command result value ResultValue = Obj.Meth()
2215   * \retval const int
2216  */
2217 //================================================================================
2218
2219 const int _pyCommand::GetNbResultValues()
2220 {
2221   int begPos = 1;
2222   int Nb=0;
2223   int endPos = myString.Location( "=", 1, Length() );
2224   TCollection_AsciiString str = "";
2225   while ( begPos < endPos) {
2226     str = GetWord( myString, begPos, true );
2227     begPos = begPos+ str.Length();
2228     Nb++;
2229   }
2230   return (Nb-1);
2231 }
2232
2233
2234 //================================================================================
2235 /*!
2236  * \brief Return substring of python command looking like
2237  *  ResultValue1 , ResultValue1,... = Obj.Meth() with res index
2238  * \retval const TCollection_AsciiString & - ResultValue with res index substring
2239  */
2240 //================================================================================
2241 const TCollection_AsciiString & _pyCommand::GetResultValue(int res)
2242 {
2243   int begPos = 1;
2244   int Nb=0;
2245   int endPos = myString.Location( "=", 1, Length() );
2246   while ( begPos < endPos) {
2247     myRes = GetWord( myString, begPos, true );
2248     begPos = begPos + myRes.Length();
2249     Nb++;
2250     if(res == Nb){
2251       myRes.RemoveAll('[');myRes.RemoveAll(']');
2252       return myRes;
2253     }
2254     if(Nb>res)
2255       break;
2256   }
2257   return theEmptyString;
2258 }
2259
2260 //================================================================================
2261 /*!
2262  * \brief Return substring of python command looking like ResVal = Object.Meth()
2263   * \retval const TCollection_AsciiString & - Object substring
2264  */
2265 //================================================================================
2266
2267 const TCollection_AsciiString & _pyCommand::GetObject()
2268 {
2269   if ( GetBegPos( OBJECT_IND ) == UNKNOWN )
2270   {
2271     // beginning
2272     int begPos = GetBegPos( RESULT_IND ) + myRes.Length();
2273     if ( begPos < 1 ) {
2274       begPos = myString.Location( "=", 1, Length() ) + 1;
2275       // is '=' in the string argument (for example, name) or not
2276       int nb1 = 0; // number of ' character at the left of =
2277       int nb2 = 0; // number of " character at the left of =
2278       for ( int i = 1; i < begPos-1; i++ ) {
2279         if ( myString.Value( i )=='\'' )
2280           nb1 += 1;
2281         else if ( myString.Value( i )=='"' )
2282           nb2 += 1;
2283       }
2284       // if number of ' or " is not divisible by 2,
2285       // then get an object at the start of the command
2286       if ( nb1 % 2 != 0 || nb2 % 2 != 0 )
2287         begPos = 1;
2288     }
2289     myObj = GetWord( myString, begPos, true );
2290     // check if object is complex,
2291     // so far consider case like "smesh.smesh.Method()"
2292     if ( int bracketPos = myString.Location( "(", begPos, Length() )) {
2293       //if ( bracketPos==0 ) bracketPos = Length();
2294       int dotPos = begPos+myObj.Length();
2295       while ( dotPos+1 < bracketPos ) {
2296         if ( int pos = myString.Location( ".", dotPos+1, bracketPos ))
2297           dotPos = pos;
2298         else
2299           break;
2300       }
2301       if ( dotPos > begPos+myObj.Length() )
2302         myObj = myString.SubString( begPos, dotPos-1 );
2303     }
2304     // store
2305     SetBegPos( OBJECT_IND, begPos );
2306   }
2307   //SCRUTE(myObj);
2308   return myObj;
2309 }
2310
2311 //================================================================================
2312 /*!
2313  * \brief Return substring of python command looking like ResVal = Obj.Method()
2314   * \retval const TCollection_AsciiString & - Method substring
2315  */
2316 //================================================================================
2317
2318 const TCollection_AsciiString & _pyCommand::GetMethod()
2319 {
2320   if ( GetBegPos( METHOD_IND ) == UNKNOWN )
2321   {
2322     // beginning
2323     int begPos = GetBegPos( OBJECT_IND ) + myObj.Length();
2324     bool forward = true;
2325     if ( begPos < 1 ) {
2326       begPos = myString.Location( "(", 1, Length() ) - 1;
2327       forward = false;
2328     }
2329     // store
2330     myMeth = GetWord( myString, begPos, forward );
2331     SetBegPos( METHOD_IND, begPos );
2332   }
2333   //SCRUTE(myMeth);
2334   return myMeth;
2335 }
2336
2337 //================================================================================
2338 /*!
2339  * \brief Return substring of python command looking like ResVal = Obj.Meth(Arg1,...)
2340   * \retval const TCollection_AsciiString & - Arg<index> substring
2341  */
2342 //================================================================================
2343
2344 const TCollection_AsciiString & _pyCommand::GetArg( int index )
2345 {
2346   if ( GetBegPos( ARG1_IND ) == UNKNOWN )
2347   {
2348     // Find all args
2349
2350     int pos = GetBegPos( METHOD_IND ) + myMeth.Length();
2351     if ( pos < 1 )
2352       pos = myString.Location( "(", 1, Length() );
2353     else
2354       --pos;
2355
2356     // we are at or before '(', skip it if present
2357     if ( pos > 0 ) {
2358       while ( pos <= Length() && myString.Value( pos ) != '(' ) ++pos;
2359       if ( myString.Value( pos ) != '(' )
2360         pos = 0;
2361     }
2362     if ( pos < 1 ) {
2363       SetBegPos( ARG1_IND, 0 ); // even no '('
2364       return theEmptyString;
2365     }
2366     ++pos;
2367
2368     list< TCollection_AsciiString > separatorStack( 1, ",)");
2369     bool ignoreNesting = false;
2370     int prevPos = pos;
2371     while ( pos <= Length() )
2372     {
2373       const char chr = myString.Value( pos );
2374
2375       if ( separatorStack.back().Location( chr, 1, separatorStack.back().Length()))
2376       {
2377         if ( separatorStack.size() == 1 ) // ',' dividing args or a terminal ')' found
2378         {
2379           while ( pos-1 >= prevPos && isspace( myString.Value( prevPos )))
2380             ++prevPos;
2381           if ( pos-1 >= prevPos ) {
2382             TCollection_AsciiString arg = myString.SubString( prevPos, pos-1 );
2383             arg.RightAdjust(); // remove spaces
2384             arg.LeftAdjust();
2385             SetBegPos( ARG1_IND + myArgs.Length(), prevPos );
2386             myArgs.Append( arg );
2387           }
2388           if ( chr == ')' )
2389             break;
2390           prevPos = pos+1;
2391         }
2392         else // end of nesting args found
2393         {
2394           separatorStack.pop_back();
2395           ignoreNesting = false;
2396         }
2397       }
2398       else if ( !ignoreNesting )
2399       {
2400         switch ( chr ) {
2401         case '(' : separatorStack.push_back(")"); break;
2402         case '[' : separatorStack.push_back("]"); break;
2403         case '\'': separatorStack.push_back("'");  ignoreNesting=true; break;
2404         case '"' : separatorStack.push_back("\""); ignoreNesting=true; break;
2405         default:;
2406         }
2407       }
2408       ++pos;
2409     }
2410   }
2411   if ( myArgs.Length() < index )
2412     return theEmptyString;
2413   return myArgs( index );
2414 }
2415
2416 //================================================================================
2417 /*!
2418  * \brief Check if char is a word part
2419   * \param c - The character to check
2420   * \retval bool - The check result
2421  */
2422 //================================================================================
2423
2424 static inline bool isWord(const char c, const bool dotIsWord)
2425 {
2426   return
2427     !isspace(c) && c != ',' && c != '=' && c != ')' && c != '(' && ( dotIsWord || c != '.');
2428 }
2429
2430 //================================================================================
2431 /*!
2432  * \brief Looks for a word in the string and returns word's beginning
2433   * \param theString - The input string
2434   * \param theStartPos - The position to start the search, returning word's beginning
2435   * \param theForward - The search direction
2436   * \retval TCollection_AsciiString - The found word
2437  */
2438 //================================================================================
2439
2440 TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & theString,
2441                                             int &      theStartPos,
2442                                             const bool theForward,
2443                                             const bool dotIsWord )
2444 {
2445   int beg = theStartPos, end = theStartPos;
2446   theStartPos = EMPTY;
2447   if ( beg < 1 || beg > theString.Length() )
2448     return theEmptyString;
2449
2450   if ( theForward ) { // search forward
2451     // beg
2452     while ( beg <= theString.Length() && !isWord( theString.Value( beg ), dotIsWord))
2453       ++beg;
2454     if ( beg > theString.Length() )
2455       return theEmptyString; // no word found
2456     // end
2457     end = beg + 1;
2458     char begChar = theString.Value( beg );
2459     if ( begChar == '"' || begChar == '\'' || begChar == '[') {
2460       char endChar = ( begChar == '[' ) ? ']' : begChar;
2461       // end is at the corresponding quoting mark or bracket
2462       while ( end < theString.Length() &&
2463               ( theString.Value( end ) != endChar || theString.Value( end-1 ) == '\\'))
2464         ++end;
2465     }
2466     else {
2467       while ( end <= theString.Length() && isWord( theString.Value( end ), dotIsWord))
2468         ++end;
2469       --end;
2470     }
2471   }
2472   else {  // search backward
2473     // end
2474     while ( end > 0 && !isWord( theString.Value( end ), dotIsWord))
2475       --end;
2476     if ( end == 0 )
2477       return theEmptyString; // no word found
2478     beg = end - 1;
2479     char endChar = theString.Value( end );
2480     if ( endChar == '"' || endChar == '\'' ) {
2481       // beg is at the corresponding quoting mark
2482       while ( beg > 1 &&
2483               ( theString.Value( beg ) != endChar || theString.Value( beg-1 ) == '\\'))
2484         --beg;
2485     }
2486     else {
2487       while ( beg > 0 && isWord( theString.Value( beg ), dotIsWord))
2488         --beg;
2489       ++beg;
2490     }
2491   }
2492   theStartPos = beg;
2493   //cout << theString << " ---- " << beg << " - " << end << endl;
2494   return theString.SubString( beg, end );
2495 }
2496
2497 //================================================================================
2498 /*!
2499  * \brief Look for position where not space char is
2500   * \param theString - The string
2501   * \param thePos - The position to search from and which returns result
2502   * \retval bool - false if there are only space after thePos in theString
2503  *
2504  *
2505  */
2506 //================================================================================
2507
2508 bool _pyCommand::SkipSpaces( const TCollection_AsciiString & theString, int & thePos )
2509 {
2510   if ( thePos < 1 || thePos > theString.Length() )
2511     return false;
2512
2513   while ( thePos <= theString.Length() && isspace( theString.Value( thePos )))
2514     ++thePos;
2515
2516   return thePos <= theString.Length();
2517 }
2518
2519 //================================================================================
2520 /*!
2521  * \brief Modify a part of the command
2522   * \param thePartIndex - The index of the part
2523   * \param thePart - The new part string
2524   * \param theOldPart - The old part
2525  */
2526 //================================================================================
2527
2528 void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePart,
2529                         TCollection_AsciiString& theOldPart)
2530 {
2531   int pos = GetBegPos( thePartIndex );
2532   if ( pos <= Length() && theOldPart != thePart)
2533   {
2534     TCollection_AsciiString seperator;
2535     if ( pos < 1 ) {
2536       pos = GetBegPos( thePartIndex + 1 );
2537       if ( pos < 1 ) return;
2538       switch ( thePartIndex ) {
2539       case RESULT_IND: seperator = " = "; break;
2540       case OBJECT_IND: seperator = "."; break;
2541       case METHOD_IND: seperator = "()"; break;
2542       default:;
2543       }
2544     }
2545     myString.Remove( pos, theOldPart.Length() );
2546     if ( !seperator.IsEmpty() )
2547       myString.Insert( pos , seperator );
2548     myString.Insert( pos, thePart );
2549     // update starting positions of the following parts
2550     int posDelta = thePart.Length() + seperator.Length() - theOldPart.Length();
2551     for ( int i = thePartIndex + 1; i <= myBegPos.Length(); ++i ) {
2552       if ( myBegPos( i ) > 0 )
2553         myBegPos( i ) += posDelta;
2554     }
2555     theOldPart = thePart;
2556   }
2557 }
2558
2559 //================================================================================
2560 /*!
2561  * \brief Set agrument
2562   * \param index - The argument index, it counts from 1
2563   * \param theArg - The argument string
2564  */
2565 //================================================================================
2566
2567 void _pyCommand::SetArg( int index, const TCollection_AsciiString& theArg)
2568 {
2569   FindAllArgs();
2570   int argInd = ARG1_IND + index - 1;
2571   int pos = GetBegPos( argInd );
2572   if ( pos < 1 ) // no index-th arg exist, append inexistent args
2573   {
2574     // find a closing parenthesis
2575     if ( GetNbArgs() != 0 && index <= GetNbArgs() ) {
2576       int lastArgInd = GetNbArgs();
2577       pos = GetBegPos( ARG1_IND + lastArgInd  - 1 ) + GetArg( lastArgInd ).Length();
2578       while ( pos > 0 && pos <= Length() && myString.Value( pos ) != ')' )
2579         ++pos;
2580     }
2581     else {
2582       pos = Length();
2583       while ( pos > 0 && myString.Value( pos ) != ')' )
2584         --pos;
2585     }
2586     if ( pos < 1 || myString.Value( pos ) != ')' ) { // no parentheses at all
2587       myString += "()";
2588       pos = Length();
2589     }
2590     while ( myArgs.Length() < index ) {
2591       if ( myArgs.Length() )
2592         myString.Insert( pos++, "," );
2593       myArgs.Append("None");
2594       myString.Insert( pos, myArgs.Last() );
2595       SetBegPos( ARG1_IND + myArgs.Length() - 1, pos );
2596       pos += myArgs.Last().Length();
2597     }
2598   }
2599   SetPart( argInd, theArg, myArgs( index ));
2600 }
2601
2602 //================================================================================
2603 /*!
2604  * \brief Empty arg list
2605  */
2606 //================================================================================
2607
2608 void _pyCommand::RemoveArgs()
2609 {
2610   if ( int pos = myString.Location( '(', 1, Length() ))
2611     myString.Trunc( pos );
2612   myString += ")";
2613   myArgs.Clear();
2614   if ( myBegPos.Length() >= ARG1_IND )
2615     myBegPos.Remove( ARG1_IND, myBegPos.Length() );
2616 }
2617
2618 //================================================================================
2619 /*!
2620  * \brief Set dependent commands after this one
2621  */
2622 //================================================================================
2623
2624 bool _pyCommand::SetDependentCmdsAfter() const
2625 {
2626   bool orderChanged = false;
2627   list< Handle(_pyCommand)>::const_reverse_iterator cmd = myDependentCmds.rbegin();
2628   for ( ; cmd != myDependentCmds.rend(); ++cmd ) {
2629     if ( (*cmd)->GetOrderNb() < GetOrderNb() ) {
2630       orderChanged = true;
2631       theGen->SetCommandAfter( *cmd, this );
2632       (*cmd)->SetDependentCmdsAfter();
2633     }
2634   }
2635   return orderChanged;
2636 }
2637 //================================================================================
2638 /*!
2639  * \brief Insert accessor method after theObjectID
2640   * \param theObjectID - id of the accessed object
2641   * \param theAcsMethod - name of the method giving access to the object
2642   * \retval bool - false if theObjectID is not found in the command string
2643  */
2644 //================================================================================
2645
2646 bool _pyCommand::AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod )
2647 {
2648   if ( !theAcsMethod )
2649     return false;
2650   // start object search from the object, i.e. ignore result
2651   GetObject();
2652   int beg = GetBegPos( OBJECT_IND );
2653   if ( beg < 1 || beg > Length() )
2654     return false;
2655   bool added = false;
2656   while (( beg = myString.Location( theObjectID, beg, Length() )))
2657   {
2658     // check that theObjectID is not just a part of a longer ID
2659     int afterEnd = beg + theObjectID.Length();
2660     Standard_Character c = myString.Value( afterEnd );
2661     if ( !isalnum( c ) && c != ':' ) {
2662       // check if accessor method already present
2663       if ( c != '.' ||
2664            myString.Location( (char*) theAcsMethod, afterEnd, Length() ) != afterEnd+1) {
2665         // insertion
2666         int oldLen = Length();
2667         myString.Insert( afterEnd, (char*) theAcsMethod );
2668         myString.Insert( afterEnd, "." );
2669         // update starting positions of the parts following the modified one
2670         int posDelta = Length() - oldLen;
2671         for ( int i = 1; i <= myBegPos.Length(); ++i ) {
2672           if ( myBegPos( i ) > afterEnd )
2673             myBegPos( i ) += posDelta;
2674         }
2675         added = true;
2676       }
2677     }
2678     beg = afterEnd; // is a part - next search
2679   }
2680   return added;
2681 }
2682
2683 //================================================================================
2684 /*!
2685  * \brief Return method name giving access to an interaface object wrapped by python class
2686   * \retval const char* - method name
2687  */
2688 //================================================================================
2689
2690 const char* _pyObject::AccessorMethod() const
2691 {
2692   return 0;
2693 }
2694 //================================================================================
2695 /*!
2696  * \brief Return ID of a father
2697  */
2698 //================================================================================
2699
2700 _pyID _pyObject::FatherID(const _pyID & childID)
2701 {
2702   int colPos = childID.SearchFromEnd(':');
2703   if ( colPos > 0 )
2704     return childID.SubString( 1, colPos-1 );
2705   return "";
2706 }
2707
2708 //================================================================================
2709 /*!
2710  * \brief SelfEraser erases creation command if no more it's commands invoked
2711  */
2712 //================================================================================
2713
2714 void _pySelfEraser::Flush()
2715 {
2716   if ( GetNbCalls() == 0 )
2717     GetCreationCmd()->Clear();
2718 }
2719
2720 //================================================================================
2721 /*!
2722  * \brief count invoked commands
2723  */
2724 //================================================================================
2725
2726 void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
2727 {
2728   _pyObject::Process(theCommand); // count calls of Process()
2729   GetCreationCmd()->AddDependantCmd( theCommand );
2730 }
2731
2732 //================================================================================
2733 /*!
2734  * \brief Clear creation command if no commands invoked
2735  */
2736 //================================================================================
2737
2738 void _pySubMesh::Flush()
2739 {
2740   if ( GetNbCalls() == 0 ) // move to the end of all commands
2741     theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() );
2742   else if ( !myCreator.IsNull() )
2743     // move to be just after creator
2744     myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
2745 }
2746
2747 //================================================================================
2748 /*!
2749  * \brief To convert creation of a group by filter
2750  */
2751 //================================================================================
2752
2753 void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
2754 {
2755   // Convert the following set of commands into mesh.MakeGroupByFilter(groupName, theFilter)
2756   // group = mesh.CreateEmptyGroup( elemType, groupName )
2757   // aFilter.SetMesh(mesh)
2758   // nbAdd = group.AddFrom( aFilter )
2759   if ( theCommand->GetMethod() == "AddFrom" )
2760   {
2761     _pyID idSource = theCommand->GetArg(1);
2762     // check if idSource is a filter
2763     Handle(_pyObject) filter = theGen->FindObject( idSource );
2764     if ( filter.IsNull() || !filter->IsKind(STANDARD_TYPE(_pyFilter)))
2765       return;
2766     // find aFilter.SetMesh(mesh) to clear it, it should be just before theCommand
2767     list< Handle(_pyCommand) >::reverse_iterator cmdIt = theGen->GetCommands().rbegin();
2768     while ( *cmdIt != theCommand ) ++cmdIt;
2769     while ( (*cmdIt)->GetOrderNb() != 1 )
2770     {
2771       const Handle(_pyCommand)& setMeshCmd = *(++cmdIt);
2772       if ((setMeshCmd->GetObject() == idSource ||
2773            setMeshCmd->GetObject() == Handle(_pyFilter)::DownCast(filter)->GetNewID() )
2774           &&
2775           setMeshCmd->GetMethod() == "SetMesh")
2776       {
2777         setMeshCmd->Clear();
2778         break;
2779       }
2780     }
2781     // replace 3 commands by one
2782     theCommand->Clear();
2783     const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd();
2784     TCollection_AsciiString name = makeGroupCmd->GetArg( 2 );
2785     makeGroupCmd->SetMethod( "MakeGroupByFilter" );
2786     makeGroupCmd->SetArg( 1, name );
2787     makeGroupCmd->SetArg( 2, idSource );
2788     // set new name of a filter
2789     filter->Process( makeGroupCmd );
2790   }
2791 }
2792
2793 //================================================================================
2794 /*!
2795  * \brief Constructor of _pyFilter
2796  */
2797 //================================================================================
2798
2799 _pyFilter::_pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID/*=""*/)
2800   :_pyObject(theCreationCmd), myNewID( newID )
2801 {
2802 }
2803
2804 //================================================================================
2805 /*!
2806  * \brief To convert creation of a filter by criteria and
2807  * to replace an old name by a new one
2808  */
2809 //================================================================================
2810
2811 void _pyFilter::Process( const Handle(_pyCommand)& theCommand)
2812 {
2813   if ( theCommand->GetObject() == GetID() )
2814     _pyObject::Process(theCommand); // count commands
2815
2816   if ( !myNewID.IsEmpty() )
2817   {
2818     if ( theCommand->GetObject() == GetID() )
2819       theCommand->SetObject( myNewID );
2820     else if ( theCommand->GetResultValue() == GetID() )
2821       theCommand->SetResultValue( myNewID );
2822     else
2823       for ( int i = 1, nb = theCommand->GetNbArgs(); i <= nb; ++i )
2824         if ( theCommand->GetArg( i ) == GetID() )
2825         {
2826           theCommand->SetArg( i, myNewID );
2827           break;
2828         }
2829   }
2830
2831   // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria)
2832   // aFilter0x2aaab0487080 = aFilterManager.CreateFilter()
2833   // aFilter0x2aaab0487080.SetCriteria(aCriteria)
2834   if ( GetNbCalls() == 0 && // none method was called before SetCriteria()
2835        theCommand->GetMethod() == "SetCriteria")
2836   {
2837     // aFilter.SetCriteria(aCriteria) ->
2838     // aFilter = smesh.GetFilterFromCriteria(criteria)
2839     if ( myNewID.IsEmpty() )
2840       theCommand->SetResultValue( GetID() );
2841     else
2842       theCommand->SetResultValue( myNewID );
2843     theCommand->SetObject( SMESH_2smeshpy::GenName() );
2844     theCommand->SetMethod( "GetFilterFromCriteria" );
2845
2846     // Clear aFilterManager.CreateFilter()
2847     GetCreationCmd()->Clear();
2848   }
2849   else if ( theCommand->GetMethod() == "SetMesh")
2850   {
2851     theGen->AddMeshAccessorMethod( theCommand );
2852   }
2853 }
2854
2855 //================================================================================
2856 /*!
2857  * \brief Set new filter name to the creation command
2858  */
2859 //================================================================================
2860
2861 void _pyFilter::Flush()
2862 {
2863   if ( !myNewID.IsEmpty() && !GetCreationCmd()->IsEmpty() )
2864     GetCreationCmd()->SetResultValue( myNewID );
2865 }