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.
Files changed (97) hide show
  1. pytecplot-1.5.2.dist-info/LICENSE.html +77 -0
  2. pytecplot-1.5.2.dist-info/METADATA +508 -0
  3. pytecplot-1.5.2.dist-info/RECORD +97 -0
  4. pytecplot-1.5.2.dist-info/WHEEL +5 -0
  5. pytecplot-1.5.2.dist-info/top_level.txt +1 -0
  6. tecplot/__init__.py +94 -0
  7. tecplot/annotation/__init__.py +7 -0
  8. tecplot/annotation/annotation.py +223 -0
  9. tecplot/annotation/geometry.py +369 -0
  10. tecplot/annotation/georeference.py +33 -0
  11. tecplot/annotation/image.py +185 -0
  12. tecplot/annotation/iter.py +105 -0
  13. tecplot/annotation/polyline.py +381 -0
  14. tecplot/annotation/text.py +744 -0
  15. tecplot/constant.py +401 -0
  16. tecplot/data/__init__.py +34 -0
  17. tecplot/data/array.py +645 -0
  18. tecplot/data/create.py +1 -0
  19. tecplot/data/dataset.py +1809 -0
  20. tecplot/data/extract.py +544 -0
  21. tecplot/data/face_neighbors.py +494 -0
  22. tecplot/data/facemap.py +814 -0
  23. tecplot/data/load.py +2075 -0
  24. tecplot/data/nodemap.py +577 -0
  25. tecplot/data/operate.py +928 -0
  26. tecplot/data/query.py +334 -0
  27. tecplot/data/save.py +343 -0
  28. tecplot/data/variable.py +280 -0
  29. tecplot/data/zone.py +841 -0
  30. tecplot/exception.py +201 -0
  31. tecplot/export/__init__.py +13 -0
  32. tecplot/export/animation.py +521 -0
  33. tecplot/export/export_setup.py +318 -0
  34. tecplot/export/image.py +577 -0
  35. tecplot/export/print_setup.py +218 -0
  36. tecplot/export/time_animation.py +607 -0
  37. tecplot/extension/__init__.py +14 -0
  38. tecplot/extension/ipython.py +68 -0
  39. tecplot/layout/__init__.py +20 -0
  40. tecplot/layout/frame.py +1285 -0
  41. tecplot/layout/layout.py +488 -0
  42. tecplot/layout/page.py +541 -0
  43. tecplot/legend/__init__.py +4 -0
  44. tecplot/legend/contour_legend.py +516 -0
  45. tecplot/legend/legend.py +141 -0
  46. tecplot/legend/line_legend.py +66 -0
  47. tecplot/legend/rgb_coloring_legend.py +291 -0
  48. tecplot/legend/scatter_legend.py +136 -0
  49. tecplot/macro.py +339 -0
  50. tecplot/plot/__init__.py +62 -0
  51. tecplot/plot/axes.py +881 -0
  52. tecplot/plot/axis.py +1350 -0
  53. tecplot/plot/blanking.py +584 -0
  54. tecplot/plot/contour.py +1302 -0
  55. tecplot/plot/effects.py +162 -0
  56. tecplot/plot/fieldmap.py +2159 -0
  57. tecplot/plot/grid.py +758 -0
  58. tecplot/plot/isosurface.py +1167 -0
  59. tecplot/plot/labels.py +338 -0
  60. tecplot/plot/linemap.py +1905 -0
  61. tecplot/plot/linking.py +489 -0
  62. tecplot/plot/plot.py +1791 -0
  63. tecplot/plot/rgb_coloring.py +281 -0
  64. tecplot/plot/scatter.py +396 -0
  65. tecplot/plot/slice.py +1544 -0
  66. tecplot/plot/streamtrace.py +1949 -0
  67. tecplot/plot/symbol.py +567 -0
  68. tecplot/plot/ticks.py +666 -0
  69. tecplot/plot/title.py +380 -0
  70. tecplot/plot/vector.py +679 -0
  71. tecplot/plot/view.py +868 -0
  72. tecplot/session/__init__.py +112 -0
  73. tecplot/session/aux_data.py +276 -0
  74. tecplot/session/config.py +92 -0
  75. tecplot/session/session.py +425 -0
  76. tecplot/session/state_changed.py +225 -0
  77. tecplot/session/style.py +504 -0
  78. tecplot/tecutil/__init__.py +16 -0
  79. tecplot/tecutil/arglist.py +230 -0
  80. tecplot/tecutil/captured_output.py +177 -0
  81. tecplot/tecutil/constant.py +1312 -0
  82. tecplot/tecutil/index_set.py +118 -0
  83. tecplot/tecutil/lock.py +36 -0
  84. tecplot/tecutil/message_pb2.py +39 -0
  85. tecplot/tecutil/preamble.py +54 -0
  86. tecplot/tecutil/stringlist.py +114 -0
  87. tecplot/tecutil/sv.py +1662 -0
  88. tecplot/tecutil/tecutil.py +12402 -0
  89. tecplot/tecutil/tecutil_client.py +627 -0
  90. tecplot/tecutil/tecutil_connector.py +937 -0
  91. tecplot/tecutil/tecutil_rpc.py +6845 -0
  92. tecplot/tecutil/util.py +332 -0
  93. tecplot/text/__init__.py +3 -0
  94. tecplot/text/font.py +224 -0
  95. tecplot/text/label_format.py +374 -0
  96. tecplot/text/textbox.py +106 -0
  97. tecplot/version.py +41 -0
@@ -0,0 +1,494 @@
1
+ from builtins import super
2
+
3
+ import logging
4
+ import itertools as it
5
+
6
+ from collections import namedtuple
7
+ from contextlib import contextmanager
8
+ from ctypes import c_int32, c_int64, c_void_p, POINTER, addressof, cast
9
+ from textwrap import dedent
10
+
11
+ from ..tecutil import _tecutil
12
+ from ..constant import *
13
+ from ..exception import *
14
+ from .. import session, tecutil, version
15
+
16
+ log = logging.getLogger(__name__)
17
+
18
+
19
+ @tecutil.lock_attributes
20
+ class FaceNeighbors(c_void_p):
21
+ r"""Face neighbor definition and control.
22
+
23
+ Face neighbors are used when the face of an element overlaps with another
24
+ face from another element. Specifying these two (or more) overlapping faces
25
+ as "face neighbors" indicates element connections outside the implicit
26
+ faces of the nodemap. By specifying face neighbors it ensures that plot
27
+ elements like shading, creases and edges are treated continously even if
28
+ there is a zone or cell boundry.
29
+
30
+ The neighbors can be completely "local", within a single zone, or "global"
31
+ conntecting two or more zones together. Furthermore, the connections made
32
+ can be one-to-one meaning there any given face can only neighbor one other
33
+ face, or one-to-many where a single face can neighbor several other faces.
34
+
35
+ This example creates two triangles in two different zones. Global
36
+ one-to-one face neighbors are then used to stitch the two triangles into a
37
+ quad. The data created looks like this:
38
+
39
+ .. code-block:: none
40
+
41
+ Node positions (x,y,z):
42
+
43
+ (1,1,1)
44
+ *
45
+ / \
46
+ / \
47
+ (0,1,.5) *-----* (1,0,.5)
48
+ \ /
49
+ \ /
50
+ *
51
+ (0,0,0)
52
+
53
+ The two triangles will have separate nodes at the shared locations:
54
+
55
+ .. code-block:: none
56
+
57
+ Nodes:
58
+ 2
59
+ Zone 1: / \
60
+ / \
61
+ 1-----0
62
+ 2-----1
63
+ \ /
64
+ Zone 0: \ /
65
+ 0
66
+
67
+ .. code-block:: python
68
+ :emphasize-lines: 50-51
69
+
70
+ import tecplot as tp
71
+ from tecplot.constant import *
72
+
73
+ # Triangle 0
74
+ nodes0 = (
75
+ (0, 0, 0 ),
76
+ (1, 0, 0.5),
77
+ (0, 1, 0.5))
78
+ scalar_data0 = (0, 1, 2)
79
+ conn0 = ((0, 1, 2),)
80
+ neighbors0 = ((None, 0, None),)
81
+ neighbor_zones0 = ((None, 1, None),)
82
+
83
+ # Triangle 1
84
+ nodes1 = (
85
+ (1, 0, 0.5),
86
+ (0, 1, 0.5),
87
+ (1, 1, 1 ))
88
+ scalar_data1 = (1, 2, 3)
89
+ conn1 = ((0, 1, 2),)
90
+ neighbors1 = ((0, None, None),)
91
+ neighbor_zones1 = ((0, None, None),)
92
+
93
+ # Create the dataset and zones
94
+ ds = tp.active_frame().create_dataset('Data', ['x','y','z','s'])
95
+ z0 = ds.add_fe_zone(ZoneType.FETriangle,
96
+ name='FE Triangle Float (3,1) Nodal 0',
97
+ num_points=len(nodes0), num_elements=len(conn0),
98
+ face_neighbor_mode=FaceNeighborMode.GlobalOneToOne)
99
+ z1 = ds.add_fe_zone(ZoneType.FETriangle,
100
+ name='FE Triangle Float (3,1) Nodal 1',
101
+ num_points=len(nodes1), num_elements=len(conn1),
102
+ face_neighbor_mode=FaceNeighborMode.GlobalOneToOne)
103
+
104
+ # Fill in and connect first triangle
105
+ z0.values('x')[:] = [n[0] for n in nodes0]
106
+ z0.values('y')[:] = [n[1] for n in nodes0]
107
+ z0.values('z')[:] = [n[2] for n in nodes0]
108
+ z0.nodemap[:] = conn0
109
+ z0.values('s')[:] = scalar_data0
110
+
111
+ # Fill in and connect second triangle
112
+ z1.values('x')[:] = [n[0] for n in nodes1]
113
+ z1.values('y')[:] = [n[1] for n in nodes1]
114
+ z1.values('z')[:] = [n[2] for n in nodes1]
115
+ z1.nodemap[:] = conn1
116
+ z1.values('s')[:] = scalar_data1
117
+
118
+ # Set face neighbors
119
+ z0.face_neighbors.set_neighbors(neighbors0, neighbor_zones0, obscures=True)
120
+ z1.face_neighbors.set_neighbors(neighbors1, neighbor_zones1, obscures=True)
121
+
122
+
123
+ ### Setup a view of the data
124
+ plot = tp.active_frame().plot(PlotType.Cartesian3D)
125
+ plot.activate()
126
+
127
+ plot.contour(0).colormap_name = 'Sequential - Yellow/Green/Blue'
128
+ plot.contour(0).colormap_filter.distribution = ColorMapDistribution.Continuous
129
+
130
+ for ax in plot.axes:
131
+ ax.show = True
132
+
133
+ plot.show_mesh = False
134
+ plot.show_contour = True
135
+ plot.show_edge = True
136
+ plot.use_translucency = True
137
+
138
+ # View parameters obtained interactively from Tecplot 360
139
+ plot.view.distance = 10
140
+ plot.view.width = 2
141
+ plot.view.psi = 80
142
+ plot.view.theta = 30
143
+ plot.view.alpha = 0
144
+ plot.view.position = (-4.2, -8.0, 2.3)
145
+
146
+ fmaps = plot.fieldmaps()
147
+ fmaps.surfaces.surfaces_to_plot = SurfacesToPlot.All
148
+ fmaps.effects.surface_translucency = 40
149
+
150
+ # Turning on mesh, we can see all the individual triangles
151
+ plot.show_mesh = True
152
+ fmaps.mesh.line_pattern = LinePattern.Dashed
153
+
154
+ plot.contour(0).levels.reset_to_nice()
155
+ tp.export.save_png('fe_triangles1.png', 600, supersample=3)
156
+
157
+ .. figure:: /_static/images/fe_triangles1.png
158
+ :width: 300px
159
+ :figwidth: 300px
160
+
161
+ Two triangles in two separate zones, stitched together using global
162
+ face neighbors, showing the edge and mesh.
163
+ """
164
+ def __init__(self, zone):
165
+ self.zone = zone
166
+ super().__init__(self._native_reference())
167
+
168
+ @tecutil.lock()
169
+ def _native_reference(self):
170
+ return _tecutil.DataFaceNbrGetReadableRef(self.zone.index + 1)
171
+
172
+ def __eq__(self, other):
173
+ self_addr = addressof(cast(self , POINTER(c_int64)).contents)
174
+ other_addr = addressof(cast(other, POINTER(c_int64)).contents)
175
+ return self_addr == other_addr
176
+
177
+ def __ne__(self, other):
178
+ return not (self == other)
179
+
180
+ @property
181
+ def c_type(self):
182
+ """Underlying storage type used by the Tecplot Engine.
183
+
184
+ Possible values: `ctypes.c_int32`, ctypes.c_int64`.
185
+
186
+ .. note:: This property is read-only.
187
+ """
188
+ _ctypes = {
189
+ OffsetDataType.OffsetDataType_32Bit: c_int32,
190
+ OffsetDataType.OffsetDataType_64Bit: c_int64}
191
+ data_type = _tecutil.DataFaceNbrRawItemType(self)
192
+ return _ctypes[data_type]
193
+
194
+ @property
195
+ def mode(self):
196
+ """`FaceNeighborMode`: Relative locality of the face neighbors.
197
+
198
+ Possible values: `FaceNeighborMode.LocalOneToOne`,
199
+ `FaceNeighborMode.LocalOneToMany`,
200
+ `FaceNeighborMode.GlobalOneToOne`,
201
+ `FaceNeighborMode.GlobalOneToMany`.
202
+
203
+ .. note:: This property is read-only.
204
+
205
+ Face neighbors are used when the face of an element overlaps with
206
+ another face from another element. The neighbors can be completely
207
+ "local", within a single zone, or "global" conntecting two or more
208
+ zones together. Furthermore, the connections made can be one-to-one
209
+ meaning there any given face can only neighbor one other face, or
210
+ one-to-many where a single face can neighbor several other faces. The
211
+ face neighbor mode is set on zone creation and can not be changed
212
+ afterwards::
213
+
214
+ >>> zone = dataset.add_fe_zone(ZoneType.FETriangle, 'Zone', 4, 2,
215
+ ... face_neighbor_mode=FaceNeighborMode.LocalOneToMany)
216
+ >>> print(zone.face_neighbors.mode)
217
+ FaceNeighborMode.LocalOneToMany
218
+ """
219
+ return _tecutil.DataFaceNbrGetModeByRef(self)
220
+
221
+ def set_neighbors(self, neighbors, zones=None, obscures=False):
222
+ """Clear and set face neighbors from the given array.
223
+
224
+ Parameters:
225
+ neighbors (array of `integers <int>`): Zero-based Element indices
226
+ of the neighbors for each face in the zone. A value of
227
+ :math:`-1` or `None` indicates no neighbor.
228
+ zones (array of `Zones <data_access>`, optional): This parameter is
229
+ only used when the face neighbor mode is global one-to-one or
230
+ global one-to-many. (default: `None`)
231
+ obscures (array of `booleans <bool>`, optional): Indicates that the
232
+ neighbors completely obscure the face. (default: `False`)
233
+
234
+ This method uses the `FaceNeighbors.assignment()` context internally to
235
+ ensure the proper book keeping is done. See the example code for
236
+ `FaceNeighbors` class object for details on how to use this method.
237
+ """
238
+ with self.assignment():
239
+ for elem, faces in enumerate(neighbors):
240
+ for face, face_neighbors in enumerate(faces):
241
+ if face_neighbors is None:
242
+ continue
243
+ elif face_neighbors == -1:
244
+ continue
245
+
246
+ if not hasattr(face_neighbors, '__iter__'):
247
+ face_neighbors = [face_neighbors]
248
+ if zones is None:
249
+ neighbor_zones = None
250
+ else:
251
+ z = zones[elem][face]
252
+ if not hasattr(z, '__iter__'):
253
+ z = [z]
254
+ neighbor_zones = z
255
+ if hasattr(obscures, '__iter__'):
256
+ if hasattr(obscures[elem], '__iter__'):
257
+ obscure = obscures[elem][face]
258
+ else:
259
+ obscure = obscures[elem]
260
+ else:
261
+ obscure = obscures
262
+ self.add_neighbors(elem, face, face_neighbors,
263
+ neighbor_zones, obscure)
264
+
265
+ def add_neighbors(self, element, face, neighbors, zones=None,
266
+ obscure=False):
267
+ """Connect boundary of an element's face to a neighboring face.
268
+
269
+ This sets the boundary connection face neighbors within an open face
270
+ neighbor assignment sequence for the specified element and face.
271
+
272
+ Parameters:
273
+ element (`int`): The element number (zero-based).
274
+ face (`int`): The face number on the element (zero-based).
275
+ neighbors (`list` of `integers <int>` or `None`): List of
276
+ zero-based indices of the neighboring faces.
277
+ zones (`list` of zone objects, optional): List of zones for
278
+ global neighbors. This must be the same length as
279
+ ``neighbors``. Use `None` to indicate these are local
280
+ neighbors. (default: `None`)
281
+ obscure (`bool`, optional): Indicates that the neighbors
282
+ completely obscure the face. (default: `False`)
283
+
284
+ This method must be called from within a `FaceNeighbors.assignment()`
285
+ context which will clear any previously existing face neighbor data::
286
+
287
+ >>> with zone.face_neighbors.assigment():
288
+ ... for elem, face, neighbors, zn in face_neighbor_data:
289
+ ... zone.face_neighbors.add_neighbors(elem, face,
290
+ ... neighbors, zn)
291
+
292
+ See the example code for `FaceNeighbors` class object for more details
293
+ on how to set up user-defined face neighbors.
294
+ """
295
+ if __debug__:
296
+ if zones is not None and len(neighbors) != len(zones):
297
+ msg = 'neighbors and zones must be the same length'
298
+ raise TecplotLogicError(msg)
299
+
300
+ _dispatch = {
301
+ c_int32: _tecutil.DataFaceNbrAssignByRef,
302
+ c_int64: _tecutil.DataFaceNbrAssignByRef64}
303
+ int_type = self.c_type
304
+
305
+ def _add_one(arr):
306
+ def _f(x):
307
+ return x + 1 if x is not None else 0
308
+ return list(map(_f, arr))
309
+
310
+ def _add_one_index(arr):
311
+ def _f(x):
312
+ return getattr(x, 'index', x) + 1 if x is not None else 0
313
+ return list(map(_f, arr))
314
+
315
+ n = len(neighbors)
316
+
317
+ if __debug__:
318
+ if min(neighbors) < 0 or self.zone.num_faces <= max(neighbors):
319
+ raise TecplotIndexError
320
+ if zones:
321
+ if min(zones) < 0 or self.zone.dataset.num_zones <= max(zones):
322
+ raise TecplotIndexError
323
+ log.debug(dedent('''\
324
+ Face Neighbor Assign:
325
+ elem: {},
326
+ face: {},
327
+ obs: {},
328
+ n: {},
329
+ nbrs: {},
330
+ zns: {}''').format(
331
+ element + 1, face + 1, obscure, n,
332
+ tecutil.array_to_str(neighbors),
333
+ tecutil.array_to_str(zones)))
334
+
335
+ neighbors = (int_type * n)(*_add_one(neighbors))
336
+ zone_unique_ids = None
337
+ if zones is not None:
338
+ zones = (c_int32 * n)(*_add_one_index(zones))
339
+ if version.sdk_version_info >= (2021, 2):
340
+ # The TecUtil API 2021.2+ requires boundary zone unique IDs.
341
+ zone_uids = (c_int64 * n)()
342
+ _tecutil.DataSetGetUniqueIDsForZones(zones, n, zone_uids)
343
+ zones = zone_uids
344
+
345
+ args = (element + 1, face + 1, obscure, n, neighbors, zones)
346
+ if not _dispatch[int_type](self, *args):
347
+ raise TecplotSystemError()
348
+
349
+ def add_local_neighbors(self, neighbors, offset=0):
350
+ """Assign all local one-to-one face neighbors at once.
351
+
352
+ Parameters:
353
+ neighbors (2D array of `integers <int>`): :math:`(E,F)` Array of
354
+ the face neighbors where :math:`E` is the number of elements
355
+ and :math:`F` is the number of faces per element.
356
+ offset (`int`, optional): Offset in Tecplot's face
357
+ neighbor array to begin assigning the supplied neighbor
358
+ elements. (default: 0)
359
+
360
+ This method must be called from within a `FaceNeighbors.assignment()`
361
+ context which will clear any previously existing face neighbor data::
362
+
363
+ >>> with zone.face_neighbors.assigment():
364
+ ... zone.face_neighbors.add_local_neighbors(neighbors)
365
+
366
+ See the example code for `FaceNeighbors` class object for more details
367
+ on how to set up user-defined face neighbors.
368
+ """
369
+ _dispatch = {
370
+ c_int32: _tecutil.DataFaceNbrAssignArrayByRef,
371
+ c_int64: _tecutil.DataFaceNbrAssignArrayByRef64}
372
+ int_type = self.c_type
373
+
374
+ def _flatten_add_one(arr):
375
+ def _add_one(x):
376
+ return x + 1 if x is not None else 0
377
+ return list(map(_add_one, it.chain(*arr)))
378
+
379
+ neighbors = _flatten_add_one(neighbors)
380
+ n = len(neighbors)
381
+ neighbors = (int_type * n)(*neighbors)
382
+
383
+ if __debug__:
384
+ if min(neighbors) < 0 or self.zone.num_faces < max(neighbors):
385
+ raise TecplotIndexError
386
+ log.debug(dedent('''\
387
+ Face Neighbor Assign Array:
388
+ offset: {},
389
+ nbrs({}): {}''').format(offset + 1, n,
390
+ tecutil.array_to_str(neighbors)))
391
+
392
+ _dispatch[int_type](self, offset + 1, n, neighbors)
393
+
394
+ @contextmanager
395
+ def assignment(self):
396
+ """Context manager for assigning face neighbors.
397
+
398
+ This context ensures the proper book keeping is done when setting face
399
+ neighbors. After the face neighbors are specified, this context will
400
+ valid the connections and make appropriate changes to the zone
401
+ metadata. It must be used with the
402
+ `FaceNeighbors.add_local_neighbors()` and/or
403
+ `FaceNeighbors.add_neighbors()` methods. See the `FaceNeighbors`
404
+ example code for more details on how to set up user-defined face
405
+ neighbors.
406
+
407
+ """
408
+ with tecutil.lock():
409
+ if not _tecutil.DataFaceNbrBeginAssign(self.zone.index + 1):
410
+ raise TecplotSystemError()
411
+ try:
412
+ yield
413
+ finally:
414
+ _tecutil.DataFaceNbrEndAssign()
415
+ c_void_p.__init__(self, self._native_reference())
416
+
417
+ _Neighbor = namedtuple('Neighbor', ['element', 'zone'])
418
+
419
+ def neighbors(self, element, face):
420
+ """Get the neighboring elements and zones of a specific face.
421
+
422
+ Parameters:
423
+ element (`int`): The zero-based index of the element.
424
+ face (`int`): The zero-based index of the face on this
425
+ element.
426
+
427
+ Returns:
428
+ `list` of `namedtuples <collections.namedtuple>`:
429
+ ``(element, zone)``:
430
+ ``element``:
431
+ The zero-based index of the neighboring element.
432
+ ``zone``:
433
+ The zone holding the neighboring element. A value of `None`
434
+ indicates this is a local (intra-zone) neighbor connection.
435
+
436
+ Example getting the neighboring faces of a zone's first element, second
437
+ face::
438
+
439
+ >>> neighbors = zone.face_neighbors.neighbors(element=0, face=1)
440
+ >>> for neighbor in neighbors:
441
+ ... elem, zn = neighbor
442
+ ... print(elem, zn.index)
443
+ 21 2
444
+ """
445
+ element = element + 1
446
+ face = face + 1
447
+ n, user_spec = _tecutil.DataFaceNbrGetNumNByRef(self, element, face)
448
+ neighbors = []
449
+ for i in range(1, n + 1):
450
+ res = _tecutil.DataFaceNbrGetNbrByRef(self, element, face, i)
451
+ neighbor_elem, neighbor_zone = res
452
+ neighbor_elem -= 1
453
+ if neighbor_zone == 0:
454
+ neighbor_zone = None
455
+ else:
456
+ neighbor_zone = self.zone.dataset.zone(neighbor_zone - 1)
457
+ neighbor = FaceNeighbors._Neighbor(neighbor_elem, neighbor_zone)
458
+ neighbors.append(neighbor)
459
+ return neighbors
460
+
461
+ def is_obscured(self, element, face, active_zones=None):
462
+ """Obscuration of the specified face.
463
+
464
+ Parameters:
465
+ element (`int`): The zero-based index of the element.
466
+ face (`int`): The zero-based index of the face on the
467
+ element.
468
+ active_zones (`list` of `Zones <data_access>`): List of zones to
469
+ consider when global face neighbors are present. If `None`,
470
+ the active zones of the dataset's parent frame will be used.
471
+
472
+ Returns:
473
+ `bool`
474
+
475
+ .. note::
476
+
477
+ Because datasets can be shared between frames, the default frame
478
+ used to identify the active zones may not be the one you want. In
479
+ this case, you can use the `Frame.active_zones()` method to provide
480
+ the active zones for a specific frame. Furthermore, the plot type
481
+ of the frame must have the concept of active zones - i.e. it must
482
+ not be in "sketch" mode.
483
+
484
+ Example usage::
485
+
486
+ >>> zone.face_neighbors.is_obscured(element=0, face=1)
487
+ True
488
+ """
489
+ if active_zones is None:
490
+ frame = self.zone.dataset.frame
491
+ active_zones = frame.active_zones()
492
+ with tecutil.IndexSet(*active_zones) as active_zones:
493
+ return _tecutil.DataFaceNbrFaceIsObscured(self, element + 1,
494
+ face + 1, active_zones)