-
Notifications
You must be signed in to change notification settings - Fork 1
/
saveNormalSlice.py
executable file
·340 lines (280 loc) · 12.7 KB
/
saveNormalSlice.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
from __future__ import print_function
# script written by Regis Thedin
import os
import sys
import glob
import argparse
from paraview.simple import *
# disable automatic camera reset on 'Show'
paraview.simple._DisableFirstRenderCameraReset()
# ------------------------------------------------------------------------------
# -------------------------------- PARSING INPUTS ------------------------------
# ------------------------------------------------------------------------------
parser = argparse.ArgumentParser()
parser.add_argument("--case", "-c", type=str, default=os.getcwd(), help="case full path (default cwd)")
parser.add_argument("--var", "-var", type=str, default="U", help="variable (e.g. U, T, UMean)")
parser.add_argument("--comp", "-comp", type=str, default="mag", help="variable (X, Y, Z, mag only)")
parser.add_argument("--normal", "-normal", type=float,default=80, help="position of the slice (e.g. 1000 for xNormal.1000, 80 for zNormal.80")
parser.add_argument("--firstFrame", "-ff", type=int, default=0, help="first frame to be saved")
parser.add_argument("--lastFrame", "-lf", type=int, default=9999, help="last frame to be saved (blank for all available)")
parser.add_argument("--sType", "-slice", type=str, default="zNormal", help="slice type (e.g. zNormal, yNormal, terrain)")
parser.add_argument("--t0", "-t0", type=int, default=999 , help="time shift for label")
parser.add_argument("--timescale", "-tscale",type=int, default=999, help="time scale for label")
parser.add_argument("--scaleL", "-lb", type=float, default=-99, help="scale lower bound")
parser.add_argument("--scaleU", "-ub", type=float, default=99, help="scale upper bound")
args = parser.parse_args()
# Parse inputs
case = args.case
var = args.var
comp = args.comp.upper()
normal = int(args.normal)
anim_fstart = args.firstFrame
anim_fend = args.lastFrame
slicetype = args.sType
t0 = args.t0
timescale = args.timescale
scalelowerbound = args.scaleL
scaleupperbound = args.scaleU
if not os.path.exists(case):
parser.error("Path does not exist")
# ------------------------------------------------------------------------------
# ----------------------------- ANIMATION PARAMETERS ---------------------------
# ------------------------------------------------------------------------------
# Example call:
# pvbatch --mesa thisscript.py --c '/home/rthedin/OpenFOAM/rthedin-6/run/gravityWaves/26_bigUnifU_stable_z15_RLup5'
# -var U
# -comp Z
# -slice xNormal
# -normal 80
# -lb -1
# -ub 1
# -t0 20000
# -ff 32
# -lf 40
# View parameters
renderViewSize = [900, 700]
# Output images parameters
ratio = 1100/600. # 1100 x 600px is a good ratio for streamwise slices or non-square-ish domain
ratio = 800/600. # 800 x 600px is a good ratio
horiz_resolution = 1100
output_resolution = [horiz_resolution, int(horiz_resolution/ratio)]
# ------------------------------------------------------------------------------
# --------------------- END OF USER-MODIFIABLE PARAMETERS ----------------------
# ------------------------------------------------------------------------------
# Some simple changes for robustness
if var == 'u' or var=='vel':
var='U'
if comp == 'MAG' or comp=='MAGNITUDE':
comp='Magnitude'
# Scale for colobar appropriately if no values were given
if var[0]=='U':
scaleleg = 'U {comp} (m/s)'.format(comp=comp)
if scalelowerbound==-99 or scaleupperbound==99:
if comp=='Magnitude' or comp=='X':
scalelowerbound = 2
scaleupperbound = 12
elif comp=='Y' or comp=='Z':
scalelowerbound = -3.0
scaleupperbound = 3.0
elif var[0]=='T':
scaleleg = 'T (K)'
if scalelowerbound==-99 or scaleupperbound==99:
scalelowerbound = 300
scaleupperbound = 320
else:
scaleleg=var
if scalelowerbound==-99 or scaleupperbound==99:
print('\n\nWARNING: Specify lower and upper limits of the scale.\n\n')
# Get list of VTKs
files1 = glob.glob('{case}/sequencedVTK/{var}_{stype}.{h}.*'.format(case=case, var=var, stype=slicetype, h=str(normal).replace('-','m') ));
files1.sort();
# set last frame of animation
if anim_fend==0 or anim_fend>=9999:
anim_fend = len(files1)
# identify first slice to set the appropriate time shift in label
if t0 == 999:
try:
fullpath = os.path.realpath(os.path.abspath(files1[0]))
except IndexError:
print('Error: You might be requesting slices that are not available, or foamSequenceVTKFiles has not been executed.\n\n')
t0 = int(os.path.basename(os.path.dirname(fullpath)))
# set scale of the time label (one slice represents 100s, 500s, etc). Assumes uniform sampling
if timescale == 999:
fullpath0 = os.path.realpath(os.path.abspath(files1[0]))
t0 = int(os.path.basename(os.path.dirname(fullpath0)))
fullpath1 = os.path.realpath(os.path.abspath(files1[1]))
t1 = int(os.path.basename(os.path.dirname(fullpath1)))
timescale = t1-t0
# set output path
if not os.path.exists('{case}/animation'.format(case=case)):
os.makedirs('{case}/animation'.format(case=case))
anim_outpath = '{case}/animation/{stype}_{h}m_{var}_{comp}.png'.format(case=case, stype=slicetype, h=str(normal).replace('-','m'), var=var, comp=comp)
# Print information
print('---------------- CASE PARAMETERS ----------------')
print('- case:', case)
print('- variable:', var)
print('- component:', comp)
print('- slice type:',slicetype)
print('- normal:', normal)
print('- time shift:', t0)
print('- time scale:', timescale)
print('- scale upper bound:', scaleupperbound)
print('- scale lower bound:', scalelowerbound)
print('- first frame:', anim_fstart)
print('- last frame:', anim_fend)
print(' ')
#print(f"Reading {var}_{slicetype}.{str(normal).replace('-','m')}.{anim_fstart}..{anim_fend}.vtk")
print('Reading {var}_{stype}.{normal}.{{{i}..{f}}}.vtk'.format(var=var, stype=slicetype, normal=str(normal).replace('-','m'), i=anim_fstart, f=anim_fend))
print('Number of available VTKs:', len(files1))
print('Animation will be saved as', anim_outpath)
print(' ')
# ------------------------------------------------------------------------------
# --------------------------------- FIRST PANEL --------------------------------
# ------------------------------------------------------------------------------
# ---------------------------------------------------------------- LOAD THE DATA
# create a new 'Legacy VTK Reader'
slices = LegacyVTKReader(FileNames=files1)
# --------------------------------------------------------------- ANIMATION SETUP
# get animation scene
animationScene1 = GetAnimationScene()
# update animation scene based on data timesteps
animationScene1.UpdateAnimationUsingDataTimeSteps()
# Set palette
LoadPalette(paletteName='WhiteBackground')
# --------------------------------------------------------------------- HIT OK
# get active view
renderView1 = GetActiveViewOrCreate('RenderView')
# uncomment following to set a specific view size
renderView1.ViewSize = renderViewSize
# get layout
layout1 = GetLayout()
# show data in view
slicesDisplay = Show(slices, renderView1)
# trace defaults for the display properties.
slicesDisplay.Representation = 'Surface'
slicesDisplay.ColorArrayName = [None, '']
slicesDisplay.OSPRayScaleArray = var
slicesDisplay.OSPRayScaleFunction = 'PiecewiseFunction'
slicesDisplay.SelectOrientationVectors = 'None'
slicesDisplay.ScaleFactor = 3072.0
slicesDisplay.SelectScaleArray = 'None'
slicesDisplay.GlyphType = 'Arrow'
slicesDisplay.GlyphTableIndexArray = 'None'
slicesDisplay.GaussianRadius = 153.6
slicesDisplay.SetScaleArray = ['POINTS', var]
slicesDisplay.ScaleTransferFunction = 'PiecewiseFunction'
slicesDisplay.OpacityArray = ['POINTS', var]
slicesDisplay.OpacityTransferFunction = 'PiecewiseFunction'
slicesDisplay.DataAxesGrid = 'GridAxesRepresentation'
slicesDisplay.SelectionCellLabelFontFile = ''
slicesDisplay.SelectionPointLabelFontFile = ''
slicesDisplay.PolarAxes = 'PolarAxesRepresentation'
# get the material library
materialLibrary1 = GetMaterialLibrary()
# ----------------------------------------------------------- SELECT VARIABLE
if var[0]=='U':
# set scalar coloring
ColorBy(slicesDisplay, ('POINTS', var, comp))
else:
ColorBy(slicesDisplay, ('POINTS', var))
# get color transfer function/color map for 'U'/'T'/'UMean'/...
uLUT = GetColorTransferFunction(var)
uLUT.RGBPoints = [6.088017156980581, 0.231373, 0.298039, 0.752941, 8.98210526138447, 0.865003, 0.865003, 0.865003, 11.876193365788358, 0.705882, 0.0156863, 0.14902]
uLUT.ScalarRangeInitialized = 1.0
# Apply a preset using its name. Note this may not work as expected when presets have duplicate names.
if scalelowerbound+scaleupperbound != 0:
uLUT.ApplyPreset('Viridis (matplotlib)', True)
# get opacity transfer function/opacity map for 'U'/'T'/'UMean'/...
uPWF = GetOpacityTransferFunction(var)
uPWF.Points = [6.088017156980581, 0.0, 0.5, 0.0, 11.876193365788358, 1.0, 0.5, 0.0]
uPWF.ScalarRangeInitialized = 1
# --------------------------------------------------------- COLORBAR PROPERTIES
# get color legend/bar for uLUT in view renderView1
uLUTColorBar = GetScalarBar(uLUT, renderView1)
uLUTColorBar.Title = scaleleg
uLUTColorBar.ComponentTitle = ''
uLUTColorBar.TitleColor = [0.0, 0.0, 0.0]
uLUTColorBar.TitleFontFile = ''
uLUTColorBar.LabelColor = [0.0, 0.0, 0.0]
uLUTColorBar.LabelFontFile = ''
# Rescale transfer function
uLUT.RescaleTransferFunction(scalelowerbound, scaleupperbound)
uPWF.RescaleTransferFunction(scalelowerbound, scaleupperbound)
# Properties modified on uLUTColorBar
uLUTColorBar.RangeLabelFormat = '%-#.1f'
# The fonts will be bigger than what I input here.
# This is a known bug in paraview 5.6: https://gitlab.kitware.com/paraview/paraview/-/issues/19831
uLUTColorBar.TitleFontSize = 5
uLUTColorBar.LabelFontSize = 5
uLUTColorBar.ScalarBarThickness = 10
uLUTColorBar.ScalarBarLength = 0.4 # a third of the height
# Update a scalar bar component title.
UpdateScalarBarsComponentTitle(uLUT, slicesDisplay)
slicesDisplay.SetScalarBarVisibility(renderView1, True)
uLUTColorBar.Title = scaleleg
uLUTColorBar.ComponentTitle = ''
# --------------------------------------------------------- CREATE TIME LABEL
# create a new 'Annotate Time Filter'
annotateTimeFilter1 = AnnotateTimeFilter(Input=slices)
# Properties modified on annotateTimeFilter1
annotateTimeFilter1.Format = 'Time: %.1f s'
annotateTimeFilter1.Shift = t0
annotateTimeFilter1.Scale = timescale
# show data in view
annotateTimeFilter1Display = Show(annotateTimeFilter1, renderView1)
# trace defaults for the display properties.
annotateTimeFilter1Display.Color = [0.0, 0.0, 0.0]
annotateTimeFilter1Display.FontFile = ''
annotateTimeFilter1Display.FontSize = 16
# --------------------------------------------------------- CREATE HEIGHT LABEL
# set active source
SetActiveSource(slices)
# create a new 'Text'
text1 = Text()
# Properties modified on text1
text1.Text = '{stype} = {normal} m'.format(stype=slicetype, normal=normal)
# show data in view
text1Display = Show(text1, renderView1)
# trace defaults for the display properties.
text1Display.Color = [0.0, 0.0, 0.0]
text1Display.FontFile = ''
# Properties modified on text1Display
text1Display.FontSize = 16
text1Display.WindowLocation = 'UpperCenter'
# --------------------------------------------------------- VIEW PROPERTIES
# Properties modified on renderView1
renderView1.EnableOSPRay = 1
#renderView1.EnableRayTracing = 1
renderView1.Shadows = 0
renderView1.CameraParallelProjection = 1
renderView1.ProgressivePasses = 2 # needs --enable-streaming-options
renderView1.CameraFocalPoint = [0, 0, 0]
if slicetype[0] == 'x':
renderView1.CameraPosition = [-1, 0, 0]
renderView1.CameraViewUp = [0, 0, 1]
elif slicetype[0] == 'y':
renderView1.CameraPosition = [0, -1, 0]
renderView1.CameraViewUp = [0, 0, 1]
elif slicetype[0] == 'z' or slicetype[0:3]=='ter':
renderView1.CameraPosition = [0, 0, 1]
renderView1.CameraViewUp = [0, 1, 0]
else:
print('This slice may require a custom camera view. Edit the script.')
# View parameters
renderView1.InteractionMode = '2D'
renderView1.ResetCamera()
##########################################################################
############################## SAVE ANIMATION ############################
##########################################################################
print('Saving animation...')
# save animation
SaveAnimation(anim_outpath,
#renderView1,
layout1, SaveAllViews=1,
ImageResolution=output_resolution,
#FontScaling='Do not scale fonts',
SeparatorWidth=1,
SeparatorColor=[0.0, 0.0, 0.0],
#TransparentBackground=1,
FrameWindow=[anim_fstart, anim_fend])
print('Done.')