Salome HOME
Update of CheckDone
[modules/smesh.git] / src / SMESH_I / SMESH_NoteBook.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File      : SMESH_NoteBook.cxx
21 // Author    : Roman NIKOLAEV
22 //
23 #include "SMESH_2smeshpy.hxx"
24 #include "SMESH_NoteBook.hxx"
25 #include "SMESH_Gen_i.hxx"
26 #include "SMESH_PythonDump.hxx"
27 #include "SMESH_Hypothesis_i.hxx"
28
29 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
30 #include <TColStd_SequenceOfAsciiString.hxx>
31 #include <TColStd_HSequenceOfInteger.hxx>
32
33 #include <SALOMEDS_wrap.hxx>
34 #include <SALOMEDS_Attributes_wrap.hxx>
35
36 #include <vector>
37 #include <string>
38
39 using namespace std;
40
41
42 namespace
43 {
44   /*!
45    *  Set variable of the SMESH_ObjectStates from position to the _pyCommand
46    *  method as nbArg argument
47    */
48   void SetVariable(Handle(_pyCommand) theCommand,
49                    const SMESH_ObjectStates* theStates,
50                    size_t position, int theArgNb)
51   {
52     if(theStates->GetCurrectState().size() > position)
53       if(!theStates->GetCurrectState().at(position).IsEmpty())
54         theCommand->SetArg(theArgNb,theStates->GetCurrectState().at(position));
55   }
56 }
57
58 //================================================================================
59 /*!
60  * \brief Constructor
61  */
62 //================================================================================
63 SMESH_ObjectStates::SMESH_ObjectStates(TCollection_AsciiString theType)
64 {
65   _type = theType;
66   _dumpstate = 0;
67 }
68
69 //================================================================================
70 /*!
71  * \brief Destructor
72  */
73 //================================================================================
74 SMESH_ObjectStates::~SMESH_ObjectStates()
75 {
76 }
77
78 //================================================================================
79 /*!
80  * \brief Add new object state 
81  * \param theState - Object state (vector of notebook variable)
82  */
83 //================================================================================
84 void SMESH_ObjectStates::AddState(const TState &theState)
85 {
86   _states.push_back(theState);
87 }
88
89 //================================================================================
90 /*!
91  * \brief Return current object state
92  * \\retval state - Object state (vector of notebook variable)
93  */
94 //================================================================================
95 TState SMESH_ObjectStates::GetCurrectState() const
96 {
97   if ( (int) _states.size() > _dumpstate)
98     return _states[_dumpstate];
99   TState empty;
100   return empty;
101 }
102
103
104 //================================================================================
105 /*!
106  *
107  */
108 //================================================================================
109 TAllStates SMESH_ObjectStates::GetAllStates() const
110 {
111   return _states;
112 }
113
114 //================================================================================
115 /*!
116  *
117  */
118 //================================================================================
119 void SMESH_ObjectStates::IncrementState()
120 {
121   _dumpstate++;
122 }
123
124 //================================================================================
125 /*!
126  *
127  */
128 //================================================================================
129 TCollection_AsciiString SMESH_ObjectStates::GetObjectType() const{
130   return _type;
131 }
132
133
134 //================================================================================
135 /*!
136  * \brief Constructor
137  */
138 //================================================================================
139 LayerDistributionStates::LayerDistributionStates():
140   SMESH_ObjectStates("LayerDistribution")
141 {
142 }
143 //================================================================================
144 /*!
145  * \brief Destructor
146  */
147 //================================================================================
148 LayerDistributionStates::~LayerDistributionStates()
149 {
150 }
151
152
153 //================================================================================
154 /*!
155  * \brief AddDistribution
156  */
157 //================================================================================
158 void LayerDistributionStates::AddDistribution(const TCollection_AsciiString& theDistribution)
159 {
160   _distributions.insert(pair<TCollection_AsciiString,TCollection_AsciiString>(theDistribution,""));
161 }
162
163 //================================================================================
164 /*!
165  * \brief HasDistribution
166  */
167 //================================================================================
168 bool LayerDistributionStates::HasDistribution(const TCollection_AsciiString& theDistribution) const
169 {
170   return _distributions.find(theDistribution) != _distributions.end();
171 }
172
173 //================================================================================
174 /*!
175  * \brief SetDistributionType
176  */
177 //================================================================================
178 bool LayerDistributionStates::SetDistributionType(const TCollection_AsciiString& theDistribution,
179                                                   const TCollection_AsciiString& theType)
180 {
181   TDistributionMap::iterator it = _distributions.find(theDistribution);
182   if(it == _distributions.end())
183     return false;
184   (*it).second = theType;
185   return true;
186 }
187
188 //================================================================================
189 /*!
190  * \brief GetDistributionType
191  */
192 //================================================================================
193 TCollection_AsciiString LayerDistributionStates::
194 GetDistributionType(const TCollection_AsciiString& theDistribution) const
195 {
196   TDistributionMap::const_iterator it = _distributions.find(theDistribution);
197   return (it == _distributions.end()) ? TCollection_AsciiString() : (*it).second;
198 }
199
200 //================================================================================
201 /*!
202  * \brief Constructor
203  */
204 //================================================================================
205 SMESH_NoteBook::SMESH_NoteBook()
206 {
207   InitObjectMap();
208 }
209
210 //================================================================================
211 /*!
212  * \brief Destructor
213  */
214 //================================================================================
215 SMESH_NoteBook::~SMESH_NoteBook()
216 {
217   TVariablesMap::const_iterator it = _objectMap.begin();
218   for(;it!=_objectMap.end();it++) {
219     if((*it).second)
220       delete (*it).second;
221   }
222 }
223
224 //================================================================================
225 /*!
226  * \brief Replace parameters of the functions on the Salome NoteBook Variables
227  * \param theString - Input string
228  * \retval TCollection_AsciiString - Conversion result
229  */
230 //================================================================================
231 void SMESH_NoteBook::ReplaceVariables()
232 {
233   for ( size_t i = 0 ; i < _commands.size(); i++ )
234   {
235     Handle(_pyCommand) aCmd = _commands[i];
236     TCollection_AsciiString aMethod      = aCmd->GetMethod();
237     TCollection_AsciiString aObject      = aCmd->GetObject();
238     TCollection_AsciiString aResultValue = aCmd->GetResultValue();
239     if(SALOME::VerbosityActivated()) {
240       cout<<"Command before : "<< aCmd->GetString()<<endl;
241       cout<<"Method : "<< aMethod<<endl;
242       cout<<"Object : "<< aObject<<endl;
243       cout<<"Result : "<< aResultValue<<endl;
244     }
245
246     // NEW APPROACH
247     // Names of variables are stored in the Study, in "StringAttribute". Python commands
248     // store zero-based indices (as e.g.'$1$') of variables within "StringAttribute";
249     // An entry of object storing "StringAttribute" is at the end of the command
250     // after TVar::ObjPrefix().
251
252     // Get the entry of object storing "StringAttribute"
253     TCollection_AsciiString & cmdStr = aCmd->GetString();
254     TEntry2VarVecMap::iterator ent2varVec;
255     Standard_Integer fromIndex = 6;
256     Standard_Integer cmdLen = cmdStr.Length();
257     if ( int pos = (fromIndex <= cmdLen) ? cmdStr.Location( SMESH::TVar::ObjPrefix(), fromIndex, cmdLen ) : 0 )
258     {
259       TCollection_AsciiString varHolderEntry =
260         cmdStr.SubString( pos + strlen( SMESH::TVar::ObjPrefix() ), cmdLen );
261       ent2varVec = _entry2VarsMap.find( varHolderEntry );
262       cmdStr.Split( pos - 1 );
263     }
264     else
265     {
266       ent2varVec = _entry2VarsMap.find( aObject );
267     }
268     // Set variables in cmdStr
269     if ( ent2varVec != _entry2VarsMap.end() && !ent2varVec->second.empty() )
270     {
271       const std::vector< std::string >& vars = ent2varVec->second;
272       int pos = 1, pos2;
273       // look for '$VarIndex$' in cmdStr. TVar::Quote() == '$'
274       while (( pos  = cmdStr.Location( 1, SMESH::TVar::Quote(), pos,   cmdStr.Length() )) &&
275              ( pos2 = cmdStr.Location( 1, SMESH::TVar::Quote(), pos+1, cmdStr.Length() )) )
276       {
277         size_t varIndex = std::string::npos;
278         const char* varIndexPtr = cmdStr.ToCString() + pos;
279         if ( '0' <= *varIndexPtr && *varIndexPtr <= '9' )
280           varIndex = atoi( varIndexPtr );
281         if ( 0 <= (int)varIndex && varIndex < vars.size() && !vars[varIndex].empty() )
282         {
283           // replace '$VarIndex$' either by var name or var value
284           const char var0    = vars[varIndex][0];
285           const bool isValue = (( '0' <= var0 && var0 <= '9' ) || var0 == '-');
286           if ( isValue ) // remove TVar::Quote() as well
287             pos2 += 2; // pos still points to '$'
288           int indexLen = pos2 - pos - 1;
289           int  lenDiff = int( vars[varIndex].size() ) - indexLen;
290           if      ( lenDiff > 0 )
291             cmdStr.InsertBefore( pos2, vars[varIndex].c_str() + vars[varIndex].size() - lenDiff );
292           else if ( lenDiff < 0 )
293             cmdStr.Remove( pos+1, -lenDiff );
294           cmdStr.SetValue( pos+(!isValue), vars[varIndex].c_str() );
295         }
296         pos = pos2 + 1;
297         if ( pos + 2 >= cmdStr.Length() )
298           break;
299       }
300     }
301
302     // OLD APPROACH
303     // Variable names are stored historically in "StringAttribute",
304     // i.e. for each command there is a set of either var names or separated empty places.
305
306     // check if method modifies the object itself
307     TVariablesMap::const_iterator it = _objectMap.find(aObject);
308     if(it == _objectMap.end()) // check if method returns a new object
309       it = _objectMap.find(aResultValue);
310     
311     if(it == _objectMap.end()) { // check if method modifies a mesh using mesh editor
312       TMeshEditorMap::const_iterator meIt = _meshEditors.find(aObject);
313       if(meIt != _meshEditors.end()) {
314         TCollection_AsciiString aMesh = (*meIt).second;
315         it = _objectMap.find(aMesh);
316       }
317     }
318     
319     if(it == _objectMap.end()) { // additional check for pattern mapping
320       if(aMethod.IsEqual("ApplyToMeshFaces") ||
321          aMethod.IsEqual("ApplyToHexahedrons"))
322         it = _objectMap.find(aCmd->GetArg(1));
323     }
324
325     if(it != _objectMap.end()) {
326       if(SALOME::VerbosityActivated())
327         cout << "Found object : " << (*it).first << endl;
328       SMESH_ObjectStates *aStates = (*it).second;
329       // Case for LocalLength hypothesis
330       if(aStates->GetObjectType().IsEqual("LocalLength") && aStates->GetCurrectState().size() >= 2)
331       {
332         if(aMethod.IsEqual("SetLength")) {
333           if(!aStates->GetCurrectState().at(0).IsEmpty() )
334             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
335           aStates->IncrementState();
336         }
337         else if(aMethod.IsEqual("SetPrecision")) {
338           if(!aStates->GetCurrectState().at(1).IsEmpty() )
339             aCmd->SetArg(1,aStates->GetCurrectState().at(1));
340           aStates->IncrementState();
341         }
342       }
343       
344       // Case for SegmentLengthAroundVertex hypothesis
345       else if(aStates->GetObjectType().IsEqual("SegmentLengthAroundVertex")
346               && aStates->GetCurrectState().size() >= 1) {
347         if(aMethod == "SetLength") {
348           if(!aStates->GetCurrectState().at(0).IsEmpty() )
349             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
350           aStates->IncrementState();
351         }
352       }
353
354       // Case for Arithmetic1D and StartEndLength hypothesis
355       else if(aStates->GetObjectType().IsEqual("Arithmetic1D") || 
356               aStates->GetObjectType().IsEqual("StartEndLength")) {
357         if(aMethod == "SetLength" &&
358            aStates->GetCurrectState().size() >= 2) {
359           if(aCmd->GetArg(2) == "1" && !aStates->GetCurrectState().at(0).IsEmpty())
360             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
361           else if(!aStates->GetCurrectState().at(1).IsEmpty())
362             aCmd->SetArg(1,aStates->GetCurrectState().at(1));
363           aStates->IncrementState();
364         }
365       }
366       
367       //Case for Deflection1D hypothesis
368       else if(aStates->GetObjectType().IsEqual("Deflection1D")){
369         if(aMethod == "SetDeflection" && aStates->GetCurrectState().size() >= 1) {
370           if(!aStates->GetCurrectState().at(0).IsEmpty() )
371             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
372           aStates->IncrementState();
373         }
374       }
375       
376       // Case for LayerDistribution hypothesis (not finished yet)
377       else if(aStates->GetObjectType() == "LayerDistribution") {
378         if(aMethod == "SetLayerDistribution"){
379           LayerDistributionStates* aLDStates = (LayerDistributionStates*)(aStates);
380           aLDStates->AddDistribution(aCmd->GetArg(1));
381           if(SALOME::VerbosityActivated())
382             cout<<"Add Distribution :"<<aCmd->GetArg(1)<<endl;
383         }
384       }
385       
386       // Case for MaxElementArea hypothesis
387       else if(aStates->GetObjectType().IsEqual("MaxElementArea")){
388         if(aMethod == "SetMaxElementArea" && aStates->GetCurrectState().size() >= 1) {
389           if(!aStates->GetCurrectState().at(0).IsEmpty() )
390             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
391           aStates->IncrementState();
392         }
393       }
394
395       // Case for MaxElementVolume hypothesis
396       else if(aStates->GetObjectType().IsEqual("MaxElementVolume")){
397         if(aMethod == "SetMaxElementVolume" && aStates->GetCurrectState().size() >= 1) {
398           if(!aStates->GetCurrectState().at(0).IsEmpty() )
399             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
400           aStates->IncrementState();
401         }
402       }
403       // Case for NumberOfLayers hypothesis
404       else if(aStates->GetObjectType().IsEqual("NumberOfLayers")){
405         if(aMethod == "SetNumberOfLayers" && aStates->GetCurrectState().size() >= 1) {
406           if(!aStates->GetCurrectState().at(0).IsEmpty() )
407             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
408           aStates->IncrementState();
409         }
410       }
411
412       // Case for NumberOfSegments hypothesis
413       else if(aStates->GetObjectType().IsEqual("NumberOfSegments")){
414         if(aMethod == "SetNumberOfSegments" && aStates->GetCurrectState().size() >= 1) {
415           if(!aStates->GetCurrectState().at(0).IsEmpty() )
416             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
417           if(aStates->GetCurrectState().size()==1)
418             aStates->IncrementState();
419         }
420         else if (aMethod == "SetScaleFactor" && aStates->GetCurrectState().size() >= 2) {
421           if(!aStates->GetCurrectState().at(1).IsEmpty() )
422             aCmd->SetArg(1,aStates->GetCurrectState().at(1));
423           aStates->IncrementState();
424         }
425       }
426       
427       else if(aStates->GetObjectType().IsEqual("Mesh")) {
428         TState aCurrentState = aStates->GetCurrectState();
429         int aCurrentStateSize = aCurrentState.size();
430         if(aMethod.IsEqual("Translate")                  ||
431            aMethod.IsEqual("TranslateMakeGroups")        ||
432            aMethod.IsEqual("TranslateMakeMesh")          ||
433            aMethod.IsEqual("TranslateObject")            ||
434            aMethod.IsEqual("TranslateObjectMakeGroups")  ||
435            aMethod.IsEqual("TranslateObjectMakeMesh")) {
436           bool isVariableFound = false;
437           int anArgIndex = 0;
438           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
439             if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
440               anArgIndex = i+1;
441               break;
442             }
443           }
444           if(anArgIndex > 0) {
445             if(aCurrentStateSize == 3) { // translation by dx, dy, dz
446               for(int j = 0; j < aCurrentStateSize; j++) {
447                 if(!aCurrentState.at(j).IsEmpty()) {
448                   isVariableFound = true;
449                   aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
450                 }
451               }
452             }
453             else if(aCurrentStateSize == 6) { // translation by x1, x2, y1, y2, z1, z2
454               // TODO: limitation until operations on the variables will be introduced
455               /*
456               isVariableFound = true;
457               for(int j = 0; j < 3; j++) {
458                 TCollection_AsciiString anArg = aCmd->GetArg(anArgIndex+j);
459                 TCollection_AsciiString aValue1 = aCurrentState.at(2*j), aValue2 = aCurrentState.at(2*j+1);
460                 bool aV1 = !aValue1.IsEmpty();
461                 bool aV2 = !aValue2.IsEmpty();
462                 double aValue, aCurrentValue = anArg.IsRealValue() ? anArg.RealValue() : 0;
463                 if(aV1 && !aV2) {
464                   if(!GetReal(aValue1, aValue))
465                     aValue = 0;
466                   aValue2 = TCollection_AsciiString( aValue + aCurrentValue );
467                 }
468                 else if(!aV1 && aV2) {
469                   if(!GetReal(aValue2, aValue))
470                     aValue = 0;
471                   aValue1 = TCollection_AsciiString( aValue - aCurrentValue );
472                 }
473                 else if(!aV1 && !aV2) {
474                   aValue1 = TCollection_AsciiString( 0 );
475                   aValue2 = TCollection_AsciiString( aCurrentValue );
476                 }
477                 aCmd->SetArg(anArgIndex+j, aValue1 + ", " + aValue2 );
478               }
479               */
480             }
481           }
482           if(isVariableFound) {
483             TCollection_AsciiString aDim;
484             if(aCurrentStateSize == 6)
485               aDim = "6";
486             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr"+aDim);
487             aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr");
488           }
489           aStates->IncrementState();
490         }
491         else if(aMethod.IsEqual("Rotate")                  ||
492                 aMethod.IsEqual("RotateMakeGroups")        ||
493                 aMethod.IsEqual("RotateMakeMesh")          ||
494                 aMethod.IsEqual("RotateObject")            ||
495                 aMethod.IsEqual("RotateObjectMakeGroups")  ||
496                 aMethod.IsEqual("RotateObjectMakeMesh")    ||
497                 aMethod.IsEqual("RotationSweep")           ||
498                 aMethod.IsEqual("RotationSweepObject")     ||
499                 aMethod.IsEqual("RotationSweepObject1D")   ||
500                 aMethod.IsEqual("RotationSweepObject2D")   ||
501                 aMethod.IsEqual("RotationSweepMakeGroups") ||
502                 aMethod.IsEqual("RotationSweepObjectMakeGroups") ||
503                 aMethod.IsEqual("RotationSweepObject1DMakeGroups") ||
504                 aMethod.IsEqual("RotationSweepObject2DMakeGroups") ||
505                 aMethod.IsEqual("Mirror")                  ||
506                 aMethod.IsEqual("MirrorMakeMesh")          ||
507                 aMethod.IsEqual("MirrorMakeGroups")        ||
508                 aMethod.IsEqual("MirrorObject")            || 
509                 aMethod.IsEqual("MirrorObjectMakeMesh")    ||
510                 aMethod.IsEqual("MirrorObjectMakeGroups")) {
511           bool isSubstitute = false;
512           int anArgIndex = 0;
513           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
514             if(aCmd->GetArg(i).IsEqual("SMESH.AxisStruct")) {
515               anArgIndex = i+1;
516               break;
517             }
518           }
519           if(anArgIndex > 0) {
520             for(int j = 0; j < aCurrentStateSize; j++) {
521               if(!aCurrentState.at(j).IsEmpty()) {
522                 if(j < 6) // 0-5 - axis struct, 6 - angle (rotation & sweep), 7-8 - nbSteps and tolerance (sweep)
523                   isSubstitute = true;
524                 aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
525               }
526             }
527           }
528           if(isSubstitute)
529             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".AxisStructStr");
530           aStates->IncrementState();
531         }
532         else if(aMethod.IsEqual("AddNode") ||
533                 aMethod.IsEqual("MoveClosestNodeToPoint")) {
534           for(int j = 0; j < aCurrentStateSize; j++) {
535             if(!aCurrentState.at(j).IsEmpty())
536               aCmd->SetArg(j+1, aCurrentState.at(j));
537           }
538           aStates->IncrementState();
539         }
540         else if(aMethod.IsEqual("MoveNode")) {
541           for(int j = 0; j < aCurrentStateSize; j++) {
542             if(!aCurrentState.at(j).IsEmpty())
543               aCmd->SetArg(j+2, aCurrentState.at(j));
544           }
545           aStates->IncrementState();
546         }
547         else if(aMethod.IsEqual("ExtrusionSweep") ||
548                 aMethod.IsEqual("ExtrusionSweepObject") ||
549                 aMethod.IsEqual("ExtrusionSweepObject1D") ||
550                 aMethod.IsEqual("ExtrusionSweepObject2D") ||
551                 aMethod.IsEqual("ExtrusionSweepMakeGroups") ||
552                 aMethod.IsEqual("ExtrusionSweepObjectMakeGroups") ||
553                 aMethod.IsEqual("ExtrusionSweepObject1DMakeGroups") ||
554                 aMethod.IsEqual("ExtrusionSweepObject2DMakeGroups")) {
555           bool isSubstitute = false;
556           int anArgIndex = 0;
557           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
558             if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
559               anArgIndex = i+1;
560               break;
561             }
562           }
563           if(anArgIndex > 0) {
564             for(int j = 0; j < aCurrentStateSize; j++) {
565               if(!aCurrentState.at(j).IsEmpty()) {
566                 if(j < 3) // 0-2 - dir struct, 3 - number of steps
567                   isSubstitute = true;
568                 aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
569               }
570             }
571           }
572           if(isSubstitute) {
573             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr");
574             aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr");
575           }
576           aStates->IncrementState();
577         }
578         else if(aMethod.IsEqual("ExtrusionAlongPath") ||
579                 aMethod.IsEqual("ExtrusionAlongPathObject") ||
580                 aMethod.IsEqual("ExtrusionAlongPathObject1D") ||
581                 aMethod.IsEqual("ExtrusionAlongPathObject2D") ||
582                 aMethod.IsEqual("ExtrusionAlongPathMakeGroups") ||
583                 aMethod.IsEqual("ExtrusionAlongPathObjectMakeGroups") ||
584                 aMethod.IsEqual("ExtrusionAlongPathObject1DMakeGroups") ||
585                 aMethod.IsEqual("ExtrusionAlongPathObject2DMakeGroups") ||
586                 /* workaround for a bug in the command parsing algorithm */
587                 aCmd->GetString().Search("ExtrusionAlongPathMakeGroups") != -1 ||
588                 aCmd->GetString().Search("ExtrusionAlongPathObjectMakeGroups") != -1 ||
589                 aCmd->GetString().Search("ExtrusionAlongPathObject1DMakeGroups") != -1 ||
590                 aCmd->GetString().Search("ExtrusionAlongPathObject2DMakeGroups") != -1 ) {
591           int aNbAngles = aCurrentStateSize-3; // State looks like "Angle1:...:AngleN:X:Y:Z"
592           bool isSubstitute = false;
593           int anArgIndex = 0;
594           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
595             if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
596               anArgIndex = i-1-aNbAngles;
597               break;
598             }
599           }
600           if(anArgIndex > 0) {
601             int j = 0;
602             for(; j < aNbAngles; j++) {
603               if(!aCurrentState.at(j).IsEmpty()) {
604                 aCmd->SetArg(anArgIndex+j-1, aCurrentState.at(j));
605               }
606             }
607             for(; j < aNbAngles+3; j++) {
608               if(!aCurrentState.at(j).IsEmpty()) {
609                 isSubstitute = true;
610                 aCmd->SetArg(anArgIndex+j+2, aCurrentState.at(j));
611               }
612             }
613           }
614           if(isSubstitute)
615             aCmd->SetArg(anArgIndex + aNbAngles + 1,
616                          TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr");
617           aStates->IncrementState();
618         }
619         else if(aMethod.IsEqual("TriToQuad") ||
620                 aMethod.IsEqual("Concatenate") ||
621                 aMethod.IsEqual("ConcatenateWithGroups")) {
622           if(aCurrentStateSize && !aCurrentState.at(0).IsEmpty())
623             aCmd->SetArg(aCmd->GetNbArgs(), aCurrentState.at(0));
624           aStates->IncrementState();
625         }
626         else if(aMethod.IsEqual("Smooth") ||
627                 aMethod.IsEqual("SmoothObject") ||
628                 aMethod.IsEqual("SmoothParametric") ||
629                 aMethod.IsEqual("SmoothParametricObject")) {
630           int anArgIndex = aCmd->GetNbArgs() - 2;
631           for(int j = 0; j < aCurrentStateSize; j++) {
632             if(!aCurrentState.at(j).IsEmpty())
633               aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
634           }
635           aStates->IncrementState();
636         }
637         else if(aMethod.IsEqual("ApplyToMeshFaces") ||
638                 aMethod.IsEqual("ApplyToHexahedrons")) {
639           int anArgIndex = aCmd->GetNbArgs()-1;
640           for(int j = 0; j < aCurrentStateSize; j++)
641             if(!aCurrentState.at(j).IsEmpty())
642               aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
643           aStates->IncrementState();
644         }
645       } // if ( aStates->GetObjectType().IsEqual("Mesh"))
646
647       // Case for NETGEN_Parameters_2D or NETGEN_Parameters_2D hypothesis
648       // else if(aStates->GetObjectType().IsEqual("NETGEN_Parameters_2D") ||
649       //         aStates->GetObjectType().IsEqual("NETGEN_Parameters")){
650       //   if(aMethod == "SetMaxSize" && aStates->GetCurrectState().size() >= 1) {
651       //     if(!aStates->GetCurrectState().at(0).IsEmpty() )
652       //       aCmd->SetArg(1,aStates->GetCurrectState().at(0));
653       //     aStates->IncrementState();
654       //   }
655       //   else if(aMethod == "SetGrowthRate" && aStates->GetCurrectState().size() >= 2) {
656       //     if(!aStates->GetCurrectState().at(1).IsEmpty() )
657       //       aCmd->SetArg(1,aStates->GetCurrectState().at(1));
658       //     aStates->IncrementState();
659       //   }
660       //   else if(aMethod == "SetNbSegPerEdge" && aStates->GetCurrectState().size() >= 3) {
661       //     if(!aStates->GetCurrectState().at(2).IsEmpty() )
662       //       aCmd->SetArg(1,aStates->GetCurrectState().at(2));
663       //     aStates->IncrementState();
664       //   }
665       //   else if(aMethod == "SetNbSegPerRadius" && aStates->GetCurrectState().size() >= 4) {
666       //     if(!aStates->GetCurrectState().at(3).IsEmpty() )
667       //       aCmd->SetArg(1,aStates->GetCurrectState().at(3));
668       //     aStates->IncrementState();
669       //   }
670       // }
671
672       // // Case for NETGEN_SimpleParameters_3D or NETGEN_SimpleParameters_2D hypothesis
673       // else if(aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_3D") ||
674       //         aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_2D")) {
675
676       //   if((aMethod == "SetNumberOfSegments" || aMethod == "SetLocalLength") && 
677       //      aStates->GetCurrectState().size() >= 1) {
678       //     if(!aStates->GetCurrectState().at(0).IsEmpty() )
679       //       aCmd->SetArg(1,aStates->GetCurrectState().at(0));
680       //     aStates->IncrementState();
681       //   }
682       //   else if(aMethod == "SetMaxElementArea" && aStates->GetCurrectState().size() >= 2) {
683       //     if(!aStates->GetCurrectState().at(1).IsEmpty() )
684       //       aCmd->SetArg(1,aStates->GetCurrectState().at(1));
685       //     aStates->IncrementState();
686       //   }
687       //   else if(aMethod == "SetMaxElementVolume" && aStates->GetCurrectState().size() >= 3) {
688       //     if(!aStates->GetCurrectState().at(2).IsEmpty() )
689       //       aCmd->SetArg(1,aStates->GetCurrectState().at(2));
690       //     aStates->IncrementState();
691       //   }
692       //   else if(aMethod == "LengthFromEdges" || aMethod == "LengthFromFaces"){
693       //     aStates->IncrementState();
694       //   }
695       // }
696
697       else
698       {
699         // treat Netgen hypotheses;
700         // this (and above) code can work wrong since nb of states can differ from nb of
701         // dumped calls due to the fix of
702         // issue 0021364:: Dump of netgen parameters has duplicate lines
703         SMESH_Gen_i *          aGen = SMESH_Gen_i::GetSMESHGen();
704         SALOMEDS::SObject_wrap sobj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( (*it).first.ToCString() );
705         CORBA::Object_var       obj = aGen->SObjectToObject( sobj );
706         if ( SMESH_Hypothesis_i* h = SMESH::DownCast< SMESH_Hypothesis_i*>( obj ))
707         {
708           TState aCurrentState = aStates->GetCurrectState();
709           int         argIndex = h->getParamIndex( aMethod, aCurrentState.size() );
710           if ( 0 <= argIndex && argIndex < (int)aCurrentState.size() &&
711                !aCurrentState[argIndex].IsEmpty() )
712             aCmd->SetArg( 1, aCurrentState[argIndex] );
713
714           if ( argIndex >= 0 )
715             aStates->IncrementState();
716         }
717       }
718     }
719     else {
720       if(SALOME::VerbosityActivated())
721         cout << "Object not found" << endl;
722     }
723     if(SALOME::VerbosityActivated()) {
724       cout<<"Command after: "<< aCmd->GetString()<<endl;
725     }
726   }
727   
728   ProcessLayerDistribution();
729 }
730 //================================================================================
731 /*!
732  * \brief Private method
733  */
734 //================================================================================
735 void SMESH_NoteBook::InitObjectMap()
736 {
737   SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen();
738   if(!aGen)
739     return;
740   
741   SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->getStudyServant();
742   if(aStudy->_is_nil())
743     return;
744   
745   CORBA::String_var compDataType = aGen->ComponentDataType();
746   SALOMEDS::SObject_wrap     aSO = aStudy->FindComponent( compDataType.in() );
747   if(CORBA::is_nil(aSO))
748     return;
749   
750   SALOMEDS::ChildIterator_wrap Itr = aStudy->NewChildIterator(aSO);
751   for( Itr->InitEx(true); Itr->More(); Itr->Next())
752   {
753     SALOMEDS::SObject_wrap aSObject = Itr->Value();
754     SALOMEDS::GenericAttribute_wrap anAttr;
755     if ( aSObject->FindAttribute( anAttr.inout(), "AttributeString"))
756     {
757       SALOMEDS::AttributeString_wrap strAttr = anAttr;
758       CORBA::String_var          aParameters = strAttr->Value();
759       CORBA::String_var                 anID = aSObject->GetID();
760       std::vector< std::string >     allVars = aGen->GetAllParameters( anID.in() );
761       SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters.in());
762       _entry2VarsMap[ TCollection_AsciiString( anID.in() )] = allVars;
763       if(SALOME::VerbosityActivated()) {
764         cout<<"Entry : "<< anID<<endl;
765         cout<<"aParameters : "<<aParameters<<endl;
766       }
767       TCollection_AsciiString anObjType;
768       CORBA::Object_var       anObject = SMESH_Gen_i::SObjectToObject(aSObject);
769       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(anObject);
770       SMESH::SMESH_Mesh_var      aMesh = SMESH::SMESH_Mesh::_narrow(anObject);
771       if(!aHyp->_is_nil()) {
772         CORBA::String_var hypName = aHyp->GetName();
773         anObjType = hypName.in();
774       }
775       else if (!aMesh->_is_nil() ) {
776         anObjType = "Mesh";
777       }
778       if(SALOME::VerbosityActivated())
779         cout<<"The object Type : "<<anObjType<<endl;
780       SMESH_ObjectStates *aState = NULL;
781       if(anObjType == "LayerDistribution")
782         aState = new LayerDistributionStates();
783       else
784         aState = new SMESH_ObjectStates(anObjType);
785
786       for ( size_t i = 0; i < aSections->length(); i++ ) {
787         TState aVars;
788         SALOMEDS::ListOfStrings aListOfVars = aSections[i];
789         for ( size_t j = 0; j < aListOfVars.length(); j++)
790         {
791           TCollection_AsciiString aVar(aListOfVars[j].in());
792           if(!aVar.IsEmpty() && aStudy->IsVariable(aVar.ToCString())) {
793             aVar.InsertBefore(1,            SMESH::TVar::Quote() );
794             aVar.InsertAfter(aVar.Length(), SMESH::TVar::Quote() );
795           }
796           aVars.push_back(aVar);
797           if(SALOME::VerbosityActivated()) {
798             cout<<"Variable: '"<<aVar<<"'"<<endl;
799           }
800         }
801         aState->AddState(aVars);
802       }
803       if ( aState->GetAllStates().empty() )
804       {
805         delete aState;
806       }
807       else
808       {
809         CORBA::String_var objID = aSObject->GetID();
810         _objectMap.insert( make_pair(TCollection_AsciiString( objID.in() ), aState ));
811       }
812     }
813   }
814 }
815
816 //================================================================================
817 /*!
818  * 
819  */
820 //================================================================================
821 void SMESH_NoteBook::AddCommand(const TCollection_AsciiString& theString)
822 {
823   if(SALOME::VerbosityActivated())
824     cout<<theString<<endl;
825   Handle(_pyCommand) aCommand = new _pyCommand( theString, -1);
826   _commands.push_back(aCommand);
827
828   if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
829     _meshEditors.insert( make_pair( aCommand->GetResultValue(),
830                                     aCommand->GetObject() ) );
831   }
832 }
833
834 //================================================================================
835 /*!
836  * 
837  */
838 //================================================================================
839 void SMESH_NoteBook::ProcessLayerDistribution()
840 {
841   // 1) Find all LayerDistribution states
842   vector<LayerDistributionStates*> aLDS;
843   TVariablesMap::const_iterator it = _objectMap.begin();
844   for(;it != _objectMap.end();it++) {
845     LayerDistributionStates* aLDStates = dynamic_cast<LayerDistributionStates*>(((*it).second));
846     if(aLDStates!=NULL) {
847       aLDS.push_back(aLDStates);
848     }
849   }
850   
851   if(!aLDS.size())
852     return;
853   
854   // 2) Initialize all type of 1D Distribution hypothesis
855   for ( size_t i = 0; i < _commands.size(); i++ ) {
856     for ( size_t j = 0; j < aLDS.size(); j++ ) {
857       TCollection_AsciiString aResultValue = _commands[i]->GetResultValue();
858       if(_commands[i]->GetMethod() == "CreateHypothesis" &&
859          aLDS[j]->HasDistribution(aResultValue)){
860         TCollection_AsciiString aType = _commands[i]->GetArg(1);
861         aType.RemoveAll('\'');
862         aLDS[j]->SetDistributionType(aResultValue,aType);
863       }
864     }
865   }
866   // 3) ... and replase variables ...
867
868   for ( size_t i = 0; i < _commands.size(); i++ ) {
869     for ( size_t j = 0; j < aLDS.size(); j++ ) {
870       TCollection_AsciiString anObject = _commands[i]->GetObject();
871
872       if(aLDS[j]->HasDistribution(anObject)) {
873         TCollection_AsciiString aType = aLDS[j]->GetDistributionType(anObject);
874         TCollection_AsciiString aMethod = _commands[i]->GetMethod();
875         if(aType == "LocalLength") {
876           if(aMethod == "SetLength") {
877             SetVariable(_commands[i], aLDS[j],0,1);
878             aLDS[j]->IncrementState();
879           }
880           else if(aMethod == "SetPrecision") {
881             SetVariable(_commands[i], aLDS[j],1,1);
882             aLDS[j]->IncrementState();
883           }
884         }
885
886         // Case for NumberOfSegments hypothesis
887         else if(aType == "NumberOfSegments"){
888           if(aMethod == "SetNumberOfSegments") {
889             SetVariable(_commands[i], aLDS[j],0,1);
890             if(aLDS[j]->GetCurrectState().size()==1)
891               aLDS[j]->IncrementState();
892           }
893           else if (aMethod == "SetScaleFactor") {
894             SetVariable(_commands[i], aLDS[j],1,1);
895             aLDS[j]->IncrementState();
896           }
897         }
898         
899         else if( aType == "Deflection1D" ){
900           if(aMethod == "SetDeflection"){
901             SetVariable(_commands[i], aLDS[j],0,1);
902             aLDS[j]->IncrementState();
903           }
904         }
905         // Case for Arithmetic1D and StartEndLength hypothesis
906         else if(aType == "Arithmetic1D" || aType == "StartEndLength") {
907           if(aMethod == "SetLength") {
908             int anArgNb = (_commands[i]->GetArg(2) == "1") ? 0 : 1;
909             SetVariable(_commands[i], aLDS[j],anArgNb,1);
910             aLDS[j]->IncrementState();
911           }
912         }
913       }
914     }
915   }
916 }
917 //================================================================================
918 /*!
919  *  \brief Return result script
920  */
921 //================================================================================
922 TCollection_AsciiString SMESH_NoteBook::GetResultScript() const
923 {
924   TCollection_AsciiString aResult;
925   for ( size_t i = 0; i < _commands.size(); i++ )
926     aResult += _commands[i]->GetString() + "\n";
927   return aResult;
928 }
929
930 //================================================================================
931 /*!
932  *  \brief Return lines of the result script
933  */
934 //================================================================================
935 void SMESH_NoteBook::GetResultLines(std::list< TCollection_AsciiString >& lines) const
936 {
937   for ( size_t i = 0; i < _commands.size(); i++ )
938     lines.push_back( _commands[i]->GetString() );
939 }
940
941 //================================================================================
942 /*!
943  *  \brief Return value of the variable
944  */
945 //================================================================================
946 bool SMESH_NoteBook::GetReal(const TCollection_AsciiString& theVarName, double& theValue)
947 {
948   bool ok = false;
949
950   SALOMEDS::Study_ptr aStudy = SMESH_Gen_i::GetSMESHGen()->getStudyServant();
951   if(aStudy->_is_nil())
952     return ok;
953
954   TCollection_AsciiString aVarName = theVarName;
955   aVarName.RemoveAll('\"');
956
957   if(aVarName.IsEmpty())
958     return ok;
959
960   const char* aName = aVarName.ToCString();
961   if(aStudy->IsVariable(aName) && (aStudy->IsReal(aName) || aStudy->IsInteger(aName))) {
962     theValue = aStudy->GetReal(aName);
963     ok = true;
964   }
965
966   return ok;
967 }