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