Salome HOME
IPAL53870: Dump study script creates an excess sub-mesh
[modules/smesh.git] / src / SMESH_I / SMESH_NoteBook.cxx
1 // Copyright (C) 2007-2016  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 - Convertion 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 <= varIndex && varIndex < vars.size() && !vars[varIndex].empty() )
288         {
289           // replace '$VarIndex$' either by var name of 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::Study_var  aStudy = aGen->GetCurrentStudy();
711         SALOMEDS::SObject_wrap sobj = aStudy->FindObjectID( (*it).first.ToCString() );
712         CORBA::Object_var       obj = aGen->SObjectToObject( sobj );
713         if ( SMESH_Hypothesis_i* h = SMESH::DownCast< SMESH_Hypothesis_i*>( obj ))
714         {
715           TState aCurrentState = aStates->GetCurrectState();
716           int         argIndex = h->getParamIndex( aMethod, aCurrentState.size() );
717           if ( 0 <= argIndex && argIndex < (int)aCurrentState.size() &&
718                !aCurrentState[argIndex].IsEmpty() )
719             aCmd->SetArg( 1, aCurrentState[argIndex] );
720
721           if ( argIndex >= 0 )
722             aStates->IncrementState();
723         }
724       }
725     }
726     else {
727       if(MYDEBUG)
728         cout << "Object not found" << endl;
729     }
730     if(MYDEBUG) {
731       cout<<"Command after: "<< aCmd->GetString()<<endl;
732     }
733   }
734   
735   ProcessLayerDistribution();
736 }
737 //================================================================================
738 /*!
739  * \brief Private method
740  */
741 //================================================================================
742 void SMESH_NoteBook::InitObjectMap()
743 {
744   SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen();
745   if(!aGen)
746     return;
747   
748   SALOMEDS::Study_var aStudy = aGen->GetCurrentStudy();
749   if(aStudy->_is_nil())
750     return;
751   
752   CORBA::String_var compDataType = aGen->ComponentDataType();
753   SALOMEDS::SObject_wrap     aSO = aStudy->FindComponent( compDataType.in() );
754   if(CORBA::is_nil(aSO))
755     return;
756   
757   SALOMEDS::ChildIterator_wrap Itr = aStudy->NewChildIterator(aSO);
758   for( Itr->InitEx(true); Itr->More(); Itr->Next())
759   {
760     SALOMEDS::SObject_wrap aSObject = Itr->Value();
761     SALOMEDS::GenericAttribute_wrap anAttr;
762     if ( aSObject->FindAttribute( anAttr.inout(), "AttributeString"))
763     {
764       SALOMEDS::AttributeString_wrap strAttr = anAttr;
765       CORBA::String_var          aParameters = strAttr->Value();
766       CORBA::String_var                 anID = aSObject->GetID();
767       std::vector< std::string >     allVars = aGen->GetAllParameters( anID.in() );
768       SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters.in());
769       _entry2VarsMap[ TCollection_AsciiString( anID.in() )] = allVars;
770       if(MYDEBUG) {
771         cout<<"Entry : "<< anID<<endl;
772         cout<<"aParameters : "<<aParameters<<endl;
773       }
774       TCollection_AsciiString anObjType;
775       CORBA::Object_var       anObject = SMESH_Gen_i::SObjectToObject(aSObject);
776       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(anObject);
777       SMESH::SMESH_Mesh_var      aMesh = SMESH::SMESH_Mesh::_narrow(anObject);
778       if(!aHyp->_is_nil()) {
779         CORBA::String_var hypName = aHyp->GetName();
780         anObjType = hypName.in();
781       }
782       else if (!aMesh->_is_nil() ) {
783         anObjType = "Mesh";
784       }
785       if(MYDEBUG)
786         cout<<"The object Type : "<<anObjType<<endl;
787       SMESH_ObjectStates *aState = NULL;
788       if(anObjType == "LayerDistribution")
789         aState = new LayerDistributionStates();
790       else
791         aState = new SMESH_ObjectStates(anObjType);
792
793       for ( size_t i = 0; i < aSections->length(); i++ ) {
794         TState aVars;
795         SALOMEDS::ListOfStrings aListOfVars = aSections[i];
796         for ( size_t j = 0; j < aListOfVars.length(); j++)
797         {
798           TCollection_AsciiString aVar(aListOfVars[j].in());
799           if(!aVar.IsEmpty() && aStudy->IsVariable(aVar.ToCString())) {
800             aVar.InsertBefore(1,            SMESH::TVar::Quote() );
801             aVar.InsertAfter(aVar.Length(), SMESH::TVar::Quote() );
802           }
803           aVars.push_back(aVar);
804           if(MYDEBUG) {
805             cout<<"Variable: '"<<aVar<<"'"<<endl;
806           }
807         }
808         aState->AddState(aVars);
809       }
810       if ( aState->GetAllStates().empty() )
811       {
812         delete aState;
813       }
814       else
815       {
816         CORBA::String_var objID = aSObject->GetID();
817         _objectMap.insert( make_pair(TCollection_AsciiString( objID.in() ), aState ));
818       }
819     }
820   }
821 }
822
823 //================================================================================
824 /*!
825  * 
826  */
827 //================================================================================
828 void SMESH_NoteBook::AddCommand(const TCollection_AsciiString& theString)
829 {
830   if(MYDEBUG)
831     cout<<theString<<endl;
832   Handle(_pyCommand) aCommand = new _pyCommand( theString, -1);
833   _commands.push_back(aCommand);
834
835   if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
836     _meshEditors.insert( make_pair( aCommand->GetResultValue(),
837                                     aCommand->GetObject() ) );
838   }
839 }
840
841 //================================================================================
842 /*!
843  * 
844  */
845 //================================================================================
846 void SMESH_NoteBook::ProcessLayerDistribution()
847 {
848   // 1) Find all LayerDistribution states
849   vector<LayerDistributionStates*> aLDS;
850   TVariablesMap::const_iterator it = _objectMap.begin();
851   for(;it != _objectMap.end();it++) {
852     LayerDistributionStates* aLDStates = dynamic_cast<LayerDistributionStates*>(((*it).second));
853     if(aLDStates!=NULL) {
854       aLDS.push_back(aLDStates);
855     }
856   }
857   
858   if(!aLDS.size())
859     return;
860   
861   // 2) Initialize all type of 1D Distribution hypothesis
862   for ( size_t i = 0; i < _commands.size(); i++ ) {
863     for ( size_t j = 0; j < aLDS.size(); j++ ) {
864       TCollection_AsciiString aResultValue = _commands[i]->GetResultValue();
865       if(_commands[i]->GetMethod() == "CreateHypothesis" &&
866          aLDS[j]->HasDistribution(aResultValue)){
867         TCollection_AsciiString aType = _commands[i]->GetArg(1);
868         aType.RemoveAll('\'');
869         aLDS[j]->SetDistributionType(aResultValue,aType);
870       }
871     }
872   }
873   // 3) ... and replase variables ...
874
875   for ( size_t i = 0; i < _commands.size(); i++ ) {
876     for ( size_t j = 0; j < aLDS.size(); j++ ) {
877       TCollection_AsciiString anObject = _commands[i]->GetObject();
878
879       if(aLDS[j]->HasDistribution(anObject)) {
880         TCollection_AsciiString aType = aLDS[j]->GetDistributionType(anObject);
881         TCollection_AsciiString aMethod = _commands[i]->GetMethod();
882         if(aType == "LocalLength") {
883           if(aMethod == "SetLength") {
884             SetVariable(_commands[i], aLDS[j],0,1);
885             aLDS[j]->IncrementState();
886           }
887           else if(aMethod == "SetPrecision") {
888             SetVariable(_commands[i], aLDS[j],1,1);
889             aLDS[j]->IncrementState();
890           }
891         }
892
893         // Case for NumberOfSegments hypothesis
894         else if(aType == "NumberOfSegments"){
895           if(aMethod == "SetNumberOfSegments") {
896             SetVariable(_commands[i], aLDS[j],0,1);
897             if(aLDS[j]->GetCurrectState().size()==1)
898               aLDS[j]->IncrementState();
899           }
900           else if (aMethod == "SetScaleFactor") {
901             SetVariable(_commands[i], aLDS[j],1,1);
902             aLDS[j]->IncrementState();
903           }
904         }
905         
906         else if( aType == "Deflection1D" ){
907           if(aMethod == "SetDeflection"){
908             SetVariable(_commands[i], aLDS[j],0,1);
909             aLDS[j]->IncrementState();
910           }
911         }
912         // Case for Arithmetic1D and StartEndLength hypothesis
913         else if(aType == "Arithmetic1D" || aType == "StartEndLength") {
914           if(aMethod == "SetLength") {
915             int anArgNb = (_commands[i]->GetArg(2) == "1") ? 0 : 1;
916             SetVariable(_commands[i], aLDS[j],anArgNb,1);
917             aLDS[j]->IncrementState();
918           }
919         }
920       }
921     }
922   }
923 }
924 //================================================================================
925 /*!
926  *  \brief Return result script
927  */
928 //================================================================================
929 TCollection_AsciiString SMESH_NoteBook::GetResultScript() const
930 {
931   TCollection_AsciiString aResult;
932   for ( size_t i = 0; i < _commands.size(); i++ )
933     aResult += _commands[i]->GetString() + "\n";
934   return aResult;
935 }
936
937 //================================================================================
938 /*!
939  *  \brief Return lines of the result script
940  */
941 //================================================================================
942 void SMESH_NoteBook::GetResultLines(std::list< TCollection_AsciiString >& lines) const
943 {
944   for ( size_t i = 0; i < _commands.size(); i++ )
945     lines.push_back( _commands[i]->GetString() );
946 }
947
948 //================================================================================
949 /*!
950  *  \brief Return value of the variable
951  */
952 //================================================================================
953 bool SMESH_NoteBook::GetReal(const TCollection_AsciiString& theVarName, double& theValue)
954 {
955   bool ok = false;
956
957   SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen();
958   if(!aGen)
959     return ok;
960
961   SALOMEDS::Study_ptr aStudy = aGen->GetCurrentStudy();
962   if(aStudy->_is_nil())
963     return ok;
964
965   TCollection_AsciiString aVarName = theVarName;
966   aVarName.RemoveAll('\"');
967
968   if(aVarName.IsEmpty())
969     return ok;
970
971   const char* aName = aVarName.ToCString();
972   if(aStudy->IsVariable(aName) && (aStudy->IsReal(aName) || aStudy->IsInteger(aName))) {
973     theValue = aStudy->GetReal(aName);
974     ok = true;
975   }
976
977   return ok;
978 }