Salome HOME
[MEDCalc] : better slices + more error handling when invalid params
[modules/med.git] / src / MEDCalc / cmp / MEDPresentationSlices.cxx
1 // Copyright (C) 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
20 #include "MEDPresentationSlices.hxx"
21
22 #include <SALOME_KernelServices.hxx>
23 #undef LOG  // should be fixed in KERNEL - double definition
24 #include <Basics_Utils.hxx>
25
26 #include <sstream>
27
28 const std::string MEDPresentationSlices::TYPE_NAME = "MEDPresentationSlices";
29 const std::string MEDPresentationSlices::PROP_NB_SLICES = "nbSlices";
30 const std::string MEDPresentationSlices::PROP_SLICE_ORIENTATION = "slicesOrientation";
31
32 MEDPresentationSlices::MEDPresentationSlices(const MEDCALC::SlicesParameters& params,
33                                                const MEDCALC::ViewModeType viewMode) :
34         MEDPresentation(params.fieldHandlerId, TYPE_NAME, viewMode, params.colorMap, params.scalarBarRange),
35         _params(params)
36 {
37   setIntProperty(MEDPresentationSlices::PROP_NB_SLICES, params.nbSlices);
38   setIntProperty(MEDPresentationSlices::PROP_SLICE_ORIENTATION, params.orientation);
39
40   int id = GeneratePythonId();
41   std::ostringstream oss;
42   oss << "__objLst" << id;
43   _sliceListVar = oss.str();
44 }
45
46 void
47 MEDPresentationSlices::setSliceParametersAndGroup()
48 {
49   std::ostringstream oss;
50   int nbSlices = getIntProperty(MEDPresentationSlices::PROP_NB_SLICES);
51   std::string normal = getNormalVector();
52
53   oss << "__origins = medcalc.GetSliceOrigins(" << _srcObjVar << ", " << nbSlices << ", " << normal << ");";
54   pushAndExecPyLine(oss.str()); oss.str("");
55
56   oss << "for sliceNum in range(" << nbSlices << "):\n";
57   oss << "  " << _sliceListVar << "[sliceNum].SliceType.Normal = " << normal << ";\n";
58   oss << "  " << _sliceListVar << "[sliceNum].SliceType.Origin = __origins[sliceNum];\n";
59   pushAndExecPyLine(oss.str()); oss.str("");
60
61   oss << _objVar << " = pvs.GroupDatasets(Input=" << _sliceListVar << ");";
62   pushAndExecPyLine(oss.str()); oss.str("");
63 }
64
65 void
66 MEDPresentationSlices::deleteGroup()
67 {
68   std::ostringstream oss;
69   oss << "pvs.Delete(" << _objVar << ");";
70   pushAndExecPyLine(oss.str()); oss.str("");
71 }
72
73 void
74 MEDPresentationSlices::adaptNumberOfSlices()
75 {
76   std::ostringstream oss;
77   int nbSlices = getIntProperty(MEDPresentationSlices::PROP_NB_SLICES);
78
79   oss << "for _ in range(max(len(" << _sliceListVar << ")-" << nbSlices << ", 0)):\n";
80   oss << "  pvs.Delete(" << _sliceListVar << ".pop());\n";
81   pushAndExecPyLine(oss.str()); oss.str("");
82
83   oss << "for _ in range(" << nbSlices << "-max(len(" << _sliceListVar << "), 0)):\n";
84   oss << "  obj = pvs.Slice(Input=" << _srcObjVar << ");\n";
85   oss << "  obj.SliceType = 'Plane';\n";
86   oss << "  " << _sliceListVar << ".append(obj);\n";
87   pushAndExecPyLine(oss.str()); oss.str("");
88 }
89
90 void
91 MEDPresentationSlices::generateAndDisplay()
92 {
93   adaptNumberOfSlices();
94   setSliceParametersAndGroup();
95
96   showObject();
97
98   colorBy(_pvFieldType);
99   showScalarBar();
100   selectColorMap();
101   rescaleTransferFunction();
102   resetCameraAndRender();
103 }
104
105 std::string
106 MEDPresentationSlices::getNormalVector() const
107 {
108   switch(_params.orientation)
109   {
110     case MEDCALC::SLICE_NORMAL_TO_X:
111       return "[1.0, 0.0, 0.0]";
112     case MEDCALC::SLICE_NORMAL_TO_Y:
113       return "[0.0, 1.0, 0.0]";
114     case MEDCALC::SLICE_NORMAL_TO_Z:
115       return "[0.0, 0.0, 1.0]";
116     case MEDCALC::SLICE_NORMAL_TO_XY:
117       return "[1.0, 1.0, 0.0]";
118     case MEDCALC::SLICE_NORMAL_TO_XZ:
119       return "[1.0, 0.0, 1.0]";
120     case MEDCALC::SLICE_NORMAL_TO_YZ:
121       return "[0.0, 1.0, 1.0]";
122     case MEDCALC::SLICE_NORMAL_TO_XYZ:
123       return "[1.0, 1.0, 1.0]";
124     default:
125       const char * mes = "Unexpected getSliceOrientationCommand() error!";
126       STDLOG(mes);
127       throw KERNEL::createSalomeException(mes);
128   }
129   return ""; // never happens
130 }
131
132 void
133 MEDPresentationSlices::selectSliceOrientation(const std::string & obj)
134 {
135   std::ostringstream oss1;
136   oss1 << obj << ".SliceType.Normal = " << getNormalVector() << ";";
137   pushAndExecPyLine(oss1.str()); oss1.str("");
138 }
139
140 void
141 MEDPresentationSlices::internalGeneratePipeline()
142 {
143   MEDPresentation::internalGeneratePipeline();
144
145   MEDPyLockWrapper lock;
146
147   std::ostringstream oss;
148
149   createSource();
150
151   // Populate internal array of available components:
152   fillAvailableFieldComponents();
153   if (_params.nbSlices < 1)
154   {
155       const char * mes = "Invalid number of slices!";
156       STDLOG(mes);
157       throw KERNEL::createSalomeException(mes);
158   }
159
160   setOrCreateRenderView(); // instanciate __viewXXX
161
162   // Now create the initial slices list
163   oss << _sliceListVar << " = [];";
164   pushAndExecPyLine(oss.str()); oss.str("");
165
166   generateAndDisplay();
167 }
168
169 void
170 MEDPresentationSlices::updatePipeline(const MEDCALC::SlicesParameters& params)
171 {
172   if (params.fieldHandlerId != _params.fieldHandlerId)
173     throw KERNEL::createSalomeException("Unexpected updatePipeline error! Mismatching fieldHandlerId!");
174
175   if (std::string(params.displayedComponent) != std::string(_params.displayedComponent))
176     updateComponent<MEDPresentationSlices, MEDCALC::SlicesParameters>(std::string(params.displayedComponent));
177   if (params.scalarBarRange != _params.scalarBarRange)
178     updateScalarBarRange<MEDPresentationSlices, MEDCALC::SlicesParameters>(params.scalarBarRange);
179   if (params.colorMap != _params.colorMap)
180     updateColorMap<MEDPresentationSlices, MEDCALC::SlicesParameters>(params.colorMap);
181
182   if (params.orientation != _params.orientation)
183     updateOrientation(params.orientation);
184   if (params.nbSlices != _params.nbSlices)
185     {
186       if (params.nbSlices < 1)
187       {
188           const char * mes = "Invalid number of slices!";
189           STDLOG(mes);
190           throw KERNEL::createSalomeException(mes);
191       }
192       updateNbSlices(params.nbSlices);
193     }
194 }
195
196 void
197 MEDPresentationSlices::updateNbSlices(const int nbSlices)
198 {
199   _params.nbSlices = nbSlices;
200
201   // GUI helper:
202   setIntProperty(MEDPresentationSlices::PROP_NB_SLICES, nbSlices);
203
204   // Update the pipeline:
205   {
206     MEDPyLockWrapper lock;
207     deleteGroup();
208     generateAndDisplay();
209   }
210 }
211
212 void
213 MEDPresentationSlices::updateOrientation(const MEDCALC::SliceOrientationType orientation)
214 {
215   _params.orientation = orientation;
216
217   // GUI helper:
218   setIntProperty(MEDPresentationSlices::PROP_SLICE_ORIENTATION, static_cast<int>(orientation));
219
220   // Update the pipeline:
221   {
222     MEDPyLockWrapper lock;
223
224     deleteGroup();
225     generateAndDisplay();
226   }
227 }
228