Salome HOME
Implementation notebook in the SMESH module.
[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 = 1;
37 #else
38 static int MYDEBUG = 1;
39 #endif
40
41 using namespace std;
42
43
44
45 //================================================================================
46 /*!
47  * \brief Constructor
48  */
49 //================================================================================
50 ObjectStates::ObjectStates(TCollection_AsciiString theType)
51 {
52   _type = theType;
53   _dumpstate = 0;
54 }
55
56 //================================================================================
57 /*!
58  * \brief Destructor
59  */
60 //================================================================================
61 ObjectStates::~ObjectStates()
62 {
63 }
64
65 //================================================================================
66 /*!
67  * \brief Add new object state 
68  * \param theState - Object state (vector of notebook variable)
69  */
70 //================================================================================
71 void ObjectStates::AddState(const TState &theState)
72 {
73   _states.push_back(theState);
74 }
75
76 //================================================================================
77 /*!
78  * \brief Return current object state
79  * \\retval state - Object state (vector of notebook variable)
80  */
81 //================================================================================
82 TState ObjectStates::GetCurrectState() const
83 {
84   return _states[_dumpstate];
85 }
86
87
88 //================================================================================
89 /*!
90  *
91  */
92 //================================================================================
93 TAllStates ObjectStates::GetAllStates() const
94 {
95   return _states;
96 }
97
98 //================================================================================
99 /*!
100  *
101  */
102 //================================================================================
103 void ObjectStates::IncrementState()
104 {
105   _dumpstate++;
106 }
107
108 //================================================================================
109 /*!
110  *
111  */
112 //================================================================================
113 TCollection_AsciiString ObjectStates::GetObjectType() const{
114   return _type;
115 }
116
117
118 //================================================================================
119 /*!
120  * \brief Constructor
121  */
122 //================================================================================
123 LayerDistributionStates::LayerDistributionStates():
124   ObjectStates("LayerDistribution")
125 {
126 }
127 //================================================================================
128 /*!
129  * \brief Destructor
130  */
131 //================================================================================
132 LayerDistributionStates::~LayerDistributionStates()
133 {
134 }
135
136
137 //================================================================================
138 /*!
139  * \brief AddDistribution
140  */
141 //================================================================================
142 void LayerDistributionStates::AddDistribution(const TCollection_AsciiString& theDistribution)
143 {
144   _distributions.insert(pair<TCollection_AsciiString,TCollection_AsciiString>(theDistribution,""));
145 }
146
147 //================================================================================
148 /*!
149  * \brief HasDistribution
150  */
151 //================================================================================
152 bool LayerDistributionStates::HasDistribution(const TCollection_AsciiString& theDistribution) const
153 {
154   return _distributions.find(theDistribution) != _distributions.end();
155 }
156
157 //================================================================================
158 /*!
159  * \brief SetDistributionType
160  */
161 //================================================================================
162 bool LayerDistributionStates::SetDistributionType(const TCollection_AsciiString& theDistribution,
163                                                   const TCollection_AsciiString& theType)
164 {
165   TDistributionMap::iterator it = _distributions.find(theDistribution);
166   if(it == _distributions.end())
167     return false;
168   (*it).second = theType;
169   return true;
170 }
171
172 //================================================================================
173 /*!
174  * \brief GetDistributionType
175  */
176 //================================================================================
177 TCollection_AsciiString LayerDistributionStates::
178 GetDistributionType(const TCollection_AsciiString& theDistribution) const
179 {
180   TDistributionMap::const_iterator it = _distributions.find(theDistribution);
181   return (it == _distributions.end()) ? TCollection_AsciiString() : (*it).second;
182 }
183
184 //================================================================================
185 /*!
186  * \brief Constructor
187  */
188 //================================================================================
189 SMESH_NoteBook::SMESH_NoteBook()
190 {
191   InitObjectMap();
192 }
193
194 //================================================================================
195 /*!
196  * \brief Destructor
197  */
198 //================================================================================
199 SMESH_NoteBook::~SMESH_NoteBook()
200 {
201   TVariablesMap::const_iterator it = _objectMap.begin();
202   for(;it!=_objectMap.end();it++) {
203     if((*it).second)
204       delete (*it).second;
205   }
206 }
207
208 //================================================================================
209 /*!
210  * \brief Replace parameters of the functions on the Salome NoteBook Variables
211  * \param theString - Input string
212  * \retval TCollection_AsciiString - Convertion result
213  */
214 //================================================================================
215 void SMESH_NoteBook::ReplaceVariables()
216 {
217
218   for(int i=0;i<_commands.size();i++) {
219     Handle(_pyCommand) aCmd = _commands[i];
220     TCollection_AsciiString aMethod = aCmd->GetMethod();
221     TCollection_AsciiString aObject = aCmd->GetObject();
222     TCollection_AsciiString aResultValue = aCmd->GetResultValue();
223     if(MYDEBUG) {
224       cout<<"Command before : "<< aCmd->GetString()<<endl;
225       cout<<"Method : "<< aMethod<<endl;
226       cout<<"Object : "<< aObject<<endl;
227       cout<<"Result : "<< aResultValue<<endl;
228     }
229     
230     // check if method modifies the object itself
231     TVariablesMap::const_iterator it = _objectMap.find(aObject);
232     if(it == _objectMap.end()) // check if method returns a new object
233       it = _objectMap.find(aResultValue);
234     
235     if(it == _objectMap.end()) { // check if method modifies a mesh using mesh editor
236       TMeshEditorMap::const_iterator meIt = myMeshEditors.find(aObject);
237       if(meIt != myMeshEditors.end()) {
238         TCollection_AsciiString aMesh = (*meIt).second;
239         it = _objectMap.find(aMesh);
240       }
241     }
242     
243     if(it != _objectMap.end() && !aMethod.IsEmpty()) {
244       ObjectStates *aStates = (*it).second;
245       // Case for LocalLength hypothesis
246       if(aStates->GetObjectType().IsEqual("LocalLength")) {
247         if(aMethod.IsEqual("SetLength")) {
248           if(!aStates->GetCurrectState().at(0).IsEmpty() )
249             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
250           aStates->IncrementState();
251         }
252         else if(aMethod.IsEqual("SetPrecision")) {
253           if(!aStates->GetCurrectState().at(1).IsEmpty() )
254             aCmd->SetArg(1,aStates->GetCurrectState().at(1));
255           aStates->IncrementState();
256         }
257       }
258       
259       // Case for SegmentLengthAroundVertex hypothesis
260       else if(aStates->GetObjectType().IsEqual("SegmentLengthAroundVertex")) {
261         if(aMethod == "SetLength") {
262           if(!aStates->GetCurrectState().at(0).IsEmpty() )
263             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
264           aStates->IncrementState();
265         }
266       }
267       // Case for LayerDistribution hypothesis (not finished yet)
268       else if(aStates->GetObjectType() == "LayerDistribution") {
269         if(aMethod == "SetLayerDistribution"){
270           LayerDistributionStates* aLDStates = (LayerDistributionStates*)(aStates);
271           aLDStates->AddDistribution(aCmd->GetArg(1));
272         }
273       }
274
275       else if(aStates->GetObjectType().IsEqual("Mesh")) {
276         if(aMethod.IsEqual("Translate") ||
277            aMethod.IsEqual("TranslateMakeGroups") ||
278            aMethod.IsEqual("TranslateMakeMesh")) {
279           bool isVariableFound = false;
280           int anArgIndex = 0;
281           for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
282             if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
283               anArgIndex = i+1;
284               break;
285             }
286           }
287           if(anArgIndex > 0) {
288             for(int j = 0; j <= 2; j++) {
289               if(!aStates->GetCurrectState().at(j).IsEmpty()) {
290                 isVariableFound = true;
291                 aCmd->SetArg(anArgIndex+j, aStates->GetCurrectState().at(j));
292               }
293             }
294           }
295           if(isVariableFound) {
296             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr");
297             aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr");
298           }
299           aStates->IncrementState();
300         }
301       }
302     }
303     if(MYDEBUG) {
304       cout<<"Command after: "<< aCmd->GetString()<<endl;
305     }
306   }
307   //  ProcessLayerDistribution();
308 }
309 //================================================================================
310 /*!
311  * \brief Private method
312  */
313 //================================================================================
314 void SMESH_NoteBook::InitObjectMap()
315 {
316   SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen();
317   if(!aGen)
318     return;
319   
320   SALOMEDS::Study_ptr aStudy = aGen->GetCurrentStudy();
321   if(aStudy->_is_nil())
322     return;
323   
324   SALOMEDS::SObject_var aSO = aStudy->FindComponent(aGen->ComponentDataType());
325   if(CORBA::is_nil(aSO))
326     return;
327   
328   SALOMEDS::ChildIterator_var Itr = aStudy->NewChildIterator(aSO);
329   char* aParameters;
330   for(Itr->InitEx(true); Itr->More(); Itr->Next()) {
331     SALOMEDS::SObject_var aSObject = Itr->Value();
332     SALOMEDS::GenericAttribute_var anAttr;
333     if ( aSObject->FindAttribute(anAttr, "AttributeString")) {
334       aParameters = SALOMEDS::AttributeString::_narrow(anAttr)->Value();
335       SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
336       if(MYDEBUG) {
337         cout<<"Entry : "<< aSObject->GetID()<<endl;
338         cout<<"aParameters : "<<aParameters<<endl;
339       }      
340       TCollection_AsciiString anObjType;
341       CORBA::Object_var anObject = SMESH_Gen_i::SObjectToObject(aSObject);
342       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(anObject);
343       if(!aHyp->_is_nil()) {
344         anObjType = TCollection_AsciiString(aHyp->GetName());
345       }
346       else if(SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObject)) {
347         anObjType = TCollection_AsciiString("Mesh");
348       }
349       if(MYDEBUG)
350         cout<<"The object Type : "<<anObjType<<endl;
351       ObjectStates *aState = NULL;
352       if(anObjType == "LayerDistribution")
353         aState = new LayerDistributionStates();
354       else
355         aState = new  ObjectStates(anObjType);
356       
357       for(int i = 0; i < aSections->length(); i++) {
358         TState aVars;
359         SALOMEDS::ListOfStrings aListOfVars = aSections[i];
360         for(int j = 0;j<aListOfVars.length();j++) {
361           TCollection_AsciiString aVar(aListOfVars[j].in());
362           if(!aVar.IsEmpty() && aStudy->IsVariable(aVar.ToCString())) {
363             aVar.InsertBefore(1,"\"");
364             aVar.InsertAfter(aVar.Length(),"\"");
365           }
366           aVars.push_back(aVar);
367           if(MYDEBUG) {
368             cout<<"Variable: '"<<aVar<<"'"<<endl;
369           }
370         }
371         aState->AddState(aVars);
372       }
373       _objectMap.insert(pair<TCollection_AsciiString,ObjectStates*>(TCollection_AsciiString(aSObject->GetID()),aState));
374     }
375   }
376 }
377
378 //================================================================================
379 /*!
380  * 
381  */
382 //================================================================================
383 void SMESH_NoteBook::AddCommand(const TCollection_AsciiString& theString)
384 {
385   Handle(_pyCommand) aCommand = new _pyCommand( theString, -1);
386   _commands.push_back(aCommand);
387
388   if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
389     myMeshEditors.insert( make_pair( aCommand->GetResultValue(),
390                                      aCommand->GetObject() ) );
391   }
392 }
393
394 //================================================================================
395 /*!
396  * 
397  */
398 //================================================================================
399 void SMESH_NoteBook::ProcessLayerDistribution()
400 {
401   // 1) Find all LayerDistribution states
402   vector<LayerDistributionStates*> aLDS;
403   TVariablesMap::const_iterator it = _objectMap.begin();
404   for(;it != _objectMap.end();it++)
405     if(LayerDistributionStates* aLDStates = (LayerDistributionStates*)((*it).second)) {
406       aLDS.push_back(aLDStates);
407     }
408   
409   // 2) Initialize all type of 1D Distribution hypothesis
410   for(int i=0;i<_commands.size();i++){
411     for(int j =0;j < aLDS.size();j++){
412       TCollection_AsciiString aResultValue = _commands[i]->GetResultValue();
413       if(_commands[i]->GetMethod() == "CreateHypothesis" &&
414          aLDS[j]->HasDistribution(aResultValue)){
415         TCollection_AsciiString aType = _commands[i]->GetArg(1);
416         aType.RemoveAll('\'');
417         aLDS[j]->SetDistributionType(aResultValue,aType);
418       }
419     }
420   }
421   // 3) ... and replase variables ...
422
423   for(int i=0;i<_commands.size();i++){
424     for(int j =0;j < aLDS.size();j++){
425       TCollection_AsciiString anObject = _commands[i]->GetObject();
426
427       if(aLDS[j]->HasDistribution(anObject)) {
428         TCollection_AsciiString aType = aLDS[j]->GetDistributionType(anObject);
429         TCollection_AsciiString aMethod = _commands[i]->GetMethod();
430         if(aType == "LocalLength") {
431           if(aMethod == "SetLength") {
432             if(!aLDS[j]->GetCurrectState().at(0).IsEmpty() )
433               _commands[i]->SetArg(1,aLDS[j]->GetCurrectState().at(0));
434             aLDS[j]->IncrementState();
435           }
436           else if(aMethod == "SetPrecision") {
437             if(!aLDS[j]->GetCurrectState().at(1).IsEmpty() )
438               _commands[i]->SetArg(1,aLDS[j]->GetCurrectState().at(1));
439             aLDS[j]->IncrementState();
440           }
441         }
442       }
443     }
444   }
445 }
446 //================================================================================
447 /*!
448  *  \brief Return result script
449  */
450 //================================================================================
451 TCollection_AsciiString SMESH_NoteBook::GetResultScript() const
452 {
453   TCollection_AsciiString aResult;
454   for(int i=0;i<_commands.size();i++)
455     aResult+=_commands[i]->GetString()+"\n";
456   return aResult;
457 }