Salome HOME
353cd0496e6e546bbb53e4d8bcbdee545830cc37
[modules/paravis.git] / test / VisuPrs / Util / paravistest.py
1 # Copyright (C) 2010-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 """
21 This module provides auxiliary classes, functions and variables for testing.
22 """
23
24 #from __future__ import print_function
25
26 from math import fabs
27 import os
28 import tempfile
29 import getpass
30 from datetime import date
31 import struct
32
33 # Auxiliary variables
34
35 # Data directory
36 samples_dir = os.getenv("DATA_DIR")
37 datadir = None
38 tablesdir = None
39 texturesdir = None
40 if samples_dir is not None:
41     samples_dir = os.path.normpath(samples_dir)
42     datadir = samples_dir + "/MedFiles/"
43     tablesdir = samples_dir + "/Tables/"
44     texturesdir = samples_dir + "/Textures/"
45
46 # Graphics files extension
47 pictureext = os.getenv("PIC_EXT")
48 if pictureext == None:
49     pictureext = "png"
50
51
52 # Auxiliary classes
53 class RepresentationType:
54     """
55     Types of representation.
56     """
57     OUTLINE = 0
58     POINTS = 1
59     WIREFRAME = 2
60     SURFACE = 3
61     SURFACEEDGES = 4
62     VOLUME = 5
63     POINTSPRITE = 6
64
65     _type2name = {OUTLINE: 'Outline',
66                   POINTS: 'Points',
67                   WIREFRAME: 'Wireframe',
68                   SURFACE: 'Surface',
69                   SURFACEEDGES: 'Surface With Edges',
70                   VOLUME: 'Volume',
71                   POINTSPRITE: 'Point Sprite'}
72
73     @classmethod
74     def get_name(cls, type):
75         """Return paraview representation type by the primitive type."""
76         return cls._type2name[type]
77
78
79 # Auxiliary functions
80 def test_values(value, et_value, check_error=0):
81     """Test values."""
82     error = 0
83     length = len(value)
84     et_length = len(et_value)
85     if (length != et_length):
86         err_msg = "ERROR!!! There is different number of created " + str(length) + " and etalon " + str(et_length) + " values!!!"
87         print err_msg
88         error = error + 1
89     else:
90         for i in range(et_length):
91             if abs(et_value[i]) > 1:
92                 max_val = abs(0.001 * et_value[i])
93                 if abs(et_value[i] - value[i]) > max_val:
94                     err_msg = "ERROR!!! Got value " + str(value[i]) + " is not equal to etalon value " + str(ret_value[i]) + "!!!"
95                     print err_msg
96                     error = error + 1
97             else:
98                 max_val = 0.001
99                 if abs(et_value[i] - value[i]) > max_val:
100                     err_msg = "ERROR!!! Got value " + value[i] + " is not equal to etalon value " + et_value[i] + "!!!"
101                     error = error + 1
102     if check_error and error > 0:
103         err_msg = ("There is(are) some error(s) was(were) found... "
104                    "For more info see ERRORs above...")
105         raise RuntimeError(err_msg)
106     return error
107
108
109 def get_picture_dir(subdir):
110     res_dir = os.getenv("PARAVIS_TEST_PICS")
111     if not res_dir:
112         # Add username and current date to unify the directory
113         cur_user = getpass.getuser()
114         cur_date = date.today().strftime("%Y%m%d")
115         res_dir = tempfile.gettempdir() + \
116             "/pic_" + cur_user + \
117             "/test_" + cur_date
118     # Add subdirectory for the case to the directory path
119     res_dir += "/" + subdir
120     # Create the directory if doesn't exist
121     res_dir = os.path.normpath(res_dir)
122     if not os.path.exists(res_dir):
123         os.makedirs(res_dir)
124     else:
125         # Clean the directory
126         for root, dirs, files in os.walk(res_dir):
127             for f in files:
128                 os.remove(os.path.join(root, f))
129
130     return res_dir
131
132
133 def call_and_check(prs, property_name, value, do_raise=1, compare_toler=-1.0):
134     """Utility function for 3D viewer test for common check of different
135     types of presentation parameters set"""
136     if property_name == 'Representation':
137         if value in prs.GetProperty('RepresentationTypesInfo'):
138             prs.SetPropertyWithName(property_name, value)
139             error_string = None
140         else:
141             error_string = (str(value) + " value of " + property_name + " is not available for this type of presentations")
142     else:
143         try:
144             prs.SetPropertyWithName(property_name, value)
145         except ValueError:
146             error_string = (str(value) + "value of " + property_name + " is not available for this type of presentations")
147         else:
148             error_string = None
149     is_good = (error_string is None)
150     if not is_good:
151         if do_raise:
152             raise RuntimeError(error_string)
153         else:
154             print error_string
155     else:
156         # compare just set value and the one got from presentation
157         really_set_value = prs.GetPropertyValue(property_name)
158         is_equal = 1
159         if compare_toler > 0:
160             is_equal = (fabs(really_set_value - value) < compare_toler)
161         else:
162             is_equal = (really_set_value == value)
163         if not is_equal:
164             msg = str(really_set_value) + " has been set instead"
165             if do_raise:
166                 raise RuntimeError(msg)
167             else:
168                 print msg
169                 is_good = False
170
171     return is_good
172
173
174 def compare_lists(value, et_value, check_error=0, eps=1e-04):
175     """
176     Compare two lists: the same length and equality of corresponding items
177     param value - list to be compared
178     param et_value - etalon list
179     param check_error - flag to catch exception if errors>0
180     check_error=0 no exception, check_error !=0 catch exception
181     param eps - defines tolerance for comparison
182     return error - number of errors
183     """
184
185     error=0
186     length = len(value)
187     et_length = len(et_value)
188     if length != et_length:
189         print "ERROR!!! There is different number of items in created ", length, " and etalon ", et_length, " lists!!!"
190         error=error+1
191     else:
192         for i in range(et_length):
193             if abs(et_value[i]) > 1:
194                 MAX = abs(eps*et_value[i])
195             else:
196                 MAX = eps
197             if abs(et_value[i] - value[i])> MAX:
198                 print "ERROR!!!", i, "-th  item", value[i], " is not equal to etalon item", et_value[i], "!!!"
199                 error=error+1
200     if check_error and error > 0:
201         raise RuntimeError, "There is(are) some error(s) was(were) found... For more info see ERRORs above..."
202     return error
203
204
205 def setShaded(view, shading):
206     """Utility function to set shaded mode in view"""
207     if shading == 0:
208         view.LightDiffuseColor = [1, 1, 1]
209     if shading == 1:
210         view.LightDiffuseColor = [0, 0, 0]
211
212
213 def TimeStampId(proxy):
214     """Return tuple for the given MED proxy: (mesh_name, {field_name: [entity, timestamp_id]})
215     Originally defined in KERNEL_TEST/Tools/CommonFunctions file.
216     """
217     import presentations
218     mesh_name = presentations.get_mesh_full_names(proxy).pop()
219     iterations = {}
220
221     # get list of field names
222     all_fields = proxy.GetProperty("FieldsTreeInfo")[::2]
223
224     # get timestamps
225     timestamps = proxy.TimestepValues.GetData()
226     timestamp_nb = len(timestamps)
227
228     for field in all_fields:
229         entity = presentations.get_field_entity(field)
230         field_short_name = presentations.get_field_short_name(field)
231
232         iterations[field_short_name] = [entity, timestamp_nb]
233
234     return mesh_name, iterations
235
236
237 def Import_Med_Field(filename, field_names, check_errors=0, prs=[]):
238     """Builds presentations on the given fields of the MED file.
239     Originally defined in VISU_TEST/Grids/visu/ImportMedField/begin file.
240
241     Arguments:
242       filename     : the full path to med file
243       field_names  : the list of field names (for ex: ["pression","temperature","vitesse"])
244       prs          : [[0,1,...], [], []]; empty list (sublist(s)) is ignored
245                      0-VISU.TGAUSSPOINTS
246                      1-VISU.TSCALARMAP
247                      2-VISU.TISOSURFACE
248                      3-VISU.TCUTPLANES
249                      4-VISU.TCUTLINES
250                      5-VISU.TDEFORMEDSHAPE
251                      6-VISU.TVECTORS
252                      7-VISU.TSTREAMLINES
253                      8-VISU.TPLOT3D
254                      9-VISU.TSCALARMAPONDEFORMEDSHAPE
255     """
256     import presentations
257
258     nb_errors = 0
259
260     print "File: ", filename
261
262     # check the file accessibility
263     if not os.access(filename, os.F_OK):
264         msg = "File " + filename + " does not exist!!!"
265         raise RuntimeError, msg
266
267     # import MED file
268     import pvsimple
269     pvsimple.OpenDataFile(filename)
270     proxy = presentations.pvs.GetActiveSource()
271     if proxy is None:
272         raise RuntimeError, "ERROR!!! Can't import file!!!"
273
274     for i in range(len(field_names)):
275         print "Name of the field: ", field_names[i]
276
277         if len(prs) != 0:
278             if len(prs[i]) != 0:
279                 mesh_name, iterations = TimeStampId(proxy)
280
281                 if iterations.has_key(field_names[i]):
282                     entity = iterations[field_names[i]][0]
283                     iteration = iterations[field_names[i]][1]
284                 else:
285                     msg="There is no information about TimeStampId of the " + field_names[i] + " field!!!"
286                     raise RuntimeError, msg
287
288                 err = nb_errors
289
290                 for type in prs[i]:
291                     try:
292                         if type==0:
293                             if presentations.GaussPointsOnField(proxy, entity, field_names[i], iteration) is None:
294                                 print "ERROR!!! Created GaussPoints presentation is None!!!"; nb_errors+=1
295                         if type==1:
296                             if presentations.ScalarMapOnField(proxy, entity, field_names[i], iteration) is None:
297                                 print "ERROR!!! Created ScalarMap presentation is None!!!"; nb_errors+=1
298                         if type==2:
299                             if presentations.IsoSurfacesOnField(proxy, entity, field_names[i], iteration) is None:
300                                 print "ERROR!!! Created IsoSurfaces presentation is None!!!"; nb_errors+=1
301                         if type==3:
302                             if presentations.CutPlanesOnField(proxy, entity, field_names[i], iteration) is None:
303                                 print "ERROR!!! Created CutPlanes presentation is None!!!"; nb_errors+=1
304                         if type==4:
305                             if presentations.CutLinesOnField(proxy, entity, field_names[i], iteration) is None:
306                                 print "ERROR!!! Created CutLines presentation is None!!!"; nb_errors+=1
307                         if type==5:
308                             if presentations.DeformedShapeOnField(proxy, entity, field_names[i], iteration) is None:
309                                 print "ERROR!!! Created DeformedShape presentation is None!!!"; nb_errors+=1
310                         if type==6:
311                             if presentations.VectorsOnField(proxy, entity, field_names[i], iteration) is None:
312                                 print "ERROR!!! Created Vectors presentation is None!!!"; nb_errors+=1
313                         if type==7:
314                             if presentations.StreamLinesOnField(proxy, entity, field_names[i], iteration) is None:
315                                 print "ERROR!!! Created StreamLines presentation is None!!!"; nb_errors+=1
316                         if type==8:
317                             if presentations.Plot3DOnField(proxy, entity, field_names[i], iteration) is None:
318                                 print "ERROR!!! Created Plot3D presentation is None!!!"; nb_errors+=1
319                         if type==9:
320                             if presentations.DeformedShapeAndScalarMapOnField(proxy, entity, field_names[i], iteration) is None:
321                                 print "ERROR!!! Created ScalarMapOnDeformedShape presentation is None!!!"; nb_errors+=1
322                     except ValueError:
323                         """ This exception comes from get_nb_components(...) function.
324                             The reason of exception is an implementation of MEDReader
325                             activating the first leaf when reading MED file (refer to
326                             MEDFileFieldRepresentationTree::activateTheFirst() and
327                             MEDFileFieldRepresentationTree::getTheSingleActivated(...) methods).
328                         """
329                         print "ValueError exception is catched"
330                         continue
331
332                 # check if number of errors has increased
333                 if err == nb_errors:
334                     print "Presentation(s) creation...OK"
335
336     if nb_errors > 0 and check_errors:
337         raise RuntimeError, "Errors occured!!! For more information see ERRORs above..."
338     else:
339         return nb_errors
340
341 def delete_with_inputs(obj):
342     """Deletes the given object with all its inputs"""
343     import pvsimple
344
345     obj_to_delete = obj
346     while obj_to_delete is not None:
347         tmp_obj = obj_to_delete
348         obj_to_delete = None
349         if hasattr(tmp_obj, 'Input'):
350             obj_to_delete = tmp_obj.Input
351
352         pvsimple.Delete(tmp_obj)
353
354 def get_png_picture_resolution(infile):
355     """Returns size (width, height) of the PNG image"""    
356     f = open(infile, 'rb')    
357     data = f.read(24)
358     f.close()
359     if not (data[:8] == '\211PNG\r\n\032\n'and (data[12:16] == 'IHDR')):
360         raise RuntimeError("File '%s' is not PNG image"%(infile))
361
362     w, h = struct.unpack('>LL', data[16:24])
363     width = int(w)
364     height = int(h)
365     return (width,height)
366
367 def save_trace(afile,atrace):    
368     """Saves atrace in afile"""        
369     f = open(afile, 'w')
370     f.write(atrace)
371     f.close()