1
2 """
3 Class that implements pyFoamPVSnapshot
4 """
5
6 from optparse import OptionGroup
7
8 from PyFoamApplication import PyFoamApplication
9
10 from CommonSelectTimesteps import CommonSelectTimesteps
11
12 from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory
13 from PyFoam.Paraview.ServermanagerWrapper import ServermanagerWrapper as SM
14 from PyFoam.Paraview.StateFile import StateFile
15 from PyFoam.Paraview import version as PVVersion
16
17 from PyFoam.FoamInformation import foamVersion
18
19 from os import path,unlink
20 import sys,string
21
22 -class PVSnapshot(PyFoamApplication,
23 CommonSelectTimesteps ):
25 description="""
26 Generates snapshots of an OpenFOAM-case and a predefined paraview-State-File
27 using the PV3FoamReader that comes with OpenFOAM.
28
29 The state-file can be generated using a different case (the script adjusts
30 it before using) but the original case has to have a similar structure to the
31 current one. Also exactly one PV3Reader has to be used in the state-file (this
32 requirement is fullfilled if the StateFile was generated using paraFoam)
33
34 In TextSources the string "%(casename)s" gets replaced by the casename. Additional
35 replacements can be specified
36 """
37 CommonSelectTimesteps.__init__(self)
38
39 PyFoamApplication.__init__(self,
40 args=args,
41 description=description,
42 usage="%prog [options] <case>",
43 interspersed=True,
44 nr=1)
45
46 typeTable={"png":"vtkPNGWriter",
47 "jpg":"vtkJPEGWriter"}
48
50 CommonSelectTimesteps.addOptions(self,defaultUnique=False)
51
52 paraview=OptionGroup(self.parser,
53 "Paraview specifications",
54 "Options concerning paraview")
55 paraview.add_option("--state-file",
56 dest="state",
57 default=None,
58 help="The pvsm-file that should be used. If none is specified the file 'default.pvsm' in the case-directory is used")
59 paraview.add_option("--maginfication",
60 dest="magnification",
61 default=1,
62 type="int",
63 help="Magnification factor of the picture (integer). Default: %default")
64 paraview.add_option("--type",
65 dest="type",
66 type="choice",
67 choices=self.typeTable.keys(),
68 default="png",
69 help="The type of the bitmap-file. Possibilities are "+string.join(self.typeTable.keys(),", ")+". Default: %default")
70 paraview.add_option("--no-progress",
71 dest="progress",
72 action="store_false",
73 default=True,
74 help="Paraview will not print the progress of the filters")
75 self.parser.add_option_group(paraview)
76
77 filename=OptionGroup(self.parser,
78 "Filename specifications",
79 "The names of the resulting files")
80 filename.add_option("--file-prefix",
81 dest="prefix",
82 default="Snapshot",
83 help="Start of the filename for the bitmap-files")
84 filename.add_option("--no-casename",
85 dest="casename",
86 action="store_false",
87 default=True,
88 help="Do not add the casename to the filename")
89 filename.add_option("--no-timename",
90 dest="timename",
91 action="store_false",
92 default=True,
93 help="Do not append the string 't=<time>' to the filename")
94 self.parser.add_option_group(filename)
95
96 replace=OptionGroup(self.parser,
97 "Replacements etc",
98 "Manipuations of the statefile")
99 replace.add_option("--replacements",
100 dest="replacements",
101 default="{}",
102 help="Dictionary with replacement strings. Default: %default")
103 replace.add_option("--casename-key",
104 dest="casenameKey",
105 default="casename",
106 help="Key with which the caename should be replaced. Default: %default")
107
109 if foamVersion()>=(1,6):
110 self.warning("This utilitiy currently does not work with OF>=1.6 because the API in Paraview>=3.6 has changed. But we'll try")
111
112 case=path.abspath(self.parser.getArgs()[0])
113 short=path.basename(case)
114
115 if self.opts.state==None:
116 self.opts.state=path.join(case,"default.pvsm")
117
118 if not path.exists(self.opts.state):
119 self.error("The state file",self.opts.state,"does not exist")
120
121 timeString=""
122
123 if self.opts.casename:
124 timeString+="_"+short
125 timeString+="_%(nr)05d"
126 if self.opts.timename:
127 timeString+="_t=%(t)s"
128 timeString+="."+self.opts.type
129
130 sol=SolutionDirectory(case,paraviewLink=False,archive=None)
131 times=self.processTimestepOptions(sol)
132 if len(times)<1:
133 self.warning("Can't continue without time-steps")
134 return
135
136 dataFile=path.join(case,short+".OpenFOAM")
137 createdDataFile=False
138 if not path.exists(dataFile):
139 createdDataFile=True
140 f=open(dataFile,"w")
141 f.close()
142
143 sf=StateFile(self.opts.state)
144 sf.setCase(dataFile)
145
146 values=eval(self.opts.replacements)
147 values[self.opts.casenameKey]=short
148 sf.rewriteTexts(values)
149 newState=sf.writeTemp()
150
151 sm=SM(requiredReader=sf.readerType())
152 if not self.opts.progress:
153 sm.ToggleProgressPrinting()
154
155
156 sm.LoadState(newState)
157 views=sm.GetRenderViews()
158
159 if len(views)>1:
160 self.warning("More than 1 view in state-file. Generating multiple series")
161 timeString="_View%(view)02d"+timeString
162 timeString=self.opts.prefix+timeString
163
164 for view in views:
165 view.UseOffscreenRenderingForScreenshots=True
166
167 for i,t in enumerate(times):
168 print "Snapshot ",i," for t=",t
169 for j,view in enumerate(views):
170 view.ViewTime=float(t)
171 fn = timeString % {'nr':i,'t':t,'view':j}
172 if PVVersion()<(3,6):
173 view.WriteImage(fn,
174 self.typeTable[self.opts.type],
175 self.opts.magnification)
176 else:
177 from paraview.simple import SetActiveView,Render,WriteImage
178 SetActiveView(view)
179 Render()
180
181 WriteImage(fn,
182 view,
183
184 Magnification=self.opts.magnification)
185
186 if createdDataFile:
187 self.warning("Removing pseudo-data-file",dataFile)
188 unlink(dataFile)
189
190 del sm
191