Salome HOME
[MEDCalc] Multiple slices + other minor imps:
[modules/med.git] / src / MEDCalc / tui / medpresentation.py
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
20 import medcalc
21 import MEDCALC, SALOME
22 from medcalc.medevents import notifyGui_addPresentation, notifyGui_removePresentation, notifyGui_error, notifyGui_modifyPresentation
23
24 __manager = medcalc.medcorba.factory.getPresentationManager()
25
26 def MakeMeshView(proxy,
27                  viewMode=MEDCALC.VIEW_MODE_DEFAULT,
28                  meshMode=MEDCALC.MESH_MODE_DEFAULT):
29   # Create the presentation instance in CORBA engine
30   # The engine in turn creates the ParaView pipeline elements
31   params = MEDCALC.MeshViewParameters(proxy.id, meshMode)
32   try:
33     presentation_id = __manager.makeMeshView(params, viewMode)
34     notifyGui_addPresentation(proxy.id, presentation_id)
35     return presentation_id
36   except SALOME.SALOME_Exception as e:
37     notifyGui_error("An error occured while creating the mesh view:\n" + e.details.text)
38     raise Exception(e.details.text)
39
40
41 def MakeScalarMap(proxy,
42                   viewMode=MEDCALC.VIEW_MODE_DEFAULT,
43                   displayedComponent=MEDCALC.DISPLAY_DEFAULT,
44                   scalarBarRange=MEDCALC.SCALAR_BAR_RANGE_DEFAULT,
45                   colorMap=MEDCALC.COLOR_MAP_DEFAULT
46                   ):
47   # Create the presentation instance in CORBA engine
48   # The engine in turn creates the ParaView pipeline elements
49   params = MEDCALC.ScalarMapParameters(proxy.id, displayedComponent, scalarBarRange, colorMap)
50   try:
51     presentation_id = __manager.makeScalarMap(params, viewMode)
52     notifyGui_addPresentation(proxy.id, presentation_id)
53     return presentation_id
54   except SALOME.SALOME_Exception as e:
55     notifyGui_error("An error occured while creating the scalar map:\n" + e.details.text)
56     raise Exception(e.details.text)
57
58 def MakeContour(proxy,
59                 viewMode=MEDCALC.VIEW_MODE_DEFAULT,
60                 scalarBarRange=MEDCALC.SCALAR_BAR_RANGE_DEFAULT,
61                 colorMap=MEDCALC.COLOR_MAP_DEFAULT,
62                 nbContours=MEDCALC.NB_CONTOURS_DEFAULT
63                 ):
64   params = MEDCALC.ContourParameters(proxy.id, scalarBarRange, colorMap, nbContours)
65   try:
66     presentation_id = __manager.makeContour(params, viewMode)
67     notifyGui_addPresentation(proxy.id, presentation_id)
68     return presentation_id
69   except SALOME.SALOME_Exception as e:
70     notifyGui_error("An error occured while creating the contour:\n" + e.details.text)
71     raise Exception(e.details.text)
72
73 #
74
75 def MakeVectorField(proxy,
76                   viewMode=MEDCALC.VIEW_MODE_DEFAULT,
77                   displayedComponent=MEDCALC.DISPLAY_DEFAULT,
78                   scalarBarRange=MEDCALC.SCALAR_BAR_RANGE_DEFAULT,
79                   colorMap=MEDCALC.COLOR_MAP_DEFAULT
80                   ):
81   # Create the presentation instance in CORBA engine
82   # The engine in turn creates the ParaView pipeline elements
83   params = MEDCALC.VectorFieldParameters(proxy.id, displayedComponent, scalarBarRange, colorMap)
84   try:
85     presentation_id = __manager.makeVectorField(params, viewMode)
86     notifyGui_addPresentation(proxy.id, presentation_id)
87     return presentation_id
88   except SALOME.SALOME_Exception as e:
89     notifyGui_error("An error occured while creating the vector field:\n" + e.details.text)
90     raise Exception(e.details.text)
91
92 def MakeSlices(proxy,
93                 viewMode=MEDCALC.VIEW_MODE_DEFAULT,
94                 displayedComponent=MEDCALC.DISPLAY_DEFAULT,
95                 scalarBarRange=MEDCALC.SCALAR_BAR_RANGE_DEFAULT,
96                 colorMap=MEDCALC.COLOR_MAP_DEFAULT,
97                 sliceOrientation=MEDCALC.SLICE_ORIENTATION_DEFAULT,
98                 nbSlices=MEDCALC.NB_SLICES_DEFAULT):
99   # Create the presentation instance in CORBA engine
100   # The engine in turn creates the ParaView pipeline elements
101   params = MEDCALC.SlicesParameters(proxy.id, displayedComponent,scalarBarRange, colorMap, 
102                                     sliceOrientation, nbSlices)
103   try:
104     presentation_id = __manager.makeSlices(params, viewMode)
105     notifyGui_addPresentation(proxy.id, presentation_id)
106     return presentation_id
107   except SALOME.SALOME_Exception as e:
108     notifyGui_error("An error occured while creating the slices:\n" + e.details.text)
109     raise Exception(e.details.text)
110 ##
111 #
112 #def MakeDeflectionShape(proxy,
113 #                        viewMode=MEDCALC.VIEW_MODE_DEFAULT
114 #                        ):
115 #  params = MEDCALC.DeflectionShapeParameters(proxy.id, viewMode)
116 #  presentation_id = __manager.makeDeflectionShape(params)
117 #  notifyGui_addPresentation(proxy.id, presentation_id)
118 #  return presentation_id
119 ##
120 #
121 def MakePointSprite(proxy,
122                   viewMode=MEDCALC.VIEW_MODE_DEFAULT,
123                   displayedComponent=MEDCALC.DISPLAY_DEFAULT,
124                   scalarBarRange=MEDCALC.SCALAR_BAR_RANGE_DEFAULT,
125                   colorMap=MEDCALC.COLOR_MAP_DEFAULT
126                   ):
127   # Create the presentation instance in CORBA engine
128   # The engine in turn creates the ParaView pipeline elements
129   params = MEDCALC.PointSpriteParameters(proxy.id, displayedComponent, scalarBarRange, colorMap)
130   try:
131     presentation_id = __manager.makePointSprite(params, viewMode)
132     notifyGui_addPresentation(proxy.id, presentation_id)
133     return presentation_id
134   except SALOME.SALOME_Exception as e:
135     notifyGui_error("An error occured while creating the point sprite:\n" + e.details.text)
136     raise Exception(e.details.text)
137
138 def RemovePresentation(presentation_id):
139   ok = __manager.removePresentation(presentation_id)
140   if ok:
141     notifyGui_removePresentation(presentation_id)
142 #
143
144 def __GetGENERICParameters(tag, presentation_id):
145   exec "params = __manager.get%sParameters(presentation_id)" % tag
146   return params
147
148 GetMeshViewParameters = lambda pres_id: __GetGENERICParameters("MeshView", pres_id)
149 GetScalarMapParameters = lambda pres_id: __GetGENERICParameters("ScalarMap", pres_id)
150 GetContourParameters = lambda pres_id: __GetGENERICParameters("Contour", pres_id)
151 GetSlicesParameters = lambda pres_id: __GetGENERICParameters("Slices", pres_id)
152 GetPointSpriteParameters = lambda pres_id: __GetGENERICParameters("PointSprite", pres_id)
153 GetVectorFieldParameters = lambda pres_id: __GetGENERICParameters("VectorField", pres_id)
154 #GetDeflectionShapeParameters = lambda pres_id: __GetGENERICParameters("DeflectionShape", pres_id)
155
156
157 def __UpdateGENERIC(tag, presentation_id, params):
158   exec "__manager.update%s(presentation_id, params)" % tag
159   notifyGui_modifyPresentation(presentation_id)
160
161 UpdateMeshView = lambda pres_id, params: __UpdateGENERIC("MeshView", pres_id, params)
162 UpdateScalarMap = lambda pres_id, params: __UpdateGENERIC("ScalarMap", pres_id, params)
163 UpdateContour = lambda pres_id, params: __UpdateGENERIC("Contour", pres_id, params)
164 UpdateSlices = lambda pres_id, params: __UpdateGENERIC("Slices", pres_id, params)
165 UpdateVectorField = lambda pres_id, params: __UpdateGENERIC("VectorField", pres_id, params)
166 UpdatePointSprite = lambda pres_id, params: __UpdateGENERIC("PointSprite", pres_id, params)
167 #UpdateDeflectionShape = lambda pres_id, params: __UpdateGENERIC("DeflectionShape", pres_id, params)
168
169 def ComputeCellAverageSize(obj):
170   """
171   @return the average cell size
172   """
173   bb, nCells = obj.GetDataInformation().GetBounds(), obj.GetDataInformation().GetNumberOfCells()
174   bb = zip(bb[::2], bb[1::2])
175   deltas = [x[1]-x[0] for x in bb]
176   vol = reduce(lambda x,y:x*y, deltas, 1.0) 
177   cellSize = (vol/nCells)**(1.0/3.0)  # necessarily 3D in ParaView
178   return cellSize
179
180 def GetDomainCenter(obj):
181   """
182   @return the center of the domain as the central point of the bounding box
183   """
184   bb = obj.GetDataInformation().GetBounds()
185   bb = zip(bb[::2], bb[1::2])
186   mids = [x[0] + 0.5*(x[1]-x[0]) for x in bb]
187   return mids
188
189 # Taken from paraview.simple from CEA ParaView's version:
190 def SetDefaultScaleFactor(active=None):
191     """Provides a good display to the bounding box of the mesh and min / max of the field.
192     This method available for filters: Warp By Vector, Glyph and Tensor Glyph"""
193     if not active:
194         active = GetActiveSource()
195     if not active:
196         return
197     name = active.__class__.__name__
198     if (name == 'WarpByVector'  or name == 'TensorGlyph') and hasattr(active, 'ScaleFactor'):
199       import math
200       datainfo = active.GetProperty("Input").SMProperty.GetProxy(0).GetDataInformation()
201       if not datainfo:
202           active.ScaleFactor = 1.0
203           return
204       nbcells = datainfo.GetNumberOfCells()
205       nbpoints = datainfo.GetNumberOfPoints()
206       nbelem = nbcells
207       if nbelem == 0:
208           nbelem = nbpoints
209       abounds = datainfo.GetBounds()
210       volume = 1
211       vol = 0
212       idim = 0
213       i = 0
214       eps = 1.0e-38
215       while i < 6 :
216           vol = math.fabs( abounds[i+1] - abounds[i] )
217           if vol > 0:
218             idim += 1
219             volume *= vol
220           i += 2
221       if nbelem == 0 or math.fabs(idim) < eps:
222           active.ScaleFactor = 0.0
223           return
224       volume /= nbelem
225       scalefactor = pow( volume, 1.0 / idim )
226       maximum = 1.0
227       property = active.GetProperty('ScaleFactor')
228       domain = None
229       if property.GetDomain('vector_range').__class__.__name__ == 'vtkSMArrayRangeDomain':
230           domain = property.GetDomain('vector_range')
231       if property.GetDomain('tensor_range').__class__.__name__ == 'vtkSMArrayRangeDomain':
232           domain = property.GetDomain('tensor_range')
233       if not domain is None:
234           if domain.GetMaximumExists(3):
235             maximum = domain.GetMaximum(3)
236       if math.fabs(maximum) > eps:
237           scalefactor /= maximum
238       active.ScaleFactor = scalefactor
239       return
240     if name == 'Glyph' and hasattr(active, 'ScaleFactor') and hasattr(active, 'UseCellsCenter') and hasattr(active, 'ScaleMode'):
241       import math
242       scaledextent = 1.0
243       property = active.GetProperty('ScaleFactor')
244       bounds_domain = property.GetDomain('bounds')
245       if bounds_domain.__class__.__name__ == 'vtkSMBoundsDomain':
246           if bounds_domain.GetMaximumExists(0):
247             scaledextent = bounds_domain.GetMaximum(0)
248       usecellscenter = active.GetProperty('UseCellsCenter').GetData()
249       sdomain = "cells_"
250       if usecellscenter == 0:
251           sdomain = "points_"
252       divisor = 1.0
253       scalemode_domain = active.GetProperty('ScaleMode')
254       scalemode = scalemode_domain.ConvertValue(scalemode_domain.GetData())
255       if scalemode == 0:
256           sdomain += "scalar_range"
257           domain = property.GetDomain(sdomain)
258           if domain.__class__.__name__ == 'vtkSMArrayRangeDomain':
259             if domain.GetMaximumExists(0):
260                 divisor = domain.GetMaximum(0)
261       if scalemode == 1 or scalemode == 2:
262           sdomain += "vector_range"
263           domain = property.GetDomain(sdomain)
264           if domain.__class__.__name__ == 'vtkSMArrayRangeDomain':
265             if domain.GetMaximumExists(3):
266                 divisor = domain.GetMaximum(3)
267       divisor = math.fabs(divisor)
268       if divisor < 0.000000001:
269           divisor = 1
270       scalefactor = scaledextent / divisor 
271       active.ScaleFactor = scalefactor
272       return
273
274 def GetSliceOrigins(obj, nbSlices, normal):
275   """
276   Compute all origin points for the position of the slices.
277   @param normal is a list of 3 floats either 0 or 1 indicating the normal vector of the slices
278   """
279   from math import sqrt
280   bb = obj.GetDataInformation().GetBounds()
281   bb = zip(bb[::2], bb[1::2])
282   origin = [x[0] + 0.5*(x[1]-x[0]) for x in bb]
283   deltas = [x[1]-x[0] for x in bb]
284   # Compute extent of slices:
285   l = [normal[i]*deltas[i]**2 for i in range(3)]   # either the X extend, or the XY diagonal, or the XYZ diagonal
286   plus = lambda x,y: x+y
287   extent = sqrt(reduce(plus, l, 0.0))
288   norm = sqrt(reduce(plus, normal, 0.0))
289   normal = [normal[i]/norm for i in range(3)]
290   origins = []
291   step = extent/nbSlices
292   for j in range(nbSlices):
293     orig_j = [origin[i]+normal[i]*(-0.5*extent + step*(0.5+j)) for i in range(3)]
294     origins.append(orig_j)
295   return origins
296