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