pytecplot 1.5.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytecplot-1.5.2.dist-info/LICENSE.html +77 -0
- pytecplot-1.5.2.dist-info/METADATA +508 -0
- pytecplot-1.5.2.dist-info/RECORD +97 -0
- pytecplot-1.5.2.dist-info/WHEEL +5 -0
- pytecplot-1.5.2.dist-info/top_level.txt +1 -0
- tecplot/__init__.py +94 -0
- tecplot/annotation/__init__.py +7 -0
- tecplot/annotation/annotation.py +223 -0
- tecplot/annotation/geometry.py +369 -0
- tecplot/annotation/georeference.py +33 -0
- tecplot/annotation/image.py +185 -0
- tecplot/annotation/iter.py +105 -0
- tecplot/annotation/polyline.py +381 -0
- tecplot/annotation/text.py +744 -0
- tecplot/constant.py +401 -0
- tecplot/data/__init__.py +34 -0
- tecplot/data/array.py +645 -0
- tecplot/data/create.py +1 -0
- tecplot/data/dataset.py +1809 -0
- tecplot/data/extract.py +544 -0
- tecplot/data/face_neighbors.py +494 -0
- tecplot/data/facemap.py +814 -0
- tecplot/data/load.py +2075 -0
- tecplot/data/nodemap.py +577 -0
- tecplot/data/operate.py +928 -0
- tecplot/data/query.py +334 -0
- tecplot/data/save.py +343 -0
- tecplot/data/variable.py +280 -0
- tecplot/data/zone.py +841 -0
- tecplot/exception.py +201 -0
- tecplot/export/__init__.py +13 -0
- tecplot/export/animation.py +521 -0
- tecplot/export/export_setup.py +318 -0
- tecplot/export/image.py +577 -0
- tecplot/export/print_setup.py +218 -0
- tecplot/export/time_animation.py +607 -0
- tecplot/extension/__init__.py +14 -0
- tecplot/extension/ipython.py +68 -0
- tecplot/layout/__init__.py +20 -0
- tecplot/layout/frame.py +1285 -0
- tecplot/layout/layout.py +488 -0
- tecplot/layout/page.py +541 -0
- tecplot/legend/__init__.py +4 -0
- tecplot/legend/contour_legend.py +516 -0
- tecplot/legend/legend.py +141 -0
- tecplot/legend/line_legend.py +66 -0
- tecplot/legend/rgb_coloring_legend.py +291 -0
- tecplot/legend/scatter_legend.py +136 -0
- tecplot/macro.py +339 -0
- tecplot/plot/__init__.py +62 -0
- tecplot/plot/axes.py +881 -0
- tecplot/plot/axis.py +1350 -0
- tecplot/plot/blanking.py +584 -0
- tecplot/plot/contour.py +1302 -0
- tecplot/plot/effects.py +162 -0
- tecplot/plot/fieldmap.py +2159 -0
- tecplot/plot/grid.py +758 -0
- tecplot/plot/isosurface.py +1167 -0
- tecplot/plot/labels.py +338 -0
- tecplot/plot/linemap.py +1905 -0
- tecplot/plot/linking.py +489 -0
- tecplot/plot/plot.py +1791 -0
- tecplot/plot/rgb_coloring.py +281 -0
- tecplot/plot/scatter.py +396 -0
- tecplot/plot/slice.py +1544 -0
- tecplot/plot/streamtrace.py +1949 -0
- tecplot/plot/symbol.py +567 -0
- tecplot/plot/ticks.py +666 -0
- tecplot/plot/title.py +380 -0
- tecplot/plot/vector.py +679 -0
- tecplot/plot/view.py +868 -0
- tecplot/session/__init__.py +112 -0
- tecplot/session/aux_data.py +276 -0
- tecplot/session/config.py +92 -0
- tecplot/session/session.py +425 -0
- tecplot/session/state_changed.py +225 -0
- tecplot/session/style.py +504 -0
- tecplot/tecutil/__init__.py +16 -0
- tecplot/tecutil/arglist.py +230 -0
- tecplot/tecutil/captured_output.py +177 -0
- tecplot/tecutil/constant.py +1312 -0
- tecplot/tecutil/index_set.py +118 -0
- tecplot/tecutil/lock.py +36 -0
- tecplot/tecutil/message_pb2.py +39 -0
- tecplot/tecutil/preamble.py +54 -0
- tecplot/tecutil/stringlist.py +114 -0
- tecplot/tecutil/sv.py +1662 -0
- tecplot/tecutil/tecutil.py +12402 -0
- tecplot/tecutil/tecutil_client.py +627 -0
- tecplot/tecutil/tecutil_connector.py +937 -0
- tecplot/tecutil/tecutil_rpc.py +6845 -0
- tecplot/tecutil/util.py +332 -0
- tecplot/text/__init__.py +3 -0
- tecplot/text/font.py +224 -0
- tecplot/text/label_format.py +374 -0
- tecplot/text/textbox.py +106 -0
- tecplot/version.py +41 -0
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
import atexit
|
|
2
|
+
import contextlib
|
|
3
|
+
import logging
|
|
4
|
+
import sys
|
|
5
|
+
import textwrap
|
|
6
|
+
import zmq
|
|
7
|
+
|
|
8
|
+
from collections.abc import Iterable
|
|
9
|
+
from ctypes import *
|
|
10
|
+
from enum import Enum
|
|
11
|
+
|
|
12
|
+
from . import message_pb2 as tecrpc
|
|
13
|
+
|
|
14
|
+
from ..constant import *
|
|
15
|
+
from ..exception import *
|
|
16
|
+
from .tecutil_rpc import TecUtilRPC, ValueType
|
|
17
|
+
from .util import Index
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
log = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def set_arglist_item(item, key, val):
|
|
24
|
+
assert isinstance(key, str) or isinstance(key, c_char)
|
|
25
|
+
|
|
26
|
+
if isinstance(key, c_char):
|
|
27
|
+
item.key = key.value.decode('utf-8')
|
|
28
|
+
else:
|
|
29
|
+
item.key = key
|
|
30
|
+
|
|
31
|
+
if isinstance(val, tecplot.tecutil.StringList):
|
|
32
|
+
addr = getattr(val, 'value', val)
|
|
33
|
+
set_address(item.value, tecrpc.Argument.StringList, addr)
|
|
34
|
+
elif isinstance(val, tecplot.tecutil.IndexSet):
|
|
35
|
+
addr = getattr(val, 'value', val)
|
|
36
|
+
set_address(item.value, tecrpc.Argument.IndexSet, addr)
|
|
37
|
+
elif isinstance(val, str):
|
|
38
|
+
set_text(item.value, None, val)
|
|
39
|
+
elif isinstance(val, (float, c_double)):
|
|
40
|
+
set_scalar(item.value, c_double, val)
|
|
41
|
+
elif isinstance(val, Index):
|
|
42
|
+
set_scalar(item.value, c_int64, val+1)
|
|
43
|
+
|
|
44
|
+
elif isinstance(val, POINTER(c_double)): # POSSIBLY IN/OUTPUT
|
|
45
|
+
item.value.type = tecrpc.Argument.Address | tecrpc.Argument.Float64
|
|
46
|
+
item.value.float64 = val[0]
|
|
47
|
+
|
|
48
|
+
elif isinstance(val, (int, bool)):
|
|
49
|
+
set_scalar(item.value, c_int64, val)
|
|
50
|
+
elif isinstance(val, Enum):
|
|
51
|
+
set_scalar(item.value, c_int64, val.value)
|
|
52
|
+
|
|
53
|
+
elif isinstance(val, c_size_t): # POSSIBLY IN/OUTPUT
|
|
54
|
+
set_arbparam(item.value, None, val)
|
|
55
|
+
elif isinstance(val, POINTER(c_size_t)): # POSSIBLY IN/OUTPUT
|
|
56
|
+
ptr = cast(val, c_void_p)
|
|
57
|
+
set_arbparam(item.value, POINTER, ptr.value)
|
|
58
|
+
elif isinstance(val, POINTER(POINTER(c_char))): # POSSIBLY IN/OUTPUT
|
|
59
|
+
set_arbparam(item.value, POINTER, val.contents)
|
|
60
|
+
elif isinstance(val, POINTER(c_char_p)): # POSSIBLY IN/OUTPUT
|
|
61
|
+
set_text(item.value, Argument.Address, val)
|
|
62
|
+
|
|
63
|
+
else:
|
|
64
|
+
if isinstance(val, Iterable):
|
|
65
|
+
val = list(val)
|
|
66
|
+
if isinstance(val, list):
|
|
67
|
+
if isinstance(val[0], Enum):
|
|
68
|
+
enum_values = [e.value for e in val]
|
|
69
|
+
set_array(item.value, c_int32, enum_values)
|
|
70
|
+
elif isinstance(val[0], float):
|
|
71
|
+
set_array(item.value, c_double, val)
|
|
72
|
+
elif len(val) == 0 or isinstance(val[0], int):
|
|
73
|
+
set_array(item.value, c_int64, val)
|
|
74
|
+
else:
|
|
75
|
+
msg = 'invalid type: {} ({} = {})'
|
|
76
|
+
msg = msg.format(type(val), key, val)
|
|
77
|
+
raise TecplotTypeError(msg)
|
|
78
|
+
else:
|
|
79
|
+
msg = 'invalid type: {} ({} = {})'
|
|
80
|
+
msg = msg.format(type(val), key, val)
|
|
81
|
+
raise TecplotTypeError(msg)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def add_arglist(arg, arglist):
|
|
85
|
+
assert isinstance(arglist, tecplot.tecutil.LocalArgList)
|
|
86
|
+
arg.type = tecrpc.Argument.ArgList
|
|
87
|
+
for key, val in arglist.items():
|
|
88
|
+
item = arg.arglist.items.add()
|
|
89
|
+
set_arglist_item(item, key, val)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def set_address(arg, argtype, value):
|
|
93
|
+
if argtype is c_uint64:
|
|
94
|
+
arg.type = tecrpc.Argument.Address
|
|
95
|
+
else:
|
|
96
|
+
arg.type = argtype | tecrpc.Argument.Address
|
|
97
|
+
|
|
98
|
+
if value is None or value == 0:
|
|
99
|
+
arg.type |= tecrpc.Argument.Null
|
|
100
|
+
else:
|
|
101
|
+
arg.uint64 = value
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def set_arbparam(arg, argtype, value):
|
|
105
|
+
assert argtype in [None, POINTER, tecrpc.Argument.Address]
|
|
106
|
+
if isinstance(value, POINTER(c_char)):
|
|
107
|
+
value = cast(value, c_char_p).value.decode('utf-8')
|
|
108
|
+
is_addr = argtype is not None and (argtype is POINTER or
|
|
109
|
+
argtype & tecrpc.Argument.Address)
|
|
110
|
+
if isinstance(value, str):
|
|
111
|
+
arg.type = tecrpc.Argument.ArbParam | tecrpc.Argument.Text
|
|
112
|
+
if is_addr:
|
|
113
|
+
arg.type |= tecrpc.Argument.Address
|
|
114
|
+
arg.text = value or ''
|
|
115
|
+
else:
|
|
116
|
+
if is_addr:
|
|
117
|
+
arg.type = tecrpc.Argument.ArbParam | tecrpc.Argument.Address
|
|
118
|
+
arg.uint64 = value
|
|
119
|
+
elif isinstance(value, Enum):
|
|
120
|
+
arg.type = tecrpc.Argument.ArbParam | tecrpc.Argument.Enum
|
|
121
|
+
arg.int64 = value.value
|
|
122
|
+
else:
|
|
123
|
+
arg.type = tecrpc.Argument.ArbParam
|
|
124
|
+
arg.int64 = c_int64(int(getattr(value, 'value', value))).value
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def set_array(arg, argtype, value):
|
|
128
|
+
_types = {
|
|
129
|
+
c_bool: tecrpc.Argument.Bool,
|
|
130
|
+
c_uint8: tecrpc.Argument.UInt8,
|
|
131
|
+
c_uint32: tecrpc.Argument.UInt32,
|
|
132
|
+
c_uint64: tecrpc.Argument.UInt64,
|
|
133
|
+
c_int32: tecrpc.Argument.Int32,
|
|
134
|
+
c_int64: tecrpc.Argument.Int64,
|
|
135
|
+
c_float: tecrpc.Argument.Float32,
|
|
136
|
+
c_double: tecrpc.Argument.Float64}
|
|
137
|
+
if value is None:
|
|
138
|
+
arg.type = tecrpc.Argument.Unspecified if argtype is None else _types[argtype]
|
|
139
|
+
arg.type |= tecrpc.Argument.Array | tecrpc.Argument.Null
|
|
140
|
+
else:
|
|
141
|
+
if argtype is None:
|
|
142
|
+
arg.type = tecrpc.Argument.Array
|
|
143
|
+
try:
|
|
144
|
+
arg.type |= _types[value._type_]
|
|
145
|
+
except KeyError:
|
|
146
|
+
arg.type |= tecrpc.Argument.Unspecified
|
|
147
|
+
arg.uint64 = len(value)
|
|
148
|
+
else:
|
|
149
|
+
arg.type = tecrpc.Argument.Array | _types[argtype]
|
|
150
|
+
if isinstance(value, Array):
|
|
151
|
+
# ctypes arrays are reinterpreted
|
|
152
|
+
if value._type_ != argtype:
|
|
153
|
+
n, r = divmod(len(value) * sizeof(value._type_), sizeof(argtype))
|
|
154
|
+
if r:
|
|
155
|
+
raise TypeError('could not cast array to the requested type')
|
|
156
|
+
p = cast(value, POINTER(argtype))
|
|
157
|
+
a = (argtype * n).from_address(addressof(p.contents))
|
|
158
|
+
arg.buffer = bytes(bytearray(a))
|
|
159
|
+
else:
|
|
160
|
+
arg.buffer = bytes(bytearray(value))
|
|
161
|
+
else:
|
|
162
|
+
# all other array types are cast to type argtype
|
|
163
|
+
try:
|
|
164
|
+
import numpy as np
|
|
165
|
+
arr = np.array(value, dtype=argtype)
|
|
166
|
+
try:
|
|
167
|
+
arg.buffer = arr.tobytes()
|
|
168
|
+
except AttributeError:
|
|
169
|
+
# numpy.ndarray.tobytes() added in 1.9.0
|
|
170
|
+
arg.buffer = bytes(arr.tostring())
|
|
171
|
+
except ImportError:
|
|
172
|
+
value = (argtype * len(value))(*value)
|
|
173
|
+
arg.buffer = bytes(bytearray(value))
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def set_scalar(arg, argtype, value):
|
|
177
|
+
_types = {
|
|
178
|
+
c_bool: tecrpc.Argument.Bool,
|
|
179
|
+
c_uint8: tecrpc.Argument.UInt8,
|
|
180
|
+
c_uint32: tecrpc.Argument.UInt32,
|
|
181
|
+
c_uint64: tecrpc.Argument.UInt64,
|
|
182
|
+
c_int32: tecrpc.Argument.Int32,
|
|
183
|
+
c_int64: tecrpc.Argument.Int64,
|
|
184
|
+
c_float: tecrpc.Argument.Float32,
|
|
185
|
+
c_double: tecrpc.Argument.Float64, }
|
|
186
|
+
arg.type = _types[argtype]
|
|
187
|
+
if arg.type == tecrpc.Argument.Bool:
|
|
188
|
+
arg.boolean = value
|
|
189
|
+
elif arg.type in [tecrpc.Argument.UInt8, tecrpc.Argument.UInt32]:
|
|
190
|
+
arg.uint32 = value
|
|
191
|
+
elif arg.type == tecrpc.Argument.UInt64:
|
|
192
|
+
arg.uint64 = value
|
|
193
|
+
elif arg.type == tecrpc.Argument.Int32:
|
|
194
|
+
arg.int32 = value
|
|
195
|
+
elif arg.type == tecrpc.Argument.Int64:
|
|
196
|
+
arg.int64 = value
|
|
197
|
+
elif arg.type == tecrpc.Argument.Float32:
|
|
198
|
+
arg.float32 = value
|
|
199
|
+
elif arg.type == tecrpc.Argument.Float64:
|
|
200
|
+
arg.float64 = value
|
|
201
|
+
else:
|
|
202
|
+
raise TecplotNotImplementedError('cannot add scalar: {}'.format(type(value)))
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def set_text(arg, argtype, value):
|
|
206
|
+
assert argtype in [None, tecrpc.Argument.Address]
|
|
207
|
+
if isinstance(value, c_char):
|
|
208
|
+
value = value.value.decode('utf-8')
|
|
209
|
+
arg.type = tecrpc.Argument.Text
|
|
210
|
+
if argtype is not None and argtype & tecrpc.Argument.Address:
|
|
211
|
+
arg.type |= tecrpc.Argument.Address
|
|
212
|
+
if value is None:
|
|
213
|
+
arg.type |= tecrpc.Argument.Null
|
|
214
|
+
else:
|
|
215
|
+
arg.text = value or ''
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def add_args(request, *args):
|
|
219
|
+
_dispatch = {
|
|
220
|
+
ValueType.Address: set_address,
|
|
221
|
+
ValueType.ArbParam: set_arbparam,
|
|
222
|
+
ValueType.Array: set_array,
|
|
223
|
+
ValueType.Scalar: set_scalar,
|
|
224
|
+
ValueType.Text: set_text, }
|
|
225
|
+
for valtype, argtype, value in args:
|
|
226
|
+
arg = request.args.add()
|
|
227
|
+
if isinstance(value, tecplot.tecutil.LocalArgList):
|
|
228
|
+
assert argtype is c_uint64
|
|
229
|
+
add_arglist(arg, value)
|
|
230
|
+
else:
|
|
231
|
+
_dispatch[valtype](arg, argtype, value)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def build_tecutil_request(request, tecutil_command, *args, **kwargs):
|
|
235
|
+
request.operation = tecutil_command
|
|
236
|
+
request.type = tecrpc.Request.TecUtil
|
|
237
|
+
if any(isinstance(a[2], tecplot.tecutil.LocalArgList) for a in args):
|
|
238
|
+
request.type |= tecrpc.Request.TecUtilX
|
|
239
|
+
if kwargs.pop('lock', True):
|
|
240
|
+
request.type |= tecrpc.Request.LockRequired
|
|
241
|
+
add_args(request, *args)
|
|
242
|
+
return request.type
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class TecUtilClient(TecUtilRPC):
|
|
246
|
+
def __init__(self):
|
|
247
|
+
self.socket = None
|
|
248
|
+
self.tuserver_version = 0
|
|
249
|
+
self.sdk_version_info = (0, 0, 0, 0)
|
|
250
|
+
self.suspended = False
|
|
251
|
+
self.state_changes = {}
|
|
252
|
+
|
|
253
|
+
def connect(self, host='localhost', port=7600, timeout=10, quiet=False):
|
|
254
|
+
# Prepare the ZeroMQ context
|
|
255
|
+
self._context = zmq.Context()
|
|
256
|
+
|
|
257
|
+
# Setup the request server socket
|
|
258
|
+
self.socket = self._context.socket(zmq.REQ)
|
|
259
|
+
|
|
260
|
+
# Set high water mark for out-going messages.
|
|
261
|
+
# This is the maximum number of messages to
|
|
262
|
+
# store in the out-going queue - send() will
|
|
263
|
+
# block until the HWM is below this limit.
|
|
264
|
+
self.socket.setsockopt(zmq.SNDHWM, 10)
|
|
265
|
+
|
|
266
|
+
# Do not linger once socket is closed.
|
|
267
|
+
# Send messages immediately, and possibly
|
|
268
|
+
# fail, but do not attempt to recover.
|
|
269
|
+
self.socket.setsockopt(zmq.LINGER, 0)
|
|
270
|
+
|
|
271
|
+
# Connect requester to the reply sever
|
|
272
|
+
self.host = host
|
|
273
|
+
self.endpoint = "tcp://{host}:{port}".format(host=host, port=port)
|
|
274
|
+
self.socket.connect(self.endpoint)
|
|
275
|
+
|
|
276
|
+
self.wait_for_connection(timeout, quiet)
|
|
277
|
+
|
|
278
|
+
if self.connected:
|
|
279
|
+
atexit.register(self.disconnect)
|
|
280
|
+
|
|
281
|
+
# Bring in tecplot module only on connection to avoid circular deps
|
|
282
|
+
import tecplot
|
|
283
|
+
globals()['tecplot'] = tecplot
|
|
284
|
+
|
|
285
|
+
def wait_for_connection(self, timeout=10, quiet=False):
|
|
286
|
+
|
|
287
|
+
def post_message(msg, quiet=quiet):
|
|
288
|
+
if not quiet:
|
|
289
|
+
if log.getEffectiveLevel() <= logging.INFO:
|
|
290
|
+
log.info(msg)
|
|
291
|
+
else:
|
|
292
|
+
print(msg)
|
|
293
|
+
|
|
294
|
+
post_message(
|
|
295
|
+
'Connecting to Tecplot 360 TecUtil Server on:\n {}'.format(
|
|
296
|
+
self.endpoint))
|
|
297
|
+
|
|
298
|
+
if not self.is_server_listening(timeout):
|
|
299
|
+
self.disconnect()
|
|
300
|
+
raise TecplotTimeoutError('Failed to connect to TecUtil Server.')
|
|
301
|
+
|
|
302
|
+
post_message('Connection established.')
|
|
303
|
+
|
|
304
|
+
def is_server_listening(self, timeout=10):
|
|
305
|
+
if self.socket is None:
|
|
306
|
+
raise TecplotLogicError('Not connected to Tecplot 360.')
|
|
307
|
+
|
|
308
|
+
# raw messages must be 255 characters or less
|
|
309
|
+
RAWMSG = 0b00001010
|
|
310
|
+
HANDSHAKE = b'UTHR?'
|
|
311
|
+
buf = bytes([RAWMSG, len(HANDSHAKE)] + list(HANDSHAKE))
|
|
312
|
+
self.socket.send(buf)
|
|
313
|
+
|
|
314
|
+
poller = zmq.Poller()
|
|
315
|
+
poller.register(self.socket, zmq.POLLIN)
|
|
316
|
+
if poller.poll(timeout * 1000):
|
|
317
|
+
ERRMSG = 'Could not perform handshake with preferred method'
|
|
318
|
+
|
|
319
|
+
msg = bytes(self.socket.recv())
|
|
320
|
+
|
|
321
|
+
if len(msg) < 10:
|
|
322
|
+
raise TecplotInvalidMessage(ERRMSG + ' (response too small')
|
|
323
|
+
if msg[0] != RAWMSG:
|
|
324
|
+
raise TecplotInvalidMessage(ERRMSG + ' (not a raw message)')
|
|
325
|
+
|
|
326
|
+
n = int(msg[1])
|
|
327
|
+
msg = bytes(msg[2:2+n]).decode('utf-8').split(':')
|
|
328
|
+
|
|
329
|
+
if msg[0] != 'YA':
|
|
330
|
+
raise TecplotInvalidMessage(ERRMSG + ' (unrecognized response)')
|
|
331
|
+
if len(msg) != 6:
|
|
332
|
+
raise TecplotInvalidMessage(ERRMSG + ' (invalid response length)')
|
|
333
|
+
|
|
334
|
+
try:
|
|
335
|
+
self.tuserver_version = int(msg[1])
|
|
336
|
+
self.sdk_version_info = tuple([int(x) for x in msg[2:2+4]])
|
|
337
|
+
except Exception as e:
|
|
338
|
+
self.tuserver_version = 0
|
|
339
|
+
self.sdk_version_info = (0, 0, 0, 0)
|
|
340
|
+
raise TecplotInvalidMessage(ERRMSG + '\n' + str(e))
|
|
341
|
+
|
|
342
|
+
return True
|
|
343
|
+
|
|
344
|
+
return False
|
|
345
|
+
|
|
346
|
+
@property
|
|
347
|
+
def connected(self):
|
|
348
|
+
return self.socket is not None
|
|
349
|
+
|
|
350
|
+
def disconnect(self):
|
|
351
|
+
if self.socket:
|
|
352
|
+
atexit.unregister(self.disconnect)
|
|
353
|
+
self.socket.disconnect(self.endpoint)
|
|
354
|
+
self.socket.close()
|
|
355
|
+
self.socket = None
|
|
356
|
+
self.tuserver_version = 0
|
|
357
|
+
self.sdk_version_info = (0, 0, 0, 0)
|
|
358
|
+
|
|
359
|
+
def sndrcv(self, tecutil_command, *args, **kwargs):
|
|
360
|
+
request = tecrpc.Request()
|
|
361
|
+
optype = build_tecutil_request(request, tecutil_command, *args, **kwargs)
|
|
362
|
+
|
|
363
|
+
request_buffer = request.SerializeToString()
|
|
364
|
+
self.socket.send(request_buffer)
|
|
365
|
+
|
|
366
|
+
reply = tecrpc.Reply()
|
|
367
|
+
reply_buffer = self.socket.recv()
|
|
368
|
+
reply.ParseFromString(reply_buffer)
|
|
369
|
+
|
|
370
|
+
if optype & tecrpc.Request.TecUtilX:
|
|
371
|
+
reply = self.read_tecutilx_reply(args, reply)
|
|
372
|
+
|
|
373
|
+
return reply
|
|
374
|
+
|
|
375
|
+
def chk(self, reply):
|
|
376
|
+
if reply.status != tecrpc.Reply.Success:
|
|
377
|
+
errmsg = reply.log
|
|
378
|
+
if not isinstance(errmsg, str):
|
|
379
|
+
errmsg = errmsg.decode('utf-8')
|
|
380
|
+
raise TecplotSystemError(errmsg)
|
|
381
|
+
|
|
382
|
+
def read_arbparam(self, arg):
|
|
383
|
+
if arg.type & tecrpc.Argument.Null:
|
|
384
|
+
return None
|
|
385
|
+
elif arg.type & tecrpc.Argument.Text:
|
|
386
|
+
txt = arg.text
|
|
387
|
+
if isinstance(txt, str):
|
|
388
|
+
ctxt = c_char_p(bytes(txt, encoding='utf-8'))
|
|
389
|
+
txt = cast(ctxt, POINTER(c_char))
|
|
390
|
+
else:
|
|
391
|
+
txt = cast(pointer(create_string_buffer(txt)), POINTER(c_char))
|
|
392
|
+
return txt
|
|
393
|
+
if (arg.type == tecrpc.Argument.Unspecified or
|
|
394
|
+
(arg.type & tecrpc.Argument.Address)):
|
|
395
|
+
return arg.int64
|
|
396
|
+
else:
|
|
397
|
+
TecplotNotImplementedError
|
|
398
|
+
|
|
399
|
+
def read_text(self, arg):
|
|
400
|
+
if (arg.type == tecrpc.Argument.Unspecified or
|
|
401
|
+
(arg.type & tecrpc.Argument.Text)):
|
|
402
|
+
return arg.text
|
|
403
|
+
elif arg.type & tecrpc.Argument.Null:
|
|
404
|
+
return None
|
|
405
|
+
else:
|
|
406
|
+
TecplotNotImplementedError
|
|
407
|
+
|
|
408
|
+
def read_enum_array(self, arg, argtype):
|
|
409
|
+
n, r = divmod(len(arg.buffer), sizeof(c_int32))
|
|
410
|
+
if r:
|
|
411
|
+
raise Exception('could not read array of specified type')
|
|
412
|
+
arr = (c_int32 * n).from_buffer_copy(arg.buffer)
|
|
413
|
+
return [argtype(i) for i in arr]
|
|
414
|
+
|
|
415
|
+
def read_array(self, arg, argtype):
|
|
416
|
+
n, r = divmod(len(arg.buffer), sizeof(argtype))
|
|
417
|
+
if r:
|
|
418
|
+
raise Exception('could not read array of specified type')
|
|
419
|
+
return (argtype * n).from_buffer_copy(arg.buffer)
|
|
420
|
+
|
|
421
|
+
def read_tecutilx_reply(self, args, reply):
|
|
422
|
+
for valtype, argtype, arg in args:
|
|
423
|
+
if isinstance(arg, tecplot.tecutil.LocalArgList):
|
|
424
|
+
for reparg in reply.args:
|
|
425
|
+
if reparg.type & tecrpc.Argument.ArgList:
|
|
426
|
+
for item in reparg.arglist.items:
|
|
427
|
+
key, value = item.key, item.value
|
|
428
|
+
if value.type & tecrpc.Argument.Float64:
|
|
429
|
+
arg[key][0] = value.float64
|
|
430
|
+
elif value.type & tecrpc.Argument.ArbParam:
|
|
431
|
+
arg[key][0] = self.read_arbparam(value)
|
|
432
|
+
elif value.type & Argument.Text:
|
|
433
|
+
arg[key] = self.read_text(value)
|
|
434
|
+
else:
|
|
435
|
+
raise TecplotValueError(key)
|
|
436
|
+
return reply
|
|
437
|
+
|
|
438
|
+
def _send_suspend_interface(self, suspend=True):
|
|
439
|
+
if self.tuserver_version < 3:
|
|
440
|
+
log.info(MESSAGES.PERFORMANCE_IMPROVEMENTS)
|
|
441
|
+
request = tecrpc.Request()
|
|
442
|
+
request.version = 1
|
|
443
|
+
request.type = tecrpc.Request.Server
|
|
444
|
+
request.operation = 'Suspend Interface'
|
|
445
|
+
arg = request.args.add()
|
|
446
|
+
arg.boolean = suspend
|
|
447
|
+
|
|
448
|
+
request_buffer = request.SerializeToString()
|
|
449
|
+
self.socket.send(request_buffer)
|
|
450
|
+
|
|
451
|
+
reply = tecrpc.Reply()
|
|
452
|
+
reply_buffer = self.socket.recv()
|
|
453
|
+
reply.ParseFromString(reply_buffer)
|
|
454
|
+
self.chk(reply)
|
|
455
|
+
|
|
456
|
+
@contextlib.contextmanager
|
|
457
|
+
def suspend_interface(self):
|
|
458
|
+
assert self.socket is not None
|
|
459
|
+
|
|
460
|
+
if self.tuserver_version < 2:
|
|
461
|
+
log.warn('This version of the TecUtil Server addon does not'
|
|
462
|
+
' support the suspended interface context. Please update'
|
|
463
|
+
' to the newest version of Tecplot 360.')
|
|
464
|
+
yield
|
|
465
|
+
else:
|
|
466
|
+
if self.suspended:
|
|
467
|
+
yield
|
|
468
|
+
else:
|
|
469
|
+
try:
|
|
470
|
+
self._send_suspend_interface(True)
|
|
471
|
+
self.suspended = True
|
|
472
|
+
yield
|
|
473
|
+
finally:
|
|
474
|
+
self.suspended = False
|
|
475
|
+
self._send_suspend_interface(False)
|
|
476
|
+
|
|
477
|
+
def clear_suspend_interface(self):
|
|
478
|
+
self._send_suspend_interface(False)
|
|
479
|
+
|
|
480
|
+
@property
|
|
481
|
+
def processing_mode(self):
|
|
482
|
+
raise TecplotNotImplementedError
|
|
483
|
+
|
|
484
|
+
@processing_mode.setter
|
|
485
|
+
def processing_mode(self, mode):
|
|
486
|
+
if self.tuserver_version < 6:
|
|
487
|
+
log.warn('This version of the TecUtil Server addon does not'
|
|
488
|
+
' support different processing modes. Please update'
|
|
489
|
+
' to the newest version of Tecplot 360.')
|
|
490
|
+
return
|
|
491
|
+
|
|
492
|
+
request = tecrpc.Request()
|
|
493
|
+
request.version = 1
|
|
494
|
+
request.type = tecrpc.Request.Server
|
|
495
|
+
request.operation = 'Set Processing Mode'
|
|
496
|
+
arg = request.args.add()
|
|
497
|
+
arg.uint32 = TecUtilServerProcessingMode(mode).value
|
|
498
|
+
|
|
499
|
+
request_buffer = request.SerializeToString()
|
|
500
|
+
self.socket.send(request_buffer)
|
|
501
|
+
|
|
502
|
+
reply = tecrpc.Reply()
|
|
503
|
+
reply_buffer = self.socket.recv()
|
|
504
|
+
reply.ParseFromString(reply_buffer)
|
|
505
|
+
self.chk(reply)
|
|
506
|
+
|
|
507
|
+
@property
|
|
508
|
+
def logging_level(self):
|
|
509
|
+
raise TecplotNotImplementedError
|
|
510
|
+
|
|
511
|
+
@logging_level.setter
|
|
512
|
+
def logging_level(self, level):
|
|
513
|
+
if self.tuserver_version < 6:
|
|
514
|
+
log.warn('This version of the TecUtil Server addon does not'
|
|
515
|
+
' support adjusting the logging level. Please update'
|
|
516
|
+
' to the newest version of Tecplot 360.')
|
|
517
|
+
return
|
|
518
|
+
|
|
519
|
+
request = tecrpc.Request()
|
|
520
|
+
request.version = 1
|
|
521
|
+
request.type = tecrpc.Request.Server
|
|
522
|
+
request.operation = 'Set Logging Level'
|
|
523
|
+
arg = request.args.add()
|
|
524
|
+
arg.int32 = level
|
|
525
|
+
|
|
526
|
+
request_buffer = request.SerializeToString()
|
|
527
|
+
self.socket.send(request_buffer)
|
|
528
|
+
|
|
529
|
+
reply = tecrpc.Reply()
|
|
530
|
+
reply_buffer = self.socket.recv()
|
|
531
|
+
reply.ParseFromString(reply_buffer)
|
|
532
|
+
self.chk(reply)
|
|
533
|
+
|
|
534
|
+
def quit(self):
|
|
535
|
+
if self.tuserver_version < 7:
|
|
536
|
+
try:
|
|
537
|
+
self.Quit()
|
|
538
|
+
except TecplotSystemError as err:
|
|
539
|
+
if str(err) != 'Tecplot quitting...':
|
|
540
|
+
raise
|
|
541
|
+
else:
|
|
542
|
+
request = tecrpc.Request()
|
|
543
|
+
request.version = 1
|
|
544
|
+
request.type = tecrpc.Request.Server
|
|
545
|
+
request.operation = 'Quit'
|
|
546
|
+
|
|
547
|
+
request_buffer = request.SerializeToString()
|
|
548
|
+
self.socket.send(request_buffer)
|
|
549
|
+
|
|
550
|
+
reply = tecrpc.Reply()
|
|
551
|
+
reply_buffer = self.socket.recv()
|
|
552
|
+
reply.ParseFromString(reply_buffer)
|
|
553
|
+
self.chk(reply)
|
|
554
|
+
|
|
555
|
+
def patch_tecutil(self):
|
|
556
|
+
'''Modify TecUtil interface according to historical changes in SDK.
|
|
557
|
+
|
|
558
|
+
2021.2
|
|
559
|
+
Facemap and FaceNeighbor connections now use zone unique IDs
|
|
560
|
+
(64-bit integers) instead of indices (32-bit integers).
|
|
561
|
+
Methods affected:
|
|
562
|
+
* Facemap.set_boundary_connections()
|
|
563
|
+
* FaceNeighbors.add_neighbors()
|
|
564
|
+
|
|
565
|
+
see also: TecUtilConnector.patch_tecutil()
|
|
566
|
+
'''
|
|
567
|
+
if self.sdk_version_info < (2021, 2):
|
|
568
|
+
|
|
569
|
+
def DataFaceMapAssignBConns(face_map,num_bndry_faces,
|
|
570
|
+
num_bndry_conns_array,
|
|
571
|
+
face_bndry_elems_array,
|
|
572
|
+
face_bndry_elem_zones_array):
|
|
573
|
+
args=((ValueType.Address,c_uint64,
|
|
574
|
+
getattr(face_map,'value',face_map)),
|
|
575
|
+
(ValueType.Scalar,c_int32,num_bndry_faces),
|
|
576
|
+
(ValueType.Array,c_int32,num_bndry_conns_array),
|
|
577
|
+
(ValueType.Array,c_int32,face_bndry_elems_array),
|
|
578
|
+
(ValueType.Array,c_int32,face_bndry_elem_zones_array),)
|
|
579
|
+
rep=self.sndrcv("DataFaceMapAssignBConns",*args)
|
|
580
|
+
self.chk(rep)
|
|
581
|
+
def DataFaceMapAssignBConns64(face_map,num_bndry_faces,
|
|
582
|
+
num_bndry_conns_array,
|
|
583
|
+
face_bndry_elems_array,
|
|
584
|
+
face_bndry_elem_zones_array):
|
|
585
|
+
args=((ValueType.Address,c_uint64,
|
|
586
|
+
getattr(face_map,'value',face_map)),
|
|
587
|
+
(ValueType.Scalar,c_int32,num_bndry_faces),
|
|
588
|
+
(ValueType.Array,c_int32,num_bndry_conns_array),
|
|
589
|
+
(ValueType.Array,c_int64,face_bndry_elems_array),
|
|
590
|
+
(ValueType.Array,c_int32,face_bndry_elem_zones_array),)
|
|
591
|
+
rep=self.sndrcv("DataFaceMapAssignBConns64",*args)
|
|
592
|
+
self.chk(rep)
|
|
593
|
+
def DataFaceNbrAssignByRef(face_neighbor,element,face,
|
|
594
|
+
nbrs_comp_obscure,num_neighbors,
|
|
595
|
+
neighbor_elems,
|
|
596
|
+
neighbor_zones):
|
|
597
|
+
args=((ValueType.Address,c_uint64,
|
|
598
|
+
getattr(face_neighbor,'value',face_neighbor)),
|
|
599
|
+
(ValueType.Scalar,c_int64,element),
|
|
600
|
+
(ValueType.Scalar,c_int32,face),
|
|
601
|
+
(ValueType.Scalar,c_bool,nbrs_comp_obscure),
|
|
602
|
+
(ValueType.Scalar,c_int32,num_neighbors),
|
|
603
|
+
(ValueType.Array,c_int32,neighbor_elems),
|
|
604
|
+
(ValueType.Array,c_int32,neighbor_zones),)
|
|
605
|
+
rep=self.sndrcv("DataFaceNbrAssignByRef",*args)
|
|
606
|
+
self.chk(rep)
|
|
607
|
+
return (rep.status == tecrpc.Reply.Success)
|
|
608
|
+
def DataFaceNbrAssignByRef64(face_neighbor,element,
|
|
609
|
+
face,nbrs_comp_obscure,num_neighbors,
|
|
610
|
+
neighbor_elems,
|
|
611
|
+
neighbor_zones):
|
|
612
|
+
args=((ValueType.Address,c_uint64,
|
|
613
|
+
getattr(face_neighbor,'value',face_neighbor)),
|
|
614
|
+
(ValueType.Scalar,c_int64,element),
|
|
615
|
+
(ValueType.Scalar,c_int32,face),
|
|
616
|
+
(ValueType.Scalar,c_bool,nbrs_comp_obscure),
|
|
617
|
+
(ValueType.Scalar,c_int32,num_neighbors),
|
|
618
|
+
(ValueType.Array,c_int64,neighbor_elems),
|
|
619
|
+
(ValueType.Array,c_int32,neighbor_zones),)
|
|
620
|
+
rep=self.sndrcv("DataFaceNbrAssignByRef64",*args)
|
|
621
|
+
self.chk(rep)
|
|
622
|
+
return (rep.status == tecrpc.Reply.Success)
|
|
623
|
+
|
|
624
|
+
self.DataFaceMapAssignBConns = DataFaceMapAssignBConns
|
|
625
|
+
self.DataFaceMapAssignBConns64 = DataFaceMapAssignBConns64
|
|
626
|
+
self.DataFaceNbrAssignByRef = DataFaceNbrAssignByRef
|
|
627
|
+
self.DataFaceNbrAssignByRef64 = DataFaceNbrAssignByRef64
|