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