CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > ParaView

pvbatch script for saving animations modifing each frame

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree2Likes
  • 1 Post By wyldckat
  • 1 Post By Gaetano

Reply
 
LinkBack Thread Tools Display Modes
Old   October 29, 2013, 13:18
Default pvbatch script for saving animations modifing each frame
  #1
New Member
 
Gaetano
Join Date: Jul 2012
Posts: 18
Rep Power: 5
Gaetano is on a distinguished road
Hi all.

I'd like to have your inputs on a problem that is puzzling me from days.

I want to save an animation starting from a series of vtk. Apart from the rendering of a point field, I need a line source to be superimposed. The coordinates of the two points defining the line have to be read from a text file (two points for each vtk).

I managed to create an image sequence, that is to export each single frame of my animation. Now I'd like to have only an .ogv as output of my python script.

I tried something like the script here, but I wasn't successful:

-----------------------------------------------------------
ERROR: In /root/ParaView-v4.0.1-source/ParaViewCore/ClientServerCore/Rendering/vtkPVCameraCueManipulator.cxx, line 94
vtkPVCameraCueManipulator (0x1ed8d550): No camera to animate.

./video3.sh: line 5: 25353 Segmentation fault /share/paraview-4.0.1-MESA/bin/pvbatch --use-offscreen-rendering screen3.py
-----------------------------------------------------------

Of course the error comes from the fact that I'm not animating the camera.

Another hint is here, where the suggestion is to put the rendering instructions into a "Python script to be called on every timestep" using the "Python Animation Cue". Nonetheless I couldn't find any reference/example on internet.

Any suggestion?

PS: the rendering instructions are those I could register using the GUI tracing tool
PPS: I'm using Paraview 4.0.1 with MESA support on a Linux machine
Gaetano is offline   Reply With Quote

Old   October 30, 2013, 06:31
Default Minimal script
  #2
New Member
 
Gaetano
Join Date: Jul 2012
Posts: 18
Rep Power: 5
Gaetano is on a distinguished road
Just to give some more background, here's a minimal version of my script:

Code:
import math
try: paraview.simple
except: from paraview.simple import *
paraview.simple._DisableFirstRenderCameraReset()

# number of frames
frames = 121
# time difference between steps (needed for reconstruct filenames)
step = 0.05

# List containing the x and y coordinates of the two points
pos = [[] for i in range(frames)]
i=0

# Filename containing the coordinates in the following format:
# time x_top y_top x_bottom y_bottom
# 0.12 0.123456 0.123456 0.123456 0.123456
# ...
in_file = open("/home/project/simulation/points.out","r")

# Loop through lines in file
for line in in_file:
   [time,xt,yt,xb,yb] = line.rsplit(' ',5)
   # Store the coordinate in a 2D list
   pos[i] = [float(xt), float(yt), float(xb), float(yb)]
   i = i+1
in_file.close()

for i in range(frames):
   # Read file
   file = "/home/project/simulation/VTK/sim_" + str(int(i*step*1000)) + ".vtk"
   reader = LegacyVTKReader( FileNames=file )

   RenderView1 = GetRenderView()

   Slice1 = Slice( SliceType="Plane" )
   Slice1.SliceOffsetValues = [0.0]
   Slice1.SliceType = "Plane"
   Slice1.SliceType.Origin = [0.0, 0.0, 0.0]
   Slice1.SliceType.Normal = [0.0, 0.0, 1.0]

   DataRepresentation1 = Show()
   DataRepresentation1.ScaleFactor = 0.05
   DataRepresentation1.SelectionPointFieldDataArrayName = 'U'
   DataRepresentation1.EdgeColor = [0.0, 0.0, 0.5]
   a1_U_PVLookupTable = GetLookupTableForArray( "U", 3, RGBPoints=[0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0], VectorMode='Magnitude', NanColor=[0.5, 0.5, 0.5], ColorSpace='HSV', ScalarRangeInitialized=1.0, LockScalarRange=1 )
   a1_U_PiecewiseFunction = CreatePiecewiseFunction( Points=[0.0, 0.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0] )
   DataRepresentation1.ColorArrayName = 'U'
   DataRepresentation1.LookupTable = a1_U_PVLookupTable

   Line1 = Line()
   Line1.Point1 = [ pos[i][0], pos[i][1], 0.0]
   Line1.Point2 = [ pos[i][2], pos[i][3], 0.0]

   DataRepresentation2 = Show()
   DataRepresentation2.ScaleFactor = 0.02
   DataRepresentation2.SelectionPointFieldDataArrayName = 'Texture Coordinates'
   DataRepresentation2.EdgeColor = [0.0, 0.0, 0.5]
   DataRepresentation2.LineWidth = 3.0

   RenderView1.ResetCamera()
   RenderView1.CenterAxesVisibility = 0
   RenderView1.OrientationAxesVisibility = 1
   RenderView1.ViewSize = [ 2400, 2400 ]

   ScalarBarWidgetRepresentation1 = CreateScalarBar( ComponentTitle='', Title='U', Enabled=1, LabelFontSize=12, LookupTable=a1_U_PVLookupTable, TitleFontSize=12, Position=[0.9, 0.25] )
   GetRenderView().Representations.append(ScalarBarWidgetRepresentation1)

   WriteImage('/home/project/frames/video' + str(int(i*step*1000)) + '.png')

   # Memory saving?
   Delete(reader)
   Delete(Slice1)
   Delete(Threshold1)
   Delete(Contour1)
   Delete(Line1)
It basically built each frame from scratch and save it as png. I know that it looks horrible, but I'm a beginner in both python programming and paraview scripting.

Is there a way to save an .ogv starting from those frames?

Any comments on the script are extremely welcome!
Gaetano is offline   Reply With Quote

Old   November 2, 2013, 17:09
Default
  #3
Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 8,301
Blog Entries: 34
Rep Power: 84
wyldckat is just really nicewyldckat is just really nicewyldckat is just really nicewyldckat is just really nice
Greetings Gaetano,

Wow, that's some heavy duty coding you want to perform! And for pvbatch, to top it off!

Personally, I prefer to use GUI first for testing. And ParaView has got a marvellous feature in the "Tools" menu, namely "Start/Stop Trace". This allows us to register most of the commands we executed graphically and when we stop tracing, we get a script which most of the times gives a good code to start with. Problem is when it doesn't give us all of the code we need

But in this case, I did a quick test, and the following pearls of wisdom it gave me were (with ParaView 3.12.0):
  1. We can load a timeline of VTK files with something like this:
    Code:
    cavity_ = LegacyVTKReader( FileNames=['/home/user/mycase/cavity_0.vtk', '/home/user/mycase/cavity_20.vtk', '/home/user/mycase/cavity_40.vtk', '/home/user/mycase/cavity_60.vtk', '/home/user/mycase/cavity_80.vtk', '/home/user/mycase/cavity_100.vtk'] )
  2. We can switch to another time frame by using this code:
    Code:
    AnimationScene1 = GetAnimationScene()
    AnimationScene1.EndTime = 5.0
    AnimationScene1.PlayMode = 'Snap To TimeSteps'
    AnimationScene1.AnimationTime = 2.0
    
    RenderView1 = GetRenderView()
    RenderView1.ViewTime = 2.0
    where 2.0 is the frame (time) I wanted. It will load up the respective data from the VTK file automatically.
  3. The embedded code to be executed on each time frame is done like this:
    Code:
    PythonAnimationCue1 = PythonAnimationCue( Script='def start_cue(self): pass\n\ndef tick(self): pass\n\nprint(self)\n\ndef end_cue(self): pass' )
As for coding the cue code, the best I can provide is the example I wrote some time ago here: Annoying issue of automatic "Rescale to Data Range " with paraFoam/paraview 3.12 post #6.


As for saving to OGV... on ParaView 4.0.1 I got this from the Python trace feature:
Quote:
WriteAnimation('/home/user/mycase/test.ogv', Magnification=1, Quality=2, FrameRate=15.000000)
Best regards,
Bruno
Nucleophobe likes this.
wyldckat is offline   Reply With Quote

Old   November 4, 2013, 13:08
Thumbs up
  #4
New Member
 
Gaetano
Join Date: Jul 2012
Posts: 18
Rep Power: 5
Gaetano is on a distinguished road
Quote:
Originally Posted by wyldckat View Post
Personally, I prefer to use GUI first for testing. And ParaView has got a marvellous feature in the "Tools" menu, namely "Start/Stop Trace".
I know: all the code above was a modification of the output of the trace tool (first Post Scriptum in my first message).

Quote:
We can switch to another time frame by using this code:
Code:
AnimationScene1 = GetAnimationScene()
AnimationScene1.EndTime = 5.0
AnimationScene1.PlayMode = 'Snap To TimeSteps'
AnimationScene1.AnimationTime = 2.0

RenderView1 = GetRenderView()
RenderView1.ViewTime = 2.0
where 2.0 is the frame (time) I wanted. It will load up the respective data from the VTK file automatically.
Here's how to move between frames, at least! But actually the definitive hint is:

Quote:
The embedded code to be executed on each time frame is done like this:
Code:
PythonAnimationCue1 = PythonAnimationCue( Script='def start_cue(self): pass\n\ndef tick(self): pass\n\nprint(self)\n\ndef end_cue(self): pass' )
Eventually, I managed to create the video I wanted. I used also the minimal script I found here: it told me how to use that "PythonAnimationCue".

For future reference (and my 2 cents for the community), here's how I did it:

Code:
try: paraview.simple
except: from paraview.simple import *
paraview.simple._DisableFirstRenderCameraReset()

# number of frames
frames = 121
# time difference between steps (needed for reconstruct filenames)
step = 0.05

AnimationScene1 = GetAnimationScene()
AnimationScene1.EndTime = frames-1
AnimationScene1.PlayMode = 'Snap To TimeSteps'

RenderView1 = GetRenderView()


# List containing the x and y coordinates of the two points
pos = [[] for i in range(frames)]

# Filename containing the coordinates in the following format:
# time x_top y_top x_bottom y_bottom
# 0.12 0.123456 0.123456 0.123456 0.123456
# ...
in_file = open("/home/project/simulation/points.out","r")

# Loop through lines in file
i=0
for line in in_file:
   [time,xt,yt,xb,yb] = line.rsplit(' ',5)
   # Store the coordinate in a 2D list
   pos[i] = [float(xt), float(yt), float(xb), float(yb)]
   i = i+1
in_file.close()

for i in range(frames):
   # Read file
   file = "/home/project/simulation/VTK/sim_" + str(int(i*step*1000)) + ".vtk"
   files.append(file)

reader = LegacyVTKReader( FileNames=files )

Slice1 = Slice( SliceType="Plane" )
Slice1.SliceOffsetValues = [0.0]
Slice1.SliceType = "Plane"
Slice1.SliceType.Origin = [0.0, 0.0, 0.0]
Slice1.SliceType.Normal = [0.0, 0.0, 1.0]

DataRepresentation1 = Show()
DataRepresentation1.ScaleFactor = 0.05
DataRepresentation1.SelectionPointFieldDataArrayName = 'U'
DataRepresentation1.EdgeColor = [0.0, 0.0, 0.5]
a1_U_PVLookupTable = GetLookupTableForArray( "U", 3, RGBPoints=[0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0], VectorMode='Magnitude', NanColor=[0.5, 0.5, 0.5], ColorSpace='HSV', ScalarRangeInitialized=1.0, LockScalarRange=1 )
a1_U_PiecewiseFunction = CreatePiecewiseFunction( Points=[0.0, 0.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0] )
DataRepresentation1.ColorArrayName = 'U'
DataRepresentation1.LookupTable = a1_U_PVLookupTable

Line1 = Line()

RenderView1.ResetCamera()

ScalarBarWidgetRepresentation1 = CreateScalarBar( ComponentTitle='', Title='U', Enabled=1, LabelFontSize=12, LookupTable=a1_U_PVLookupTable, TitleFontSize=12, Position=[0.9, 0.25] )
GetRenderView().Representations.append(ScalarBarWidgetRepresentation1)

PythonAnimationCue1 = PythonAnimationCue()
PythonAnimationCue1.Script= """
def start_cue(self): pass

def tick(self):

   i = int(GetAnimationScene().TimeKeeper.Time)

   RenderView1.ViewTime = i
   AnimationScene1.AnimationTime = i

   Line1 = FindSource("Line1")

   Line1.UpdatePipeline(GetAnimationScene().TimeKeeper.Time)

   Line1.Point1 = [ pos[i][0], pos[i][1], 0.0]
   Line1.Point2 = [ pos[i][2], pos[i][3], 0.0]

   DataRepresentation2 = Show()
   DataRepresentation2.ScaleFactor = 0.02
   DataRepresentation2.SelectionPointFieldDataArrayName = 'Texture Coordinates'
   DataRepresentation2.EdgeColor = [0.0, 0.0, 0.5]
   DataRepresentation2.LineWidth = 3.0

def end_cue(self): pass
"""

AnimationScene1.Cues.append(PythonAnimationCue1)

RenderView1.CenterAxesVisibility = 0
RenderView1.OrientationAxesVisibility = 1
RenderView1.ViewSize = [ 2400, 2400 ]

WriteAnimation('/home/project/frames/video.ogv', Magnification=1, Quality=2, FrameRate=8.0)
Thanks Bruno: you really made my day!

Regards,
Gaetano
wyldckat likes this.
Gaetano is offline   Reply With Quote

Old   January 30, 2014, 06:42
Default
  #5
New Member
 
Gaetano
Join Date: Jul 2012
Posts: 18
Rep Power: 5
Gaetano is on a distinguished road
Errata corrige: my script seems to put the line at the previous instant into the current instant photogram. There is still something wrong, so be careful if you're going to use it.

Regards,
Gaetano
Gaetano is offline   Reply With Quote

Reply

Tags
animation, frame, pvbatch, python

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -4. The time now is 19:08.