/
pvw-lite.py
237 lines (192 loc) · 11.8 KB
/
pvw-lite.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
r"""
This module is a ParaViewWeb server application.
The following command line illustrates how to use it::
$ pvpython -dr .../pvw-lite.py --data /.../path-to-your-data-directory
--data
Path used to list that directory on the server and let the client choose a
file to load. You may also specify multiple directories, each with a name
that should be displayed as the top-level name of the directory in the UI.
If this parameter takes the form: "name1=path1|name2=path2|...",
then we will treat this as the case where multiple data directories are
required. In this case, each top-level directory will be given the name
associated with the directory in the argument.
--load-file try to load the file relative to data-dir if any.
--ds-host None
Host name where pvserver has been started
--ds-port 11111
Port number to use to connect to pvserver
--rs-host None
Host name where renderserver has been started
--rs-port 22222
Port number to use to connect to the renderserver
--exclude-regex "[0-9]+\\."
Regular expression used to filter out files in directory/file listing.
--group-regex "^\\.|~$|^\\$"
Regular expression used to group files into a single loadable entity.
--plugins
Colon-separated (':') list of fully qualified path names to plugin objects
to load.
--color-palette-file
File to load to define a set of color maps. File format is the same as
for ParaViews 'ColorMaps.xml' configuration file.
--reverse-connect-port
If supplied, a reverse connection will be established on the given port.
This option is useful when running in mpi mode and you want pvservers to
connect to this pvpython application.
--save-data-dir
Server directory under which all data will be saved. Data, state, and
screenshots can be saved to relative paths under this directory.
Any ParaViewWeb executable script comes with a set of standard arguments that can be overriden if need be::
--port 8080
Port number on which the HTTP server will listen.
--content /path-to-web-content/
Directory that you want to serve as static web content.
By default, this variable is empty which means that we rely on another
server to deliver the static content and the current process only
focuses on the WebSocket connectivity of clients.
--authKey vtkweb-secret
Secret key that should be provided by the client to allow it to make
any WebSocket communication. The client will assume if none is given
that the server expects "vtkweb-secret" as secret key.
"""
# import to process args
import os
import sys
# Try handle virtual env if provided
if '--virtual-env' in sys.argv:
virtualEnvPath = sys.argv[sys.argv.index('--virtual-env') + 1]
virtualEnv = virtualEnvPath + '/bin/activate_this.py'
execfile(virtualEnv, dict(__file__=virtualEnv))
# Use local proxy file
defaultProxyFile = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'proxies.json')
# import paraview modules.
from paraview.web import pv_wslink
from paraview.web import protocols as pv_protocols
# import RPC annotation
from wslink import register as exportRpc
from paraview import simple
from wslink import server
import lite_protocols as local_protocols
import argparse
# =============================================================================
# Create custom Pipeline Manager class to handle clients requests
# =============================================================================
class _Server(pv_wslink.PVServerProtocol):
dataDir = os.getcwd()
authKey = "wslink-secret"
dsHost = None
dsPort = 11111
rsHost = None
rsPort = 11111
rcPort = -1
fileToLoad = None
groupRegex = "[0-9]+\\.[0-9]+\\.|[0-9]+\\."
excludeRegex = "^\\.|~$|^\\$"
plugins = None
filterFile = None
colorPalette = None
proxies = None
allReaders = True
saveDataDir = os.getcwd()
viewportScale=1.0
viewportMaxWidth=2560
viewportMaxHeight=1440
settingsLODThreshold = 102400
@staticmethod
def add_arguments(parser):
parser.add_argument("--virtual-env", default=None, help="Path to virtual environment to use")
parser.add_argument("--data", default=os.getcwd(), help="path to data directory to list, or else multiple directories given as 'name1=path1|name2=path2|...'", dest="path")
parser.add_argument("--load-file", default=None, help="File to load if any based on data-dir base path", dest="file")
parser.add_argument("--color-palette-file", default=None, help="File to load to define a set of color map", dest="palettes")
parser.add_argument("--no-built-in-palette", help="If provided, disables built-in color maps", action="store_true", dest="hide_built_in_color_maps")
parser.add_argument("--ds-host", default=None, help="Hostname to connect to for DataServer", dest="dsHost")
parser.add_argument("--ds-port", default=11111, type=int, help="Port number to connect to for DataServer", dest="dsPort")
parser.add_argument("--rs-host", default=None, help="Hostname to connect to for RenderServer", dest="rsHost")
parser.add_argument("--rs-port", default=11111, type=int, help="Port number to connect to for RenderServer", dest="rsPort")
parser.add_argument("--reverse-connect-port", default=-1, type=int, help="If supplied, a reverse connection will be established on the given port", dest="reverseConnectPort")
parser.add_argument("--exclude-regex", default=_Server.excludeRegex, help="Regular expression for file filtering", dest="exclude")
parser.add_argument("--group-regex", default=_Server.groupRegex, help="Regular expression for grouping files", dest="group")
parser.add_argument("--plugins", default=None, help="List of fully qualified path names to plugin objects to load", dest="plugins")
parser.add_argument("--proxies", default=defaultProxyFile, help="Path to a file with json text containing filters to load", dest="proxies")
parser.add_argument("--no-auto-readers", help="If provided, disables ability to use non-configured readers", action="store_true", dest="no_auto_readers")
parser.add_argument("--save-data-dir", default='', help="Server directory under which all data will be saved", dest="saveDataDir")
parser.add_argument("--viewport-scale", default=1.0, type=float, help="Viewport scaling factor", dest="viewportScale")
parser.add_argument("--viewport-max-width", default=2560, type=int, help="Viewport maximum size in width", dest="viewportMaxWidth")
parser.add_argument("--viewport-max-height", default=1440, type=int, help="Viewport maximum size in height", dest="viewportMaxHeight")
parser.add_argument("--settings-lod-threshold", default=102400, type=int, help="LOD Threshold in Megabytes", dest="settingsLODThreshold")
@staticmethod
def configure(args):
_Server.authKey = args.authKey
_Server.dataDir = args.path
_Server.dsHost = args.dsHost
_Server.dsPort = args.dsPort
_Server.rsHost = args.rsHost
_Server.rsPort = args.rsPort
_Server.rcPort = args.reverseConnectPort
_Server.excludeRegex = args.exclude
_Server.groupRegex = args.group
_Server.plugins = args.plugins
_Server.proxies = args.proxies
_Server.colorPalette = args.palettes
_Server.viewportScale = args.viewportScale
_Server.viewportMaxWidth = args.viewportMaxWidth
_Server.viewportMaxHeight = args.viewportMaxHeight
_Server.settingsLODThreshold = args.settingsLODThreshold
_Server.allReaders = not args.no_auto_readers
_Server.showBuiltin = not args.hide_built_in_color_maps
# If no save directory is provided, default it to the data directory
if args.saveDataDir == '':
_Server.saveDataDir = _Server.dataDir
else:
_Server.saveDataDir = args.saveDataDir
if args.file:
_Server.fileToLoad = os.path.join(args.path, args.file)
def initialize(self):
# Bring used components from ParaView
self.registerVtkWebProtocol(pv_protocols.ParaViewWebStartupRemoteConnection(_Server.dsHost, _Server.dsPort, _Server.rsHost, _Server.rsPort, _Server.rcPort))
self.registerVtkWebProtocol(pv_protocols.ParaViewWebStartupPluginLoader(_Server.plugins))
self.registerVtkWebProtocol(pv_protocols.ParaViewWebFileListing(_Server.dataDir, "Home", _Server.excludeRegex, _Server.groupRegex))
self.registerVtkWebProtocol(pv_protocols.ParaViewWebProxyManager(allowedProxiesFile=_Server.proxies, baseDir=_Server.dataDir, fileToLoad=_Server.fileToLoad, allowUnconfiguredReaders=_Server.allReaders))
self.registerVtkWebProtocol(pv_protocols.ParaViewWebColorManager(pathToColorMaps=_Server.colorPalette, showBuiltin=_Server.showBuiltin))
self.registerVtkWebProtocol(pv_protocols.ParaViewWebMouseHandler())
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPort(_Server.viewportScale, _Server.viewportMaxWidth, _Server.viewportMaxHeight))
self.registerVtkWebProtocol(pv_protocols.ParaViewWebPublishImageDelivery(decode=False))
self.registerVtkWebProtocol(pv_protocols.ParaViewWebTimeHandler())
self.registerVtkWebProtocol(pv_protocols.ParaViewWebSelectionHandler())
self.registerVtkWebProtocol(pv_protocols.ParaViewWebWidgetManager())
self.registerVtkWebProtocol(pv_protocols.ParaViewWebKeyValuePairStore())
self.registerVtkWebProtocol(pv_protocols.ParaViewWebSaveData(baseSavePath=_Server.saveDataDir))
# Bring used components from ParaView Lite
self.registerVtkWebProtocol(local_protocols.ParaViewLite())
# Update authentication key to use
self.updateSecret(_Server.authKey)
# tell the C++ web app to use no encoding. ParaViewWebPublishImageDelivery must be set to decode=False to match.
self.getApplication().SetImageEncoding(0);
# Disable interactor-based render calls
view = simple.GetRenderView()
view.EnableRenderOnInteraction = 0
view.Background = [0.4470588235294118, 0.4470588235294118, 0.4470588235294118]
view.Background2 = [0.2235294117647059, 0.2235294117647059, 0.2235294117647059]
view.UseGradientBackground = 1
view.OrientationAxesVisibility = 0
# ProxyManager helper
pxm = simple.servermanager.ProxyManager()
# Update interaction mode
interactionProxy = pxm.GetProxy('settings', 'RenderViewInteractionSettings')
interactionProxy.Camera3DManipulators = ['Rotate', 'Pan', 'Zoom', 'Pan', 'Roll', 'Pan', 'Zoom', 'Rotate', 'Zoom']
# Custom rendering settings
renderingSettings = pxm.GetProxy('settings', 'RenderViewSettings')
renderingSettings.LODThreshold = _Server.settingsLODThreshold
# =============================================================================
# Main: Parse args and start server
# =============================================================================
if __name__ == "__main__":
# Create argument parser
parser = argparse.ArgumentParser(description="ParaView Lite")
# Add arguments
server.add_arguments(parser)
_Server.add_arguments(parser)
args = parser.parse_args()
_Server.configure(args)
# Start server
server.start_webserver(options=args, protocol=_Server)