Salome HOME
Merge from V6_main 01/04/2013
[modules/smesh.git] / src / SMESH_I / SMESH_NoteBook.cxx
1 // Copyright (C) 2007-2013  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.
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                    int 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(_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(int 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     if (int pos = cmdStr.Location( SMESH::TVar::ObjPrefix(), 6, cmdStr.Length() ))
262     {
263       TCollection_AsciiString varHolderEntry =
264         cmdStr.SubString( pos + strlen( SMESH::TVar::ObjPrefix() ), cmdStr.Length() );
265       ent2varVec = _entry2VarsMap.find( varHolderEntry );
266       cmdStr.Split( pos - 1 );
267     }
268     else
269     {
270       ent2varVec = _entry2VarsMap.find( aObject );
271     }
272     // Set variables in cmdStr
273     if ( ent2varVec != _entry2VarsMap.end() && !ent2varVec->second.empty() )
274     {
275       const std::vector< std::string >& vars = ent2varVec->second;
276       int pos = 1, pos2;
277       // look for '$VarIndex$' in cmdStr. TVar::Quote() == '$'
278       while (( pos  = cmdStr.Location( 1, SMESH::TVar::Quote(), pos,   cmdStr.Length() )) &&
279              ( pos2 = cmdStr.Location( 1, SMESH::TVar::Quote(), pos+1, cmdStr.Length() )) )
280       {
281         size_t varIndex = std::string::npos;
282         const char* varIndexPtr = cmdStr.ToCString() + pos;
283         if ( '0' <= *varIndexPtr && *varIndexPtr <= '9' )
284           varIndex = atoi( varIndexPtr );
285         if ( 0 <= varIndex && varIndex < vars.size() && !vars[varIndex].empty() )
286         {
287           // replace '$VarIndex$' either by var name of var value
288           const char var0    = vars[varIndex][0];
289           const bool isValue = (( '0' <= var0 && var0 <= '9' ) || var0 == '-');
290           if ( isValue ) // remove TVar::Quote() as well
291             pos2 += 2; // pos still points to '$'
292           int indexLen = pos2 - pos - 1;
293           int  lenDiff = int( vars[varIndex].size() ) - indexLen;
294           if      ( lenDiff > 0 )
295             cmdStr.InsertBefore( pos2, vars[varIndex].c_str() + vars[varIndex].size() - lenDiff );
296           else if ( lenDiff < 0 )
297             cmdStr.Remove( pos+1, -lenDiff );
298           cmdStr.SetValue( pos+(!isValue), vars[varIndex].c_str() );
299         }
300         pos = pos2 + 1;
301         if ( pos + 2 >= cmdStr.Length() )
302           break;
303       }
304     }
305
306     // OLD APPROACH
307     // Variable names are stored historically in "StringAttribute",
308     // i.e. for each command there is a set of either var names or separated empty places.
309
310     // check if method modifies the object itself
311     TVariablesMap::const_iterator it = _objectMap.find(aObject);
312     if(it == _objectMap.end()) // check if method returns a new object
313       it = _objectMap.find(aResultValue);
314     
315     if(it == _objectMap.end()) { // check if method modifies a mesh using mesh editor
316       TMeshEditorMap::const_iterator meIt = _meshEditors.find(aObject);
317       if(meIt != _meshEditors.end()) {
318         TCollection_AsciiString aMesh = (*meIt).second;
319         it = _objectMap.find(aMesh);
320       }
321     }
322     
323     if(it == _objectMap.end()) { // additional check for pattern mapping
324       if(aMethod.IsEqual("ApplyToMeshFaces") ||
325          aMethod.IsEqual("ApplyToHexahedrons"))
326         it = _objectMap.find(aCmd->GetArg(1));
327     }
328
329     if(it != _objectMap.end()) {
330       if(MYDEBUG)
331         cout << "Found object : " << (*it).first << endl;
332       SMESH_ObjectStates *aStates = (*it).second;
333       // Case for LocalLength hypothesis
334       if(aStates->GetObjectType().IsEqual("LocalLength") && aStates->GetCurrectState().size() >= 2)
335       {
336         if(aMethod.IsEqual("SetLength")) {
337           if(!aStates->GetCurrectState().at(0).IsEmpty() )
338             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
339           aStates->IncrementState();
340         }
341         else if(aMethod.IsEqual("SetPrecision")) {
342           if(!aStates->GetCurrectState().at(1).IsEmpty() )
343             aCmd->SetArg(1,aStates->GetCurrectState().at(1));
344           aStates->IncrementState();
345         }
346       }
347       
348       // Case for SegmentLengthAroundVertex hypothesis
349       else if(aStates->GetObjectType().IsEqual("SegmentLengthAroundVertex")
350               && aStates->GetCurrectState().size() >= 1) {
351         if(aMethod == "SetLength") {
352           if(!aStates->GetCurrectState().at(0).IsEmpty() )
353             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
354           aStates->IncrementState();
355         }
356       }
357
358       // Case for Arithmetic1D and StartEndLength hypothesis
359       else if(aStates->GetObjectType().IsEqual("Arithmetic1D") || 
360               aStates->GetObjectType().IsEqual("StartEndLength")) {
361         if(aMethod == "SetLength" &&
362            aStates->GetCurrectState().size() >= 2) {
363           if(aCmd->GetArg(2) == "1" && !aStates->GetCurrectState().at(0).IsEmpty())
364             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
365           else if(!aStates->GetCurrectState().at(1).IsEmpty())
366             aCmd->SetArg(1,aStates->GetCurrectState().at(1));
367           aStates->IncrementState();
368         }
369       }
370       
371       //Case for Deflection1D hypothesis
372       else if(aStates->GetObjectType().IsEqual("Deflection1D")){
373         if(aMethod == "SetDeflection" && aStates->GetCurrectState().size() >= 1) {
374           if(!aStates->GetCurrectState().at(0).IsEmpty() )
375             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
376           aStates->IncrementState();
377         }
378       }
379       
380       // Case for LayerDistribution hypothesis (not finished yet)
381       else if(aStates->GetObjectType() == "LayerDistribution") {
382         if(aMethod == "SetLayerDistribution"){
383           LayerDistributionStates* aLDStates = (LayerDistributionStates*)(aStates);
384           aLDStates->AddDistribution(aCmd->GetArg(1));
385           if(MYDEBUG)
386             cout<<"Add Distribution :"<<aCmd->GetArg(1)<<endl;
387         }
388       }
389       
390       // Case for MaxElementArea hypothesis
391       else if(aStates->GetObjectType().IsEqual("MaxElementArea")){
392         if(aMethod == "SetMaxElementArea" && aStates->GetCurrectState().size() >= 1) {
393           if(!aStates->GetCurrectState().at(0).IsEmpty() )
394             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
395           aStates->IncrementState();
396         }
397       }
398
399       // Case for MaxElementVolume hypothesis
400       else if(aStates->GetObjectType().IsEqual("MaxElementVolume")){
401         if(aMethod == "SetMaxElementVolume" && aStates->GetCurrectState().size() >= 1) {
402           if(!aStates->GetCurrectState().at(0).IsEmpty() )
403             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
404           aStates->IncrementState();
405         }
406       }
407       // Case for NumberOfLayers hypothesis
408       else if(aStates->GetObjectType().IsEqual("NumberOfLayers")){
409         if(aMethod == "SetNumberOfLayers" && aStates->GetCurrectState().size() >= 1) {
410           if(!aStates->GetCurrectState().at(0).IsEmpty() )
411             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
412           aStates->IncrementState();
413         }
414       }
415
416       // Case for NumberOfSegments hypothesis
417       else if(aStates->GetObjectType().IsEqual("NumberOfSegments")){
418         if(aMethod == "SetNumberOfSegments" && aStates->GetCurrectState().size() >= 1) {
419           if(!aStates->GetCurrectState().at(0).IsEmpty() )
420             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
421           if(aStates->GetCurrectState().size()==1)
422             aStates->IncrementState();
423         }
424         else if (aMethod == "SetScaleFactor" && aStates->GetCurrectState().size() >= 2) {
425           if(!aStates->GetCurrectState().at(1).IsEmpty() )
426             aCmd->SetArg(1,aStates->GetCurrectState().at(1));
427           aStates->IncrementState();
428         }
429       }
430       
431       else if(aStates->GetObjectType().IsEqual("Mesh")) {
432         TState aCurrentState = aStates->GetCurrectState();
433         int aCurrentStateSize = aCurrentState.size();
434         if(aMethod.IsEqual("Translate")                  ||
435            aMethod.IsEqual("TranslateMakeGroups")        ||
436            aMethod.IsEqual("TranslateMakeMesh")          ||
437            aMethod.IsEqual("TranslateObject")            ||
438            aMethod.IsEqual("TranslateObjectMakeGroups")  ||
439            aMethod.IsEqual("TranslateObjectMakeMesh")) {
440           bool isVariableFound = false;
441           int anArgIndex = 0;
442           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
443             if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
444               anArgIndex = i+1;
445               break;
446             }
447           }
448           if(anArgIndex > 0) {
449             if(aCurrentStateSize == 3) { // translation by dx, dy, dz
450               for(int j = 0; j < aCurrentStateSize; j++) {
451                 if(!aCurrentState.at(j).IsEmpty()) {
452                   isVariableFound = true;
453                   aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
454                 }
455               }
456             }
457             else if(aCurrentStateSize == 6) { // translation by x1, x2, y1, y2, z1, z2
458               // TODO: limitation until operations on the variables will be introduced
459               /*
460               isVariableFound = true;
461               for(int j = 0; j < 3; j++) {
462                 TCollection_AsciiString anArg = aCmd->GetArg(anArgIndex+j);
463                 TCollection_AsciiString aValue1 = aCurrentState.at(2*j), aValue2 = aCurrentState.at(2*j+1);
464                 bool aV1 = !aValue1.IsEmpty();
465                 bool aV2 = !aValue2.IsEmpty();
466                 double aValue, aCurrentValue = anArg.IsRealValue() ? anArg.RealValue() : 0;
467                 if(aV1 && !aV2) {
468                   if(!GetReal(aValue1, aValue))
469                     aValue = 0;
470                   aValue2 = TCollection_AsciiString( aValue + aCurrentValue );
471                 }
472                 else if(!aV1 && aV2) {
473                   if(!GetReal(aValue2, aValue))
474                     aValue = 0;
475                   aValue1 = TCollection_AsciiString( aValue - aCurrentValue );
476                 }
477                 else if(!aV1 && !aV2) {
478                   aValue1 = TCollection_AsciiString( 0 );
479                   aValue2 = TCollection_AsciiString( aCurrentValue );
480                 }
481                 aCmd->SetArg(anArgIndex+j, aValue1 + ", " + aValue2 );
482               }
483               */
484             }
485           }
486           if(isVariableFound) {
487             TCollection_AsciiString aDim;
488             if(aCurrentStateSize == 6)
489               aDim = "6";
490             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr"+aDim);
491             aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr");
492           }
493           aStates->IncrementState();
494         }
495         else if(aMethod.IsEqual("Rotate")                  ||
496                 aMethod.IsEqual("RotateMakeGroups")        ||
497                 aMethod.IsEqual("RotateMakeMesh")          ||
498                 aMethod.IsEqual("RotateObject")            ||
499                 aMethod.IsEqual("RotateObjectMakeGroups")  ||
500                 aMethod.IsEqual("RotateObjectMakeMesh")    ||
501                 aMethod.IsEqual("RotationSweep")           ||
502                 aMethod.IsEqual("RotationSweepObject")     ||
503                 aMethod.IsEqual("RotationSweepObject1D")   ||
504                 aMethod.IsEqual("RotationSweepObject2D")   ||
505                 aMethod.IsEqual("RotationSweepMakeGroups") ||
506                 aMethod.IsEqual("RotationSweepObjectMakeGroups") ||
507                 aMethod.IsEqual("RotationSweepObject1DMakeGroups") ||
508                 aMethod.IsEqual("RotationSweepObject2DMakeGroups") ||
509                 aMethod.IsEqual("Mirror")                  ||
510                 aMethod.IsEqual("MirrorMakeMesh")          ||
511                 aMethod.IsEqual("MirrorMakeGroups")        ||
512                 aMethod.IsEqual("MirrorObject")            || 
513                 aMethod.IsEqual("MirrorObjectMakeMesh")    ||
514                 aMethod.IsEqual("MirrorObjectMakeGroups")) {
515           bool isSubstitute = false;
516           int anArgIndex = 0;
517           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
518             if(aCmd->GetArg(i).IsEqual("SMESH.AxisStruct")) {
519               anArgIndex = i+1;
520               break;
521             }
522           }
523           if(anArgIndex > 0) {
524             for(int j = 0; j < aCurrentStateSize; j++) {
525               if(!aCurrentState.at(j).IsEmpty()) {
526                 if(j < 6) // 0-5 - axis struct, 6 - angle (rotation & sweep), 7-8 - nbSteps and tolerance (sweep)
527                   isSubstitute = true;
528                 aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
529               }
530             }
531           }
532           if(isSubstitute)
533             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".AxisStructStr");
534           aStates->IncrementState();
535         }
536         else if(aMethod.IsEqual("AddNode") ||
537                 aMethod.IsEqual("MoveClosestNodeToPoint")) {
538           for(int j = 0; j < aCurrentStateSize; j++) {
539             if(!aCurrentState.at(j).IsEmpty())
540               aCmd->SetArg(j+1, aCurrentState.at(j));
541           }
542           aStates->IncrementState();
543         }
544         else if(aMethod.IsEqual("MoveNode")) {
545           for(int j = 0; j < aCurrentStateSize; j++) {
546             if(!aCurrentState.at(j).IsEmpty())
547               aCmd->SetArg(j+2, aCurrentState.at(j));
548           }
549           aStates->IncrementState();
550         }
551         else if(aMethod.IsEqual("ExtrusionSweep") ||
552                 aMethod.IsEqual("ExtrusionSweepObject") ||
553                 aMethod.IsEqual("ExtrusionSweepObject1D") ||
554                 aMethod.IsEqual("ExtrusionSweepObject2D") ||
555                 aMethod.IsEqual("ExtrusionSweepMakeGroups") ||
556                 aMethod.IsEqual("ExtrusionSweepObjectMakeGroups") ||
557                 aMethod.IsEqual("ExtrusionSweepObject1DMakeGroups") ||
558                 aMethod.IsEqual("ExtrusionSweepObject2DMakeGroups")) {
559           bool isSubstitute = false;
560           int anArgIndex = 0;
561           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
562             if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
563               anArgIndex = i+1;
564               break;
565             }
566           }
567           if(anArgIndex > 0) {
568             for(int j = 0; j < aCurrentStateSize; j++) {
569               if(!aCurrentState.at(j).IsEmpty()) {
570                 if(j < 3) // 0-2 - dir struct, 3 - number of steps
571                   isSubstitute = true;
572                 aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
573               }
574             }
575           }
576           if(isSubstitute) {
577             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr");
578             aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr");
579           }
580           aStates->IncrementState();
581         }
582         else if(aMethod.IsEqual("ExtrusionAlongPath") ||
583                 aMethod.IsEqual("ExtrusionAlongPathObject") ||
584                 aMethod.IsEqual("ExtrusionAlongPathObject1D") ||
585                 aMethod.IsEqual("ExtrusionAlongPathObject2D") ||
586                 aMethod.IsEqual("ExtrusionAlongPathMakeGroups") ||
587                 aMethod.IsEqual("ExtrusionAlongPathObjectMakeGroups") ||
588                 aMethod.IsEqual("ExtrusionAlongPathObject1DMakeGroups") ||
589                 aMethod.IsEqual("ExtrusionAlongPathObject2DMakeGroups") ||
590                 /* workaround for a bug in the command parsing algorithm */
591                 aCmd->GetString().Search("ExtrusionAlongPathMakeGroups") != -1 ||
592                 aCmd->GetString().Search("ExtrusionAlongPathObjectMakeGroups") != -1 ||
593                 aCmd->GetString().Search("ExtrusionAlongPathObject1DMakeGroups") != -1 ||
594                 aCmd->GetString().Search("ExtrusionAlongPathObject2DMakeGroups") != -1 ) {
595           int aNbAngles = aCurrentStateSize-3; // State looks like "Angle1:...:AngleN:X:Y:Z"
596           bool isSubstitute = false;
597           int anArgIndex = 0;
598           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
599             if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
600               anArgIndex = i-1-aNbAngles;
601               break;
602             }
603           }
604           if(anArgIndex > 0) {
605             int j = 0;
606             for(; j < aNbAngles; j++) {
607               if(!aCurrentState.at(j).IsEmpty()) {
608                 aCmd->SetArg(anArgIndex+j-1, aCurrentState.at(j));
609               }
610             }
611             for(; j < aNbAngles+3; j++) {
612               if(!aCurrentState.at(j).IsEmpty()) {
613                 isSubstitute = true;
614                 aCmd->SetArg(anArgIndex+j+2, aCurrentState.at(j));
615               }
616             }
617           }
618           if(isSubstitute)
619             aCmd->SetArg(anArgIndex + aNbAngles + 1,
620                          TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr");
621           aStates->IncrementState();
622         }
623         else if(aMethod.IsEqual("TriToQuad") ||
624                 aMethod.IsEqual("Concatenate") ||
625                 aMethod.IsEqual("ConcatenateWithGroups")) {
626           if(aCurrentStateSize && !aCurrentState.at(0).IsEmpty())
627             aCmd->SetArg(aCmd->GetNbArgs(), aCurrentState.at(0));
628           aStates->IncrementState();
629         }
630         else if(aMethod.IsEqual("Smooth") ||
631                 aMethod.IsEqual("SmoothObject") ||
632                 aMethod.IsEqual("SmoothParametric") ||
633                 aMethod.IsEqual("SmoothParametricObject")) {
634           int anArgIndex = aCmd->GetNbArgs() - 2;
635           for(int j = 0; j < aCurrentStateSize; j++) {
636             if(!aCurrentState.at(j).IsEmpty())
637               aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
638           }
639           aStates->IncrementState();
640         }
641         else if(aMethod.IsEqual("ApplyToMeshFaces") ||
642                 aMethod.IsEqual("ApplyToHexahedrons")) {
643           int anArgIndex = aCmd->GetNbArgs()-1;
644           for(int j = 0; j < aCurrentStateSize; j++)
645             if(!aCurrentState.at(j).IsEmpty())
646               aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
647           aStates->IncrementState();
648         }
649       } // if ( aStates->GetObjectType().IsEqual("Mesh"))
650
651       // Case for NETGEN_Parameters_2D or NETGEN_Parameters_2D hypothesis
652       // else if(aStates->GetObjectType().IsEqual("NETGEN_Parameters_2D") ||
653       //         aStates->GetObjectType().IsEqual("NETGEN_Parameters")){
654       //   if(aMethod == "SetMaxSize" && aStates->GetCurrectState().size() >= 1) {
655       //     if(!aStates->GetCurrectState().at(0).IsEmpty() )
656       //       aCmd->SetArg(1,aStates->GetCurrectState().at(0));
657       //     aStates->IncrementState();
658       //   }
659       //   else if(aMethod == "SetGrowthRate" && aStates->GetCurrectState().size() >= 2) {
660       //     if(!aStates->GetCurrectState().at(1).IsEmpty() )
661       //       aCmd->SetArg(1,aStates->GetCurrectState().at(1));
662       //     aStates->IncrementState();
663       //   }
664       //   else if(aMethod == "SetNbSegPerEdge" && aStates->GetCurrectState().size() >= 3) {
665       //     if(!aStates->GetCurrectState().at(2).IsEmpty() )
666       //       aCmd->SetArg(1,aStates->GetCurrectState().at(2));
667       //     aStates->IncrementState();
668       //   }
669       //   else if(aMethod == "SetNbSegPerRadius" && aStates->GetCurrectState().size() >= 4) {
670       //     if(!aStates->GetCurrectState().at(3).IsEmpty() )
671       //       aCmd->SetArg(1,aStates->GetCurrectState().at(3));
672       //     aStates->IncrementState();
673       //   }
674       // }
675
676       // // Case for NETGEN_SimpleParameters_3D or NETGEN_SimpleParameters_2D hypothesis
677       // else if(aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_3D") ||
678       //         aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_2D")) {
679
680       //   if((aMethod == "SetNumberOfSegments" || aMethod == "SetLocalLength") && 
681       //      aStates->GetCurrectState().size() >= 1) {
682       //     if(!aStates->GetCurrectState().at(0).IsEmpty() )
683       //       aCmd->SetArg(1,aStates->GetCurrectState().at(0));
684       //     aStates->IncrementState();
685       //   }
686       //   else if(aMethod == "SetMaxElementArea" && aStates->GetCurrectState().size() >= 2) {
687       //     if(!aStates->GetCurrectState().at(1).IsEmpty() )
688       //       aCmd->SetArg(1,aStates->GetCurrectState().at(1));
689       //     aStates->IncrementState();
690       //   }
691       //   else if(aMethod == "SetMaxElementVolume" && aStates->GetCurrectState().size() >= 3) {
692       //     if(!aStates->GetCurrectState().at(2).IsEmpty() )
693       //       aCmd->SetArg(1,aStates->GetCurrectState().at(2));
694       //     aStates->IncrementState();
695       //   }
696       //   else if(aMethod == "LengthFromEdges" || aMethod == "LengthFromFaces"){
697       //     aStates->IncrementState();
698       //   }
699       // }
700
701       else
702       {
703         // treat Netgen hypotheses;
704         // this (and above) code can work wrong since nb of states can differ from nb of
705         // dumped calls due to the fix of
706         // issue 0021364:: Dump of netgen parameters has duplicate lines
707         SMESH_Gen_i *          aGen = SMESH_Gen_i::GetSMESHGen();
708         SALOMEDS::Study_var  aStudy = aGen->GetCurrentStudy();
709         SALOMEDS::SObject_wrap sobj = aStudy->FindObjectID( (*it).first.ToCString() );
710         CORBA::Object_var       obj = aGen->SObjectToObject( sobj );
711         if ( SMESH_Hypothesis_i* h = SMESH::DownCast< SMESH_Hypothesis_i*>( obj ))
712         {
713           TState aCurrentState = aStates->GetCurrectState();
714           int         argIndex = h->getParamIndex( aMethod, aCurrentState.size() );
715           if ( 0 <= argIndex && argIndex < aCurrentState.size() &&
716                !aCurrentState[argIndex].IsEmpty() )
717             aCmd->SetArg( 1, aCurrentState[argIndex] );
718
719           if ( argIndex >= 0 )
720             aStates->IncrementState();
721         }
722       }
723     }
724     else {
725       if(MYDEBUG)
726         cout << "Object not found" << endl;
727     }
728     if(MYDEBUG) {
729       cout<<"Command after: "<< aCmd->GetString()<<endl;
730     }
731   }
732   
733   ProcessLayerDistribution();
734 }
735 //================================================================================
736 /*!
737  * \brief Private method
738  */
739 //================================================================================
740 void SMESH_NoteBook::InitObjectMap()
741 {
742   SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen();
743   if(!aGen)
744     return;
745   
746   SALOMEDS::Study_var aStudy = aGen->GetCurrentStudy();
747   if(aStudy->_is_nil())
748     return;
749   
750   CORBA::String_var compDataType = aGen->ComponentDataType();
751   SALOMEDS::SObject_wrap     aSO = aStudy->FindComponent( compDataType.in() );
752   if(CORBA::is_nil(aSO))
753     return;
754   
755   SALOMEDS::ChildIterator_wrap Itr = aStudy->NewChildIterator(aSO);
756   for( Itr->InitEx(true); Itr->More(); Itr->Next())
757   {
758     SALOMEDS::SObject_wrap aSObject = Itr->Value();
759     SALOMEDS::GenericAttribute_wrap anAttr;
760     if ( aSObject->FindAttribute( anAttr.inout(), "AttributeString"))
761     {
762       SALOMEDS::AttributeString_wrap strAttr = anAttr;
763       CORBA::String_var          aParameters = strAttr->Value();
764       CORBA::String_var                 anID = aSObject->GetID();
765       std::vector< std::string >     allVars = aGen->GetAllParameters( anID.in() );
766       SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters.in());
767       _entry2VarsMap[ TCollection_AsciiString( anID.in() )] = allVars;
768       if(MYDEBUG) {
769         cout<<"Entry : "<< anID<<endl;
770         cout<<"aParameters : "<<aParameters<<endl;
771       }
772       TCollection_AsciiString anObjType;
773       CORBA::Object_var       anObject = SMESH_Gen_i::SObjectToObject(aSObject);
774       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(anObject);
775       SMESH::SMESH_Mesh_var      aMesh = SMESH::SMESH_Mesh::_narrow(anObject);
776       if(!aHyp->_is_nil()) {
777         CORBA::String_var hypName = aHyp->GetName();
778         anObjType = hypName.in();
779       }
780       else if (!aMesh->_is_nil() ) {
781         anObjType = "Mesh";
782       }
783       if(MYDEBUG)
784         cout<<"The object Type : "<<anObjType<<endl;
785       SMESH_ObjectStates *aState = NULL;
786       if(anObjType == "LayerDistribution")
787         aState = new LayerDistributionStates();
788       else
789         aState = new SMESH_ObjectStates(anObjType);
790
791       for(int i = 0; i < aSections->length(); i++) {
792         TState aVars;
793         SALOMEDS::ListOfStrings aListOfVars = aSections[i];
794         for ( int j = 0; j<aListOfVars.length(); j++)
795         {
796           TCollection_AsciiString aVar(aListOfVars[j].in());
797           if(!aVar.IsEmpty() && aStudy->IsVariable(aVar.ToCString())) {
798             aVar.InsertBefore(1,            SMESH::TVar::Quote() );
799             aVar.InsertAfter(aVar.Length(), SMESH::TVar::Quote() );
800           }
801           aVars.push_back(aVar);
802           if(MYDEBUG) {
803             cout<<"Variable: '"<<aVar<<"'"<<endl;
804           }
805         }
806         aState->AddState(aVars);
807       }
808       if ( aState->GetAllStates().empty() )
809       {
810         delete aState;
811       }
812       else
813       {
814         CORBA::String_var objID = aSObject->GetID();
815         _objectMap.insert( make_pair(TCollection_AsciiString( objID.in() ), aState ));
816       }
817     }
818   }
819 }
820
821 //================================================================================
822 /*!
823  * 
824  */
825 //================================================================================
826 void SMESH_NoteBook::AddCommand(const TCollection_AsciiString& theString)
827 {
828   if(MYDEBUG)
829     cout<<theString<<endl;
830   Handle(_pyCommand) aCommand = new _pyCommand( theString, -1);
831   _commands.push_back(aCommand);
832
833   if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
834     _meshEditors.insert( make_pair( aCommand->GetResultValue(),
835                                     aCommand->GetObject() ) );
836   }
837 }
838
839 //================================================================================
840 /*!
841  * 
842  */
843 //================================================================================
844 void SMESH_NoteBook::ProcessLayerDistribution()
845 {
846   // 1) Find all LayerDistribution states
847   vector<LayerDistributionStates*> aLDS;
848   TVariablesMap::const_iterator it = _objectMap.begin();
849   for(;it != _objectMap.end();it++) {
850     LayerDistributionStates* aLDStates = dynamic_cast<LayerDistributionStates*>(((*it).second));
851     if(aLDStates!=NULL) {
852       aLDS.push_back(aLDStates);
853     }
854   }
855   
856   if(!aLDS.size())
857     return;
858   
859   // 2) Initialize all type of 1D Distribution hypothesis
860   for(int i=0;i<_commands.size();i++){
861     for(int j =0;j < aLDS.size();j++){
862       TCollection_AsciiString aResultValue = _commands[i]->GetResultValue();
863       if(_commands[i]->GetMethod() == "CreateHypothesis" &&
864          aLDS[j]->HasDistribution(aResultValue)){
865         TCollection_AsciiString aType = _commands[i]->GetArg(1);
866         aType.RemoveAll('\'');
867         aLDS[j]->SetDistributionType(aResultValue,aType);
868       }
869     }
870   }
871   // 3) ... and replase variables ...
872
873   for(int i=0;i<_commands.size();i++){
874     for(int j =0;j < aLDS.size();j++){
875       TCollection_AsciiString anObject = _commands[i]->GetObject();
876
877       if(aLDS[j]->HasDistribution(anObject)) {
878         TCollection_AsciiString aType = aLDS[j]->GetDistributionType(anObject);
879         TCollection_AsciiString aMethod = _commands[i]->GetMethod();
880         if(aType == "LocalLength") {
881           if(aMethod == "SetLength") {
882             SetVariable(_commands[i], aLDS[j],0,1);
883             aLDS[j]->IncrementState();
884           }
885           else if(aMethod == "SetPrecision") {
886             SetVariable(_commands[i], aLDS[j],1,1);
887             aLDS[j]->IncrementState();
888           }
889         }
890
891         // Case for NumberOfSegments hypothesis
892         else if(aType == "NumberOfSegments"){
893           if(aMethod == "SetNumberOfSegments") {
894             SetVariable(_commands[i], aLDS[j],0,1);
895             if(aLDS[j]->GetCurrectState().size()==1)
896               aLDS[j]->IncrementState();
897           }
898           else if (aMethod == "SetScaleFactor") {
899             SetVariable(_commands[i], aLDS[j],1,1);
900             aLDS[j]->IncrementState();
901           }
902         }
903         
904         else if( aType == "Deflection1D" ){
905           if(aMethod == "SetDeflection"){
906             SetVariable(_commands[i], aLDS[j],0,1);
907             aLDS[j]->IncrementState();
908           }
909         }
910         // Case for Arithmetic1D and StartEndLength hypothesis
911         else if(aType == "Arithmetic1D" || aType == "StartEndLength") {
912           if(aMethod == "SetLength") {
913             int anArgNb = (_commands[i]->GetArg(2) == "1") ? 0 : 1;
914             SetVariable(_commands[i], aLDS[j],anArgNb,1);
915             aLDS[j]->IncrementState();
916           }
917         }
918       }
919     }
920   }
921 }
922 //================================================================================
923 /*!
924  *  \brief Return result script
925  */
926 //================================================================================
927 TCollection_AsciiString SMESH_NoteBook::GetResultScript() const
928 {
929   TCollection_AsciiString aResult;
930   for(int i=0;i<_commands.size();i++)
931     aResult+=_commands[i]->GetString()+"\n";
932   return aResult;
933 }
934
935 //================================================================================
936 /*!
937  *  \brief Return value of the variable
938  */
939 //================================================================================
940 bool SMESH_NoteBook::GetReal(const TCollection_AsciiString& theVarName, double& theValue)
941 {
942   bool ok = false;
943
944   SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen();
945   if(!aGen)
946     return ok;
947
948   SALOMEDS::Study_ptr aStudy = aGen->GetCurrentStudy();
949   if(aStudy->_is_nil())
950     return ok;
951
952   TCollection_AsciiString aVarName = theVarName;
953   aVarName.RemoveAll('\"');
954
955   if(aVarName.IsEmpty())
956     return ok;
957
958   const char* aName = aVarName.ToCString();
959   if(aStudy->IsVariable(aName) && (aStudy->IsReal(aName) || aStudy->IsInteger(aName))) {
960     theValue = aStudy->GetReal(aName);
961     ok = true;
962   }
963
964   return ok;
965 }
966