]> SALOME platform Git repositories - modules/med.git/blob - src/MEDCalc/cmp/MEDPresentation.cxx
Salome HOME
[MEDCalc] Simplifying IDL enum names.
[modules/med.git] / src / MEDCalc / cmp / MEDPresentation.cxx
1 // Copyright (C) 2011-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Authors: A Bruneton (CEA), C Aguerre (EdF)
20
21 #include "MEDPyLockWrapper.hxx"
22 #include "MEDFactoryClient.hxx"
23 #include "MEDPresentation.hxx"
24 #include "MEDPresentationException.hxx"
25 #include "MEDCouplingRefCountObject.hxx"
26 #include <SALOME_KernelServices.hxx>
27 #undef LOG
28 #include <Basics_Utils.hxx>
29
30 #include <sstream>
31
32 const std::string MEDPresentation::PROP_NAME  = "name";
33 const std::string MEDPresentation::PROP_NB_COMPONENTS = "nbComponents";
34 const std::string MEDPresentation::PROP_SELECTED_COMPONENT = "selectedComponent";
35 const std::string MEDPresentation::PROP_COMPONENT = "component_";
36 const std::string MEDPresentation::PROP_COLOR_MAP = "colorMap";
37 const std::string MEDPresentation::PROP_SCALAR_BAR_RANGE = "scalarBarRange";
38
39 MEDPresentation::MEDPresentation(MEDPresentation::TypeID fieldHandlerId, const std::string& name,
40                                  const MEDCALC::ViewModeType viewMode,
41                                  const MEDCALC::ColorMapType colorMap,
42                                  const MEDCALC::ScalarBarRangeType sbRange)
43     : _fieldHandlerId(fieldHandlerId), _propertiesStr(),
44       //_pipeline(0), _display(0)
45       _selectedComponentIndex(-1),
46       _viewMode(viewMode),
47       _colorMap(colorMap),
48       _sbRange(sbRange),
49       _renderViewPyId(-1),  // will be set by getRenderViewCommand()
50       _globalDict(0)
51 {
52   MEDCALC::MEDDataManager_ptr dataManager(MEDFactoryClient::getDataManager());
53   MEDCALC::FieldHandler* fieldHandler = dataManager->getFieldHandler(fieldHandlerId);
54   MEDCALC::MeshHandler* meshHandler = dataManager->getMesh(fieldHandler->meshid);
55   MEDCALC::DatasourceHandler* dataSHandler = dataManager->getDatasourceHandlerFromID(meshHandler->sourceid);
56
57   _fileName = dataSHandler->uri;
58   _fieldName = fieldHandler->fieldname;
59   _fieldType = getFieldTypeString((MEDCoupling::TypeOfField) fieldHandler->type);
60
61   if (_fileName.substr(0, 7) != std::string("file://")) {
62     const char* msg = "MEDPresentation(): Data source is not a file! Can not proceed.";
63     STDLOG(msg);
64     throw MEDPresentationException(msg);
65   }
66   _fileName = _fileName.substr(7, _fileName.size());
67
68   setStringProperty(MEDPresentation::PROP_NAME, name);
69
70   setIntProperty(MEDPresentation::PROP_NB_COMPONENTS, 0);
71   setIntProperty(MEDPresentation::PROP_SELECTED_COMPONENT, 0);
72
73   setIntProperty(MEDPresentation::PROP_COLOR_MAP, static_cast<int>(colorMap));
74   setIntProperty(MEDPresentation::PROP_SCALAR_BAR_RANGE, static_cast<int>(sbRange));
75
76   // Python variables:
77   int id = GeneratePythonId();
78   std::ostringstream oss_o, oss_d, oss_l, oss_s;
79   oss_o << "__obj" << id;
80   oss_s << "__srcObj" << id;
81   oss_d << "__disp" << id;
82   oss_l << "__lut" << id;
83   _objVar = oss_o.str();
84   _srcObjVar = oss_s.str();
85   _dispVar = oss_d.str();
86   _lutVar = oss_l.str();
87 }
88
89 MEDPresentation::~MEDPresentation()
90 {
91   STDLOG("~MEDPresentation(): clear display");
92   {
93     MEDPyLockWrapper lock;
94     std::ostringstream oss_v, oss;
95     oss_v << "__view" << _renderViewPyId;
96     oss << "pvs.Hide(" << _objVar <<  ", view=" << oss_v.str() << ");";
97     oss << "pvs.Render();";
98
99     PyRun_SimpleString(oss.str().c_str());
100   }
101 }
102
103 void
104 MEDPresentation::generatePipeline()
105 {
106   // Might be more complicated in the future:
107
108   this->internalGeneratePipeline();
109 }
110
111 //void
112 //MEDPresentation::pushPyObjects(PyObjectId obj, PyObjectId disp)
113 //{
114 //  _pipeline.push_back(obj);
115 //  _display.push_back(disp);
116 //}
117
118 void
119 MEDPresentation::pushAndExecPyLine(const std::string & lin)
120 {
121   execPyLine(lin);
122   _pythonCmds.push_back(lin);
123 }
124
125 void
126 MEDPresentation::execPyLine(const std::string & lin)
127 {
128   MEDPyLockWrapper lock;
129   STDLOG("@@@@ MEDPresentation::execPyLine() about to exec >> " << lin);
130   if(PyRun_SimpleString(lin.c_str()))
131     {
132       std::ostringstream oss;
133       oss << "MEDPresentation::execPyLine(): following Python command failed!\n";
134       oss << ">> " << lin;
135       STDLOG(oss.str());
136       throw KERNEL::createSalomeException(oss.str().c_str());
137     }
138 }
139
140 void
141 MEDPresentation::setStringProperty(const std::string& propName, const std::string& propValue)
142 {
143   _propertiesStr[propName] = propValue;
144 }
145
146 const std::string
147 MEDPresentation::getStringProperty(const std::string& propName) const
148 {
149   std::map<std::string, std::string>::const_iterator it = _propertiesStr.find(propName);
150   if (it != _propertiesStr.end()) {
151       return (*it).second;
152   }
153   else {
154       STDLOG("MEDPresentation::getStringProperty(): no property named " + propName);
155       throw MEDPresentationException("MEDPresentation::getStringProperty(): no property named " + propName);
156   }
157 }
158
159 void
160 MEDPresentation::setIntProperty(const std::string& propName, const int propValue)
161 {
162   _propertiesInt[propName] = propValue;
163 }
164
165 int
166 MEDPresentation::getIntProperty(const std::string& propName) const
167 {
168   std::map<std::string, int>::const_iterator it = _propertiesInt.find(propName);
169   if (it != _propertiesInt.end()) {
170       return (*it).second;
171   }
172   else {
173       STDLOG("MEDPresentation::getIntProperty(): no property named " + propName);
174       throw MEDPresentationException("MEDPresentation::getIntProperty(): no property named " + propName);
175   }
176 }
177
178  void
179  MEDPresentation::dumpIntProperties() const
180  {
181    std::map<std::string, int>::const_iterator it = _propertiesInt.begin();
182    STDLOG("@@@ Dumping INT properties");
183    for(; it != _propertiesInt.end(); ++it)
184      {
185        std::ostringstream oss;
186        oss << (*it).first << "  ->   " << (*it).second;
187        STDLOG(oss.str());
188      }
189  }
190
191  void
192  MEDPresentation::dumpStringProperties() const
193  {
194    std::map<std::string, std::string>::const_iterator it = _propertiesStr.begin();
195    STDLOG("@@@ Dumping STR properties");
196    for(; it != _propertiesStr.end(); ++it)
197      {
198        std::ostringstream oss;
199        oss << (*it).first << "  ->   " << (*it).second;
200        STDLOG(oss.str());
201      }
202  }
203
204  void
205  MEDPresentation::internalGeneratePipeline()
206  {
207    MEDPyLockWrapper lock;
208    pushAndExecPyLine( "import pvsimple as pvs;");
209  }
210
211
212 PyObject*
213 MEDPresentation::getPythonObjectFromMain(const char* python_var) const
214 {
215   if (! _globalDict)
216     {
217       // All the calls below returns *borrowed* references
218       PyObject* main_module = PyImport_AddModule((char*)"__main__");
219       _globalDict = PyModule_GetDict(main_module);
220     }
221   return PyDict_GetItemString(_globalDict, python_var);
222 }
223
224 std::string
225 MEDPresentation::getFieldTypeString(MEDCoupling::TypeOfField fieldType) const
226 {
227   switch(fieldType)
228   {
229     case MEDCoupling::ON_CELLS:
230       return "CELLS";
231     case MEDCoupling::ON_NODES:
232       return "POINTS";
233     default:
234       STDLOG("MEDPresentation::getFieldTypeString() -- Not implemented ! Gauss points?");
235       return "";
236   }
237 }
238
239 std::string
240 MEDPresentation::getRenderViewVar() const
241 {
242   std::ostringstream oss;
243   oss << "__view" << _renderViewPyId;
244   return oss.str();
245 }
246
247 std::string
248 MEDPresentation::getRenderViewCommand() const
249 {
250   std::ostringstream oss, oss2;
251
252   std::string view(getRenderViewVar());
253   oss2 << "pvs._DisableFirstRenderCameraReset();" << std::endl;
254   if (_viewMode == MEDCALC::VIEW_MODE_OVERLAP) {
255       // this might potentially re-assign to an existing view variable, but this is OK, we
256       // normally reassign exaclty the same RenderView object.
257       oss2 << view << " = pvs.GetActiveViewOrCreate('RenderView');" << std::endl;
258   } else if (_viewMode == MEDCALC::VIEW_MODE_REPLACE) {
259       // same as above
260       oss2 << view << " = pvs.GetActiveViewOrCreate('RenderView');" << std::endl;
261       oss2 << "pvs.active_objects.source and pvs.Hide(view=" << view << ");" << std::endl;
262       oss2 << "pvs.Render();" << std::endl;
263   } else if (_viewMode == MEDCALC::VIEW_MODE_NEW_LAYOUT) {
264       oss2 <<  "__layout1 = pvs.servermanager.misc.ViewLayout(registrationGroup='layouts');" << std::endl;
265       oss2 << view << " = pvs.CreateView('RenderView');" << std::endl;
266   } else if (_viewMode == MEDCALC::VIEW_MODE_SPLIT_VIEW) {
267       oss2 << view << " = pvs.CreateView('RenderView');" << std::endl;
268   }
269   return oss2.str();
270 }
271
272 std::string
273 MEDPresentation::getResetCameraCommand() const
274 {
275   return getRenderViewVar() + ".ResetCamera();";
276 }
277
278 std::string
279 MEDPresentation::getComponentSelectionCommand() const
280 {
281   std::ostringstream oss, oss_l;
282   std::string ret;
283
284   if (_selectedComponentIndex != -1)
285     {
286       oss << _lutVar << ".VectorMode = 'Component';\n";
287       oss << _lutVar << ".VectorComponent = " << _selectedComponentIndex << ";";
288     }
289   else  // Euclidean norm
290     {
291       oss << _lutVar << ".VectorMode = 'Magnitude';";
292     }
293   return oss.str();
294 }
295
296 std::string
297 MEDPresentation::getColorMapCommand() const
298 {
299   std::string ret;
300   switch (_colorMap) {
301   case MEDCALC::COLOR_MAP_BLUE_TO_RED_RAINBOW:
302     ret = _lutVar + ".ApplyPreset('Blue to Red Rainbow',True);";
303     break;
304   case MEDCALC::COLOR_MAP_COOL_TO_WARM:
305     ret = _lutVar + ".ApplyPreset('Cool to Warm',True);";
306     break;
307   default:
308     STDLOG("MEDPresentation::getColorMapCommand(): invalid colormap!");
309     throw KERNEL::createSalomeException("MEDPresentation::getColorMapCommand(): invalid colormap!");
310   }
311   return ret;
312 }
313 std::string
314 MEDPresentation::getRescaleCommand() const
315 {
316   std::string ret;
317   switch(_sbRange)
318   {
319     case MEDCALC::SCALAR_BAR_ALL_TIMESTEPS:
320       ret = _dispVar + ".RescaleTransferFunctionToDataRangeOverTime();";
321       break;
322     case MEDCALC::SCALAR_BAR_CURRENT_TIMESTEP:
323       ret = _dispVar + ".RescaleTransferFunctionToDataRange(False);";
324       break;
325     default:
326       STDLOG("MEDPresentation::getRescaleCommand(): invalid range!");
327       throw KERNEL::createSalomeException("MEDPresentation::getRescaleCommand(): invalid range!");
328   }
329   return ret;
330 }
331
332 int
333 MEDPresentation::GeneratePythonId()
334 {
335   static int INIT_ID = 0;
336   return INIT_ID++;
337 }
338
339 void
340 MEDPresentation::activateView()
341 {
342   MEDPyLockWrapper lock;
343   pushAndExecPyLine("pvs.SetActiveView(" + getRenderViewVar() + ");");
344 }
345
346
347 std::string
348 MEDPresentation::paravisDump() const
349 {
350   using namespace std;
351   ostringstream oss;
352   for (vector<string>::const_iterator it=_pythonCmds.begin(); it != _pythonCmds.end(); ++it)
353     {
354       oss << (*it);
355       oss << "\n";
356     }
357   return oss.str();
358 }
359
360 /**
361  * Query all available component names for the field associated with this presentation.
362  * Fills in all the corresponding string properties:
363  *  - PROP_COMPONENT1
364  *  - PROP_COMPONENT2
365  *    etc...
366  *  and the number of components.
367  */
368 void
369 MEDPresentation::fillAvailableFieldComponents()
370 {
371   MEDPyLockWrapper lock;  // GIL!
372   std::string typ;
373
374   if(_fieldType == "CELLS") {
375       typ = "CellData";
376   }
377   else if (_fieldType == "POINTS") {
378       typ = "PointData";
379   }
380   else {
381       std::string msg("Unsupported spatial discretisation: " + _fieldType);
382       STDLOG(msg);
383       throw KERNEL::createSalomeException(msg.c_str());
384   }
385
386   std::ostringstream oss;
387   oss << "__nbCompo = " << _srcObjVar << "." << typ << ".GetArray('" <<  _fieldName << "').GetNumberOfComponents();";
388   execPyLine(oss.str());
389   PyObject* p_obj = getPythonObjectFromMain("__nbCompo");
390   long nbCompo;
391   if (p_obj && PyInt_Check(p_obj))
392     nbCompo = PyInt_AS_LONG(p_obj);
393   else
394     {
395       STDLOG("Unexpected Python error");
396       throw KERNEL::createSalomeException("Unexpected Python error");
397     }
398   setIntProperty(MEDPresentation::PROP_NB_COMPONENTS, nbCompo);
399   for (long i = 0; i<nbCompo; i++)
400     {
401       std::ostringstream oss2;
402       oss2 << "__compo = " << _srcObjVar << "." << typ << ".GetArray('" <<  _fieldName << "').GetComponentName(" << i << ");";
403       execPyLine(oss2.str());
404       PyObject* p_obj = getPythonObjectFromMain("__compo");
405       std::string compo;
406       if (p_obj && PyString_Check(p_obj))
407         compo = std::string(PyString_AsString(p_obj));  // pointing to internal Python memory, so make a copy!!
408       else
409         {
410           STDLOG("Unexpected Python error");
411           throw KERNEL::createSalomeException("Unexpected Python error");
412         }
413       std::ostringstream oss_p;
414       oss_p << MEDPresentation::PROP_COMPONENT << i;
415       setStringProperty(oss_p.str(), compo);
416     }
417 }
418