Salome HOME
[MEDCalc] Fully functional scalar map (other pres deactivated)
[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 "MEDFactoryClient.hxx"
22 #include "MEDPresentation.hxx"
23 #include "MEDPresentationException.hxx"
24 #include "MEDCouplingRefCountObject.hxx"
25 #include <SALOME_KernelServices.hxx>
26 #undef LOG
27 #include <Basics_Utils.hxx>
28 #include <PyInterp_Utils.h>
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::MEDPresentationViewMode viewMode,
41                                  const MEDCALC::MEDPresentationColorMap colorMap)
42     : _fieldHandlerId(fieldHandlerId), _propertiesStr(),
43       //_pipeline(0), _display(0)
44       _selectedComponentIndex(-1),
45       _viewMode(viewMode),
46       _colorMap(colorMap),
47       _renderViewPyId(GeneratePythonId()),
48       _objId(_renderViewPyId), _dispId(_renderViewPyId), _lutId(_renderViewPyId),
49       _globalDict(0)
50 {
51   MEDCALC::MEDDataManager_ptr dataManager(MEDFactoryClient::getDataManager());
52   MEDCALC::FieldHandler* fieldHandler = dataManager->getFieldHandler(fieldHandlerId);
53   MEDCALC::MeshHandler* meshHandler = dataManager->getMesh(fieldHandler->meshid);
54   MEDCALC::DatasourceHandler* dataSHandler = dataManager->getDatasourceHandlerFromID(meshHandler->sourceid);
55
56   _fileName = dataSHandler->uri;
57   _fieldName = fieldHandler->fieldname;
58   _fieldType = getFieldTypeString((MEDCoupling::TypeOfField) fieldHandler->type);
59
60   if (_fileName.substr(0, 7) != std::string("file://")) {
61     const char* msg = "Data source is not a file! Can not proceed.";
62     throw MEDPresentationException(msg);
63   }
64   _fileName = _fileName.substr(7, _fileName.size());
65
66   setStringProperty(MEDPresentation::PROP_NAME, name);
67
68   setIntProperty(MEDPresentation::PROP_NB_COMPONENTS, 0);
69   setIntProperty(MEDPresentation::PROP_SELECTED_COMPONENT, 0);
70
71   setIntProperty(MEDPresentation::PROP_COLOR_MAP, static_cast<int>(MEDCALC::COLOR_MAP_DEFAULT));
72   setIntProperty(MEDPresentation::PROP_SCALAR_BAR_RANGE, static_cast<int>(MEDCALC::SCALAR_BAR_RANGE_DEFAULT));
73 }
74
75 MEDPresentation::~MEDPresentation()
76 {
77   STDLOG("~MEDPresentation(): clear display");
78   {
79     PyLockWrapper lock;
80     std::ostringstream oss_o, oss_v, oss;
81     oss_o << "__obj" << _objId;
82     oss_v << "__view" << _renderViewPyId;
83     oss << "pvs.Hide(" << oss_o.str() <<  ", view=" << oss_v.str() << ");";
84     oss << "pvs.Render();";
85
86     PyRun_SimpleString(oss.str().c_str());
87   }
88 }
89
90 void
91 MEDPresentation::generatePipeline()
92 {
93   // Might be more complicated in the future:
94
95   this->internalGeneratePipeline();
96 }
97
98 //void
99 //MEDPresentation::pushPyObjects(PyObjectId obj, PyObjectId disp)
100 //{
101 //  _pipeline.push_back(obj);
102 //  _display.push_back(disp);
103 //}
104
105 void
106 MEDPresentation::pushAndExecPyLine(const std::string & lin)
107 {
108   PyLockWrapper lock;
109 //  std::cerr << lin << std::endl;
110   if(PyRun_SimpleString(lin.c_str()))
111     {
112       std::ostringstream oss;
113       oss << "MEDPresentation::pushAndExecPyLine(): following Python command failed!\n";
114       oss << ">> " << lin;
115       STDLOG(oss.str());
116       throw KERNEL::createSalomeException(oss.str().c_str());
117     }
118   _pythonCmds.push_back(lin);
119 }
120
121 void
122 MEDPresentation::setStringProperty(const std::string& propName, const std::string& propValue)
123 {
124   _propertiesStr[propName] = propValue;
125 }
126
127 const std::string
128 MEDPresentation::getStringProperty(const std::string& propName) const
129 {
130   std::map<std::string, std::string>::const_iterator it = _propertiesStr.find(propName);
131   if (it != _propertiesStr.end()) {
132       return (*it).second;
133   }
134   else {
135       throw MEDPresentationException("MEDPresentation::getStringProperty(): no property named " + propName);
136   }
137 }
138
139 void
140 MEDPresentation::setIntProperty(const std::string& propName, const int propValue)
141 {
142   _propertiesInt[propName] = propValue;
143 }
144
145 int
146 MEDPresentation::getIntProperty(const std::string& propName) const
147 {
148   std::map<std::string, int>::const_iterator it = _propertiesInt.find(propName);
149   if (it != _propertiesInt.end()) {
150       return (*it).second;
151   }
152   else {
153       throw MEDPresentationException("MEDPresentation::getIntProperty(): no property named " + propName);
154   }
155 }
156
157  void
158  MEDPresentation::dumpIntProperties() const
159  {
160    std::map<std::string, int>::const_iterator it = _propertiesInt.begin();
161    STDLOG("@@@ Dumping INT properties");
162    for(; it != _propertiesInt.end(); ++it)
163      {
164        std::ostringstream oss;
165        oss << (*it).first << "  ->   " << (*it).second;
166        STDLOG(oss.str());
167      }
168  }
169
170  void
171  MEDPresentation::dumpStringProperties() const
172  {
173    std::map<std::string, std::string>::const_iterator it = _propertiesStr.begin();
174    STDLOG("@@@ Dumping STR properties");
175    for(; it != _propertiesStr.end(); ++it)
176      {
177        std::ostringstream oss;
178        oss << (*it).first << "  ->   " << (*it).second;
179        STDLOG(oss.str());
180      }
181  }
182
183
184 PyObject*
185 MEDPresentation::getPythonObjectFromMain(const char* python_var) const
186 {
187   if (! _globalDict)
188     {
189       // All the calls below returns *borrowed* references
190       PyObject* main_module = PyImport_AddModule((char*)"__main__");
191       _globalDict = PyModule_GetDict(main_module);
192     }
193   return PyDict_GetItemString(_globalDict, python_var);
194 }
195
196 std::string
197 MEDPresentation::getFieldTypeString(MEDCoupling::TypeOfField fieldType) const
198 {
199   switch(fieldType)
200   {
201     case MEDCoupling::ON_CELLS:
202       return "CELLS";
203     case MEDCoupling::ON_NODES:
204       return "POINTS";
205     default:
206       STDLOG("MEDPresentation::getFieldTypeString() -- Not implemented ! Gauss points?");
207       return "";
208   }
209 }
210
211 std::string
212 MEDPresentation::getRenderViewCommand() const
213 {
214   std::ostringstream oss, oss2;
215   oss << "__view" << _renderViewPyId;
216   std::string view(oss.str());
217   oss2 << "pvs._DisableFirstRenderCameraReset();" << std::endl;
218   if (_viewMode == MEDCALC::VIEW_MODE_OVERLAP) {
219       oss2 << view << " = pvs.GetActiveViewOrCreate('RenderView');" << std::endl;
220   } else if (_viewMode == MEDCALC::VIEW_MODE_REPLACE) {
221       oss2 << view << " = pvs.GetActiveViewOrCreate('RenderView');" << std::endl;
222       oss2 << "pvs.active_objects.source and pvs.Hide(view=" << view << ");" << std::endl;
223       oss2 << "pvs.Render();" << std::endl;
224   } else if (_viewMode == MEDCALC::VIEW_MODE_NEW_LAYOUT) {
225       oss2 <<  "__layout1 = pvs.servermanager.misc.ViewLayout(registrationGroup='layouts');" << std::endl;
226       oss2 << view << " = pvs.CreateView('RenderView');" << std::endl;
227   } else if (_viewMode == MEDCALC::VIEW_MODE_SPLIT_VIEW) {
228       oss2 << view << " = pvs.CreateView('RenderView');" << std::endl;
229   }
230   return oss2.str();
231 }
232
233 std::string
234 MEDPresentation::getResetCameraCommand() const
235 {
236   std::ostringstream oss;
237   oss << "__view" << _renderViewPyId << ".ResetCamera();";
238   return oss.str();
239 }
240
241 std::string
242 MEDPresentation::getComponentSelectionCommand() const
243 {
244   std::ostringstream oss, oss_l;
245   oss_l << "__lut" << _lutId;    std::string lut(oss_l.str());
246
247   if (_selectedComponentIndex != -1)
248     {
249       oss << lut << ".VectorMode = 'Component';\n";
250       oss << lut << ".VectorComponent = " << _selectedComponentIndex << ";";
251     }
252   else  // Euclidean norm
253     {
254       oss << lut << ".VectorMode = 'Magnitude';";
255     }
256   return oss.str();
257 }
258
259 std::string
260 MEDPresentation::getColorMapCommand() const
261 {
262   std::ostringstream oss, oss_l;
263   oss_l << "__lut" << _lutId;    std::string lut(oss_l.str());
264   switch (_colorMap) {
265   case MEDCALC::COLOR_MAP_BLUE_TO_RED_RAINBOW:
266     oss << lut << ".ApplyPreset('Blue to Red Rainbow',True);";
267     break;
268   case MEDCALC::COLOR_MAP_COOL_TO_WARM:
269     oss << lut << ".ApplyPreset('Cool to Warm',True);";
270     break;
271   default:
272     throw KERNEL::createSalomeException("MEDPresentation::getColorMapCommand(): invalid colormap!");
273   }
274   return oss.str();
275 }
276 std::string
277 MEDPresentation::getRescaleCommand() const
278 {
279   std::ostringstream oss, oss_d;
280   oss_d << "__disp" << _dispId;    std::string disp(oss_d.str());
281   switch(_sbRange)
282   {
283     case MEDCALC::SCALAR_BAR_ALL_TIMESTEPS:
284       oss << disp <<  ".RescaleTransferFunctionToDataRangeOverTime();";
285       break;
286     case MEDCALC::SCALAR_BAR_CURRENT_TIMESTEP:
287       oss << disp <<  ".RescaleTransferFunctionToDataRange(False);";
288       break;
289     default:
290       throw KERNEL::createSalomeException("MEDPresentation::getRescaleCommand(): invalid range!");
291   }
292   return oss.str();
293 }
294
295 int
296 MEDPresentation::GeneratePythonId()
297 {
298   static int INIT_ID = 0;
299   return INIT_ID++;
300 }
301
302 void
303 MEDPresentation::activateView()
304 {
305   PyLockWrapper lock;
306
307   std::ostringstream oss;
308   oss << "pvs.SetActiveView(__view" << _renderViewPyId << ");";
309   pushAndExecPyLine(oss.str());
310 }
311
312
313 std::string
314 MEDPresentation::paravisDump() const
315 {
316   using namespace std;
317   ostringstream oss;
318   for (vector<string>::const_iterator it=_pythonCmds.begin(); it != _pythonCmds.end(); ++it)
319     {
320       oss << (*it);
321       oss << "\n";
322     }
323   return oss.str();
324 }
325
326 /**
327  * Query all available component names for the field associated with this presentation.
328  * Fills in all the corresponding string properties:
329  *  - PROP_COMPONENT1
330  *  - PROP_COMPONENT2
331  *    etc...
332  *  and the number of components.
333  */
334 void
335 MEDPresentation::fillAvailableFieldComponents()
336 {
337   PyLockWrapper lock;  // GIL!
338
339   std::ostringstream oss_o;
340   oss_o << "__obj" << _objId;      std::string obj(oss_o.str());
341   std::string typ;
342
343   if(_fieldType == "CELLS") {
344       typ = "CellData";
345   }
346   else if (_fieldType == "POINTS") {
347       typ = "PointData";
348   }
349   else {
350       std::string msg("Unsupported spatial discretisation: " + _fieldType);
351       throw KERNEL::createSalomeException(msg.c_str());
352   }
353
354   std::ostringstream oss;
355   oss << "__nbCompo = " << obj << "." << typ << ".GetArray('" <<  _fieldName << "').GetNumberOfComponents();";
356   PyRun_SimpleString(oss.str().c_str());
357   PyObject* p_obj = getPythonObjectFromMain("__nbCompo");
358   long nbCompo;
359   if (p_obj && PyInt_Check(p_obj))
360     nbCompo = PyInt_AS_LONG(p_obj);
361   else
362     throw KERNEL::createSalomeException("Unexpected Python error");
363   setIntProperty(MEDPresentation::PROP_NB_COMPONENTS, nbCompo);
364   for (long i = 0; i<nbCompo; i++)
365     {
366       std::ostringstream oss2;
367       oss2 << "__compo = " << obj << "." << typ << ".GetArray('" <<  _fieldName << "').GetComponentName(" << i << ");";
368       PyRun_SimpleString(oss2.str().c_str());
369       PyObject* p_obj = getPythonObjectFromMain("__compo");
370       std::string compo;
371       if (p_obj && PyString_Check(p_obj))
372         compo = std::string(PyString_AsString(p_obj));  // pointing to internal Python memory, so make a copy!!
373       else
374         throw KERNEL::createSalomeException("Unexpected Python error");
375       std::ostringstream oss_p;
376       oss_p << MEDPresentation::PROP_COMPONENT << i;
377       setStringProperty(oss_p.str(), compo);
378     }
379 }
380