Salome HOME
bos #28928: Merge branch 'rnv/28928'
[modules/med.git] / src / MEDCalc / cmp / MEDPresentationPlot3D.cxx
1 // Copyright (C) 2016-2021  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
20 #include "MEDPyLockWrapper.hxx"
21
22 #include "MEDPresentationPlot3D.hxx"
23 #include "MEDPresentationException.hxx"
24
25 #include <SALOME_KernelServices.hxx>
26 #undef LOG  // should be fixed in KERNEL - double definition
27 #include <Basics_Utils.hxx>
28
29 #include <sstream>
30
31 const std::string MEDPresentationPlot3D::TYPE_NAME = "MEDPresentationPlot3D";
32 const std::string MEDPresentationPlot3D::PROP_PLANE_NORMAL_X = "planeNormalX";
33 const std::string MEDPresentationPlot3D::PROP_PLANE_NORMAL_Y = "planeNormalY";
34 const std::string MEDPresentationPlot3D::PROP_PLANE_NORMAL_Z = "planeNormalZ";
35 const std::string MEDPresentationPlot3D::PROP_PLANE_POS = "planePos";
36 const std::string MEDPresentationPlot3D::PROP_IS_PLANAR = "isPlanar";
37
38
39 MEDPresentationPlot3D::MEDPresentationPlot3D(const MEDCALC::Plot3DParameters& params,
40                                                    const MEDCALC::ViewModeType viewMode) :
41     MEDPresentation(params.fieldHandlerId, TYPE_NAME, viewMode, params.colorMap, params.scalarBarRange),
42     _params(params)
43 {
44   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_X, params.planeNormal[0]);
45   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_Y, params.planeNormal[1]);
46   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_Z, params.planeNormal[2]);
47   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_POS, params.planePos);
48   
49   _isPlanar = 0;
50   setIntProperty(MEDPresentationPlot3D::PROP_IS_PLANAR, _isPlanar);
51 }
52
53 void
54 MEDPresentationPlot3D::initFieldMeshInfos()
55 {
56   MEDPresentation::initFieldMeshInfos();
57   _colorByType = "POINTS";
58 }
59
60
61 void
62 MEDPresentationPlot3D::getSliceObj()
63 {
64   std::ostringstream oss;
65   oss << "__objSlice";
66   _objSlice = oss.str(); oss.str("");
67
68   oss << _objSlice << " = pvs.Slice(" << _srcObjVar << ");";
69         pushAndExecPyLine(oss.str()); oss.str("");
70   
71   oss << _objSlice << ".SliceType.Normal = [" << 
72     _params.planeNormal[0] << ", " <<
73           _params.planeNormal[1] << ", " <<
74           _params.planeNormal[2] << "];";
75   pushAndExecPyLine(oss.str()); oss.str("");
76
77   oss << "slicePos = medcalc.GetPositions(" << _srcObjVar << ", [" <<
78     _params.planeNormal[0] << ", " <<
79           _params.planeNormal[1] << ", " <<
80           _params.planeNormal[2] << "]," <<
81     _params.planePos << ");";
82   pushAndExecPyLine(oss.str()); oss.str("");
83
84   oss << _objSlice << ".SliceType.Origin = slicePos";
85   pushAndExecPyLine(oss.str()); oss.str("");
86   oss << _objVar << " = " << _objSlice;
87   execPyLine(oss.str()); oss.str(""); 
88 }
89
90 void
91 MEDPresentationPlot3D::getMagnitude()
92 {
93   std::ostringstream oss;
94   oss << "__objCalc";
95   _objCalc = oss.str(); oss.str("");
96
97         oss << _objCalc <<"= pvs.Calculator(Input=" << _objSlice << ");";
98   pushAndExecPyLine(oss.str()); oss.str("");
99   if (_pvFieldType == "CELLS") {
100     oss << _objCalc << ".AttributeType = 'Cell Data'";
101     pushAndExecPyLine(oss.str()); oss.str("");
102   }
103   oss << _objCalc << ".ResultArrayName = 'resCalcMag'";
104   pushAndExecPyLine(oss.str()); oss.str("");
105   std::string fieldName = _fieldName;
106   if(_nbComponents == 2)
107     fieldName += "_Vector";
108   oss << _objCalc << ".Function = 'mag(" << fieldName << ")'";
109   pushAndExecPyLine(oss.str()); oss.str("");
110   execPyLine(oss.str()); oss.str("");
111 }
112
113 void
114 MEDPresentationPlot3D::internalGeneratePipeline()
115 {
116   MEDPresentation::internalGeneratePipeline();
117
118   MEDPyLockWrapper lock;
119
120   createSource();
121   setTimestamp();
122
123   fillAvailableFieldComponents();
124   setOrCreateRenderView();
125
126   std::ostringstream oss;
127   oss << "is_planar = medcalc.IsPlanarObj("<< _srcObjVar<<");";
128   pushAndExecPyLine(oss.str()); oss.str("");
129   getPythonObjectFromMain("is_planar");
130   PyObject * obj = getPythonObjectFromMain("is_planar");
131
132   // Planar mesh?
133   if (obj && PyBool_Check(obj) && (obj == Py_False))
134   {
135           getSliceObj();
136   }
137   else
138   {
139     oss << "__objSlice";
140     _objSlice = oss.str(); oss.str("");
141     oss << _objSlice << " = " << _srcObjVar;
142           execPyLine(oss.str()); oss.str("");
143     _isPlanar = 1;
144     setIntProperty(MEDPresentationPlot3D::PROP_IS_PLANAR, _isPlanar);
145   }
146   // Vector field?
147   if(_nbComponents > 1)
148   {
149     getMagnitude();
150     oss << "scalarArray = "<< _objCalc << ".ResultArrayName;";
151     execPyLine(oss.str()); oss.str("");
152   }
153   else
154   {
155     oss << "__objCalc";
156     _objCalc = oss.str(); oss.str("");
157     oss << _objCalc << " = " << _objSlice;
158           execPyLine(oss.str()); oss.str("");
159   }
160   // cell data?
161   if (_pvFieldType == "CELLS")
162   {
163     oss << _objCalc << " = pvs.CellDatatoPointData(" << _objCalc << ");";
164     oss << _objCalc << ".PassCellData = 1;";
165     pushAndExecPyLine(oss.str()); oss.str("");
166   }
167
168   oss << _objVar << " = pvs.WarpByScalar(Input=" << _objCalc << ");";
169   pushAndExecPyLine(oss.str()); oss.str("");
170   if(_nbComponents > 1)
171     oss << _objVar << ".Scalars = ['" << "POINTS" << "', " << "scalarArray]";
172   else
173     oss << _objVar << ".Scalars = ['" << "POINTS" << "', '" << _fieldName << "']";
174   pushAndExecPyLine(oss.str()); oss.str("");
175   if (obj && PyBool_Check(obj) && (obj == Py_False))
176   {
177     oss << _objVar << ".Normal = [" << 
178     _params.planeNormal[0] << ", " <<
179           _params.planeNormal[1] << ", " <<
180           _params.planeNormal[2] << "];";
181   }
182   else
183   {
184     oss << "P2 = " << "medcalc.GetPlaneNormalVector(" << _objSlice << ")";
185     execPyLine(oss.str()); oss.str("");
186     PyObject * obj2 = getPythonObjectFromMain("P2");
187     if (obj2 && PyList_Check(obj2)) {
188       PyObject* objP0 = PyList_GetItem(obj2, 0);
189       PyObject* objP1 = PyList_GetItem(obj2, 1);
190       PyObject* objP2 = PyList_GetItem(obj2, 2);
191       if (PyFloat_Check(objP0) && PyFloat_Check(objP1) && PyFloat_Check(objP2)) {
192         _params.planeNormal[0] = PyFloat_AsDouble(objP0);
193         _params.planeNormal[1] = PyFloat_AsDouble(objP1);
194         _params.planeNormal[2] = PyFloat_AsDouble(objP2);
195       }
196     }
197
198   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_X, _params.planeNormal[0]);
199   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_Y, _params.planeNormal[1]);
200   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_Z, _params.planeNormal[2]);
201     oss << _objVar << ".Normal = " << "medcalc.GetPlaneNormalVector(" << _objSlice << ")";
202   }
203   pushAndExecPyLine(oss.str()); oss.str("");
204
205   showObject();
206   colorBy();    // see initFieldInfo() - necessarily POINTS because of the conversion above
207   showScalarBar();
208   selectColorMap();
209   rescaleTransferFunction();
210   resetCameraAndRender();
211 }
212
213 void
214 MEDPresentationPlot3D::updatePipeline(const MEDCALC::Plot3DParameters& params)
215 {
216   if (params.fieldHandlerId != _params.fieldHandlerId)
217     throw KERNEL::createSalomeException("Unexpected updatePipeline error! Mismatching fieldHandlerId!");
218
219   if (params.colorMap != _params.colorMap)
220     updateColorMap<MEDPresentationPlot3D, MEDCALC::Plot3DParameters>(params.colorMap);
221
222   if (params.scalarBarRange != _params.scalarBarRange ||
223     params.hideDataOutsideCustomRange != _params.hideDataOutsideCustomRange ||
224     params.scalarBarRangeArray[0] != _params.scalarBarRangeArray[0] ||
225     params.scalarBarRangeArray[1] != _params.scalarBarRangeArray[1])
226     updateScalarBarRange<MEDPresentationPlot3D, MEDCALC::Plot3DParameters>(params.scalarBarRange,
227       params.hideDataOutsideCustomRange,
228       params.scalarBarRangeArray[0],
229       params.scalarBarRangeArray[1]);
230
231   if (params.planeNormal[0] != _params.planeNormal[0] ||
232       params.planeNormal[1] != _params.planeNormal[1] ||
233       params.planeNormal[2] != _params.planeNormal[2])
234     updatePlaneNormal(params.planeNormal);
235
236   if (_isPlanar == 0 && params.planePos != _params.planePos)
237     updatePlanePos(params.planePos);
238
239   if (params.visibility != _params.visibility)
240     updateVisibility<MEDPresentationPlot3D, MEDCALC::Plot3DParameters>(params.visibility);
241   if (params.scalarBarVisibility != _params.scalarBarVisibility)
242     updateScalarBarVisibility<MEDPresentationPlot3D, MEDCALC::Plot3DParameters>(params.scalarBarVisibility);
243 }
244
245 void
246 MEDPresentationPlot3D::updatePlaneNormal(MEDCALC::DoubleArray planeNormal)
247 {
248   _params.planeNormal[0] = planeNormal[0];
249   _params.planeNormal[1] = planeNormal[1];
250   _params.planeNormal[2] = planeNormal[2];
251
252   // GUI helper:
253   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_X, planeNormal[0]);
254   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_Y, planeNormal[1]);
255   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_NORMAL_Z, planeNormal[2]);
256   
257   // Update Plane Normal
258   {
259     MEDPyLockWrapper lock;
260     std::ostringstream oss;
261     if(_isPlanar == 0)
262     {
263       oss << _objSlice << ".SliceType.Normal = [" << 
264       _params.planeNormal[0] << ", " <<
265             _params.planeNormal[1] << ", " <<
266             _params.planeNormal[2] << "];";
267       pushAndExecPyLine(oss.str()); oss.str("");
268       updatePlanePos(_params.planePos);
269     }
270
271     oss << _objVar << ".Normal = [" << 
272     _params.planeNormal[0] << ", " <<
273           _params.planeNormal[1] << ", " <<
274           _params.planeNormal[2] << "];";
275     pushAndExecPyLine(oss.str()); oss.str("");
276     pushAndExecPyLine("pvs.Render();");
277   }
278 }
279
280 void
281 MEDPresentationPlot3D::updatePlanePos(const double planePos)
282 {
283   _params.planePos = planePos;
284
285   // GUI helper:
286   setDoubleProperty(MEDPresentationPlot3D::PROP_PLANE_POS, planePos);
287
288   // Update Plane Position
289   {
290     MEDPyLockWrapper lock;
291     std::ostringstream oss;
292     oss << "slicePos = medcalc.GetPositions(" << _srcObjVar << ", [" <<
293       _params.planeNormal[0] << ", " <<
294             _params.planeNormal[1] << ", " <<
295             _params.planeNormal[2] << "]," <<
296       _params.planePos << ");";
297     pushAndExecPyLine(oss.str()); oss.str("");
298
299     oss << _objSlice << ".SliceType.Origin = slicePos";
300     pushAndExecPyLine(oss.str()); oss.str("");
301     pushAndExecPyLine("pvs.Render();");
302   }
303 }