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