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,
131 paraviewLink=False,
132 archive=None)
133
134 times=self.processTimestepOptions(sol)
135 if len(times)<1:
136 self.warning("Can't continue without time-steps")
137 return
138
139 dataFile=path.join(case,short+".OpenFOAM")
140 createdDataFile=False
141 if not path.exists(dataFile):
142 createdDataFile=True
143 f=open(dataFile,"w")
144 f.close()
145
146 sf=StateFile(self.opts.state)
147 sf.setCase(dataFile)
148
149 values=eval(self.opts.replacements)
150 values[self.opts.casenameKey]=short
151 sf.rewriteTexts(values)
152 newState=sf.writeTemp()
153
154 sm=SM(requiredReader=sf.readerType())
155 if not self.opts.progress:
156 sm.ToggleProgressPrinting()
157
158
159 sm.LoadState(newState)
160 views=sm.GetRenderViews()
161
162 if len(views)>1:
163 self.warning("More than 1 view in state-file. Generating multiple series")
164 timeString="_View%(view)02d"+timeString
165 timeString=self.opts.prefix+timeString
166
167 for view in views:
168 view.UseOffscreenRenderingForScreenshots=True
169
170 for i,t in enumerate(times):
171 print "Snapshot ",i," for t=",t
172 for j,view in enumerate(views):
173 view.ViewTime=float(t)
174 fn = timeString % {'nr':i,'t':t,'view':j}
175 if PVVersion()<(3,6):
176 view.WriteImage(fn,
177 self.typeTable[self.opts.type],
178 self.opts.magnification)
179 else:
180 from paraview.simple import SetActiveView,Render,WriteImage
181 SetActiveView(view)
182 Render()
183
184 WriteImage(fn,
185 view,
186
187 Magnification=self.opts.magnification)
188
189 if createdDataFile:
190 self.warning("Removing pseudo-data-file",dataFile)
191 unlink(dataFile)
192
193 del sm
194