ansys-pyensight-core 0.8.10__tar.gz → 0.8.12__tar.gz
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.
Potentially problematic release.
This version of ansys-pyensight-core might be problematic. Click here for more details.
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/PKG-INFO +10 -8
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/pyproject.toml +10 -8
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/deep_pixel_view.html +10 -10
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/libuserd.py +171 -50
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/locallauncher.py +2 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/renderable.py +12 -3
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/dsg_server.py +27 -5
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/omniverse.py +3 -3
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/omniverse_cli.py +33 -24
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/omniverse_dsg_server.py +3 -1
- ansys_pyensight_core-0.8.12/src/ansys/pyensight/core/utils/omniverse_glb_server.py +625 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/parts.py +1 -1
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/variables.py +1 -1
- ansys_pyensight_core-0.8.10/src/ansys/pyensight/core/utils/omniverse_glb_server.py +0 -279
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/LICENSE +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/README.rst +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/__init__.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/common.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/dockerlauncher.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/enscontext.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/enshell_grpc.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/ensight_grpc.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/ensobj.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/launch_ensight.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/launcher.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/listobj.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/py.typed +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/session.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/sgeo_poll.html +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/__init__.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/adr.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/export.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/query.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/readers.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/resources/Materials/000_sky.exr +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/support.py +0 -0
- {ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/utils/views.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ansys-pyensight-core
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.12
|
|
4
4
|
Summary: A python wrapper for Ansys EnSight
|
|
5
5
|
Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
6
6
|
Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
@@ -32,27 +32,29 @@ Requires-Dist: ipdb>=0.9.4 ; extra == "dev"
|
|
|
32
32
|
Requires-Dist: dill>=0.3.5.1 ; extra == "dev"
|
|
33
33
|
Requires-Dist: pre-commit>=3.3.3 ; extra == "dev"
|
|
34
34
|
Requires-Dist: Sphinx==8.0.2 ; extra == "doc"
|
|
35
|
-
Requires-Dist: numpydoc==1.
|
|
36
|
-
Requires-Dist: ansys-sphinx-theme==
|
|
35
|
+
Requires-Dist: numpydoc==1.8.0 ; extra == "doc"
|
|
36
|
+
Requires-Dist: ansys-sphinx-theme==1.1.1 ; extra == "doc"
|
|
37
37
|
Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "doc"
|
|
38
|
-
Requires-Dist: sphinx-gallery==0.
|
|
38
|
+
Requires-Dist: sphinx-gallery==0.17.1 ; extra == "doc"
|
|
39
39
|
Requires-Dist: sphinxcontrib-mermaid==0.9.2 ; extra == "doc"
|
|
40
40
|
Requires-Dist: docker>=6.1.0 ; extra == "doc"
|
|
41
41
|
Requires-Dist: matplotlib==3.9.1.post1 ; extra == "doc"
|
|
42
42
|
Requires-Dist: requests>=2.28.2 ; extra == "doc"
|
|
43
43
|
Requires-Dist: sphinxcontrib.jquery==4.1 ; extra == "doc"
|
|
44
|
-
Requires-Dist:
|
|
45
|
-
Requires-Dist:
|
|
46
|
-
Requires-Dist: sphinxcontrib-video==0.2.
|
|
44
|
+
Requires-Dist: sphinxcontrib-openapi==0.8.4 ; extra == "doc"
|
|
45
|
+
Requires-Dist: coverage-badge==1.1.2 ; extra == "doc"
|
|
46
|
+
Requires-Dist: sphinxcontrib-video==0.2.1 ; extra == "doc"
|
|
47
47
|
Requires-Dist: usd-core>=24.8 ; extra == "doc"
|
|
48
48
|
Requires-Dist: pygltflib>=1.16.2 ; extra == "doc"
|
|
49
49
|
Requires-Dist: pytest==8.3.2 ; extra == "tests"
|
|
50
|
-
Requires-Dist: pytest-cov==
|
|
50
|
+
Requires-Dist: pytest-cov==5.0.0 ; extra == "tests"
|
|
51
51
|
Requires-Dist: dill>=0.3.5.1 ; extra == "tests"
|
|
52
52
|
Requires-Dist: pytest-mock==3.10.0 ; extra == "tests"
|
|
53
53
|
Requires-Dist: urllib3==2.2.2 ; extra == "tests"
|
|
54
54
|
Requires-Dist: requests>=2.28.2 ; extra == "tests"
|
|
55
55
|
Requires-Dist: docker>=6.1.0 ; extra == "tests"
|
|
56
|
+
Requires-Dist: pytest-xdist==1.31.0 ; extra == "tests"
|
|
57
|
+
Requires-Dist: pytest-rerunfailures~=14.0 ; extra == "tests"
|
|
56
58
|
Project-URL: Changelog, https://github.com/ansys/pyensight/blob/main/CHANGELOG.rst
|
|
57
59
|
Project-URL: Documentation, https://ensight.docs.pyansys.com/
|
|
58
60
|
Project-URL: Homepage, https://github.com/ansys/pyensight
|
|
@@ -6,7 +6,7 @@ build-backend = "flit_core.buildapi"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "ansys-pyensight-core"
|
|
9
|
-
version = "0.8.
|
|
9
|
+
version = "0.8.12"
|
|
10
10
|
description = "A python wrapper for Ansys EnSight"
|
|
11
11
|
readme = "README.rst"
|
|
12
12
|
requires-python = ">=3.9,<4"
|
|
@@ -49,27 +49,29 @@ dev = [
|
|
|
49
49
|
]
|
|
50
50
|
tests = [
|
|
51
51
|
"pytest==8.3.2",
|
|
52
|
-
"pytest-cov==
|
|
52
|
+
"pytest-cov==5.0.0",
|
|
53
53
|
"dill>=0.3.5.1",
|
|
54
54
|
"pytest-mock==3.10.0",
|
|
55
55
|
"urllib3==2.2.2",
|
|
56
56
|
"requests>=2.28.2",
|
|
57
57
|
"docker>=6.1.0",
|
|
58
|
+
"pytest-xdist==1.31.0",
|
|
59
|
+
"pytest-rerunfailures~=14.0",
|
|
58
60
|
]
|
|
59
61
|
doc = [
|
|
60
62
|
"Sphinx==8.0.2",
|
|
61
|
-
"numpydoc==1.
|
|
62
|
-
"ansys-sphinx-theme==
|
|
63
|
+
"numpydoc==1.8.0",
|
|
64
|
+
"ansys-sphinx-theme==1.1.1",
|
|
63
65
|
"sphinx-copybutton==0.5.2",
|
|
64
|
-
"sphinx-gallery==0.
|
|
66
|
+
"sphinx-gallery==0.17.1",
|
|
65
67
|
"sphinxcontrib-mermaid==0.9.2",
|
|
66
68
|
"docker>=6.1.0",
|
|
67
69
|
"matplotlib==3.9.1.post1",
|
|
68
70
|
"requests>=2.28.2",
|
|
69
71
|
"sphinxcontrib.jquery==4.1",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"sphinxcontrib-video==0.2.
|
|
72
|
+
"sphinxcontrib-openapi==0.8.4",
|
|
73
|
+
"coverage-badge==1.1.2",
|
|
74
|
+
"sphinxcontrib-video==0.2.1",
|
|
73
75
|
"usd-core>=24.8",
|
|
74
76
|
"pygltflib>=1.16.2",
|
|
75
77
|
]
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<link rel="stylesheet" type="text/css" href="/bootstrap.min.cssOPTIONAL_QUERY"/>
|
|
5
5
|
|
|
6
|
-
<script src='/
|
|
6
|
+
<script src='/jqueryJQUERY_VERSION.min.jsOPTIONAL_QUERY'></script>
|
|
7
7
|
<script src='/geotiff.jsOPTIONAL_QUERY'></script>
|
|
8
8
|
<script src='/geotiff_nexus.jsOPTIONAL_QUERY'></script>
|
|
9
9
|
<script src="/bootstrap.min.jsOPTIONAL_QUERY"></script>
|
|
@@ -76,15 +76,15 @@
|
|
|
76
76
|
<div style="margin: 0 auto; display:flex; justify-content:center;">
|
|
77
77
|
<!-- tooltip parent for img --->
|
|
78
78
|
<div id="probe_display_ITEMID"
|
|
79
|
-
data-
|
|
80
|
-
data-
|
|
81
|
-
data-
|
|
82
|
-
data-
|
|
83
|
-
data-
|
|
84
|
-
data-
|
|
85
|
-
data-
|
|
86
|
-
data-
|
|
87
|
-
data-
|
|
79
|
+
data-BS_PREFIXtoggle="tooltip"
|
|
80
|
+
data-BS_PREFIXplacement="bottom"
|
|
81
|
+
data-BS_PREFIXfallbackPlacement="['top', 'right']"
|
|
82
|
+
data-BS_PREFIXhtml="true"
|
|
83
|
+
data-BS_PREFIXcontainer="body"
|
|
84
|
+
data-BS_PREFIXboundary="viewport"
|
|
85
|
+
data-BS_PREFIXanimation="false"
|
|
86
|
+
data-BS_PREFIXtrigger="manual"
|
|
87
|
+
data-BS_PREFIXtitle='<span class="f-1r">
|
|
88
88
|
<span>X, Y : <span id="probe_xy_ITEMID">0, 0</span></span>
|
|
89
89
|
<br>
|
|
90
90
|
<span id="probe_result_ITEMID"></span>
|
{ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/libuserd.py
RENAMED
|
@@ -63,6 +63,22 @@ warnings.warn(
|
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
|
|
66
|
+
def _build_enum(name: str, pb_enum: Any, flag: bool = False) -> Union[enum.IntEnum, enum.IntFlag]:
|
|
67
|
+
values = {}
|
|
68
|
+
for v in pb_enum:
|
|
69
|
+
values[v[0]] = v[1]
|
|
70
|
+
if flag:
|
|
71
|
+
return enum.IntFlag(name, values)
|
|
72
|
+
return enum.IntEnum(name, values)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
ErrorCodes = _build_enum("ErrorCodes", libuserd_pb2.ErrorCodes.items())
|
|
76
|
+
ElementType = _build_enum("ElementType", libuserd_pb2.ElementType.items())
|
|
77
|
+
VariableLocation = _build_enum("VariableLocation", libuserd_pb2.VariableLocation.items())
|
|
78
|
+
VariableType = _build_enum("VariableType", libuserd_pb2.VariableType.items())
|
|
79
|
+
PartHints = _build_enum("PartHints", libuserd_pb2.PartHints.items(), flag=True)
|
|
80
|
+
|
|
81
|
+
|
|
66
82
|
class LibUserdError(Exception):
|
|
67
83
|
"""
|
|
68
84
|
This class is an exception object raised from the libuserd
|
|
@@ -179,9 +195,9 @@ class Variable(object):
|
|
|
179
195
|
The unit label of this variable, "Pa" for example.
|
|
180
196
|
unitDims : str
|
|
181
197
|
The dimensions of this variable, "L/S" for distance per second.
|
|
182
|
-
location : "
|
|
198
|
+
location : "VariableLocation"
|
|
183
199
|
The location of this variable.
|
|
184
|
-
type : "
|
|
200
|
+
type : "VariableType"
|
|
185
201
|
The type of this variable.
|
|
186
202
|
timeVarying : bool
|
|
187
203
|
True if the variable is time-varying.
|
|
@@ -200,8 +216,8 @@ class Variable(object):
|
|
|
200
216
|
self.name = pb.name
|
|
201
217
|
self.unitLabel = pb.unitLabel
|
|
202
218
|
self.unitDims = pb.unitDims
|
|
203
|
-
self.location =
|
|
204
|
-
self.type =
|
|
219
|
+
self.location = VariableLocation(pb.varLocation) # type: ignore
|
|
220
|
+
self.type = VariableType(pb.type) # type: ignore
|
|
205
221
|
self.timeVarying = pb.timeVarying
|
|
206
222
|
self.isComplex = pb.isComplex
|
|
207
223
|
self.interleaveFlag = pb.interleaveFlag
|
|
@@ -240,7 +256,7 @@ class Part(object):
|
|
|
240
256
|
reader_id : int
|
|
241
257
|
The id of the Reader this part is associated with.
|
|
242
258
|
hints : int
|
|
243
|
-
See: `
|
|
259
|
+
See: `PartHints`.
|
|
244
260
|
reader_api_version : float
|
|
245
261
|
The API version number of the USERD reader this part was read with.
|
|
246
262
|
metadata : Dict[str, str]
|
|
@@ -315,7 +331,7 @@ class Part(object):
|
|
|
315
331
|
>>> part = reader.parts()[0]
|
|
316
332
|
>>> elements = part.elements()
|
|
317
333
|
>>> for etype, count in elements.items():
|
|
318
|
-
... print(
|
|
334
|
+
... print(libuserd.ElementType(etype).name, count)
|
|
319
335
|
|
|
320
336
|
"""
|
|
321
337
|
self._userd.connect_check()
|
|
@@ -350,14 +366,14 @@ class Part(object):
|
|
|
350
366
|
--------
|
|
351
367
|
|
|
352
368
|
>>> part = reader.parts()[0]
|
|
353
|
-
>>> conn = part.element_conn(
|
|
354
|
-
>>> nodes_per_elem = libuserd_instance.nodes_per_element(
|
|
369
|
+
>>> conn = part.element_conn(libuserd.ElementType.HEX08)
|
|
370
|
+
>>> nodes_per_elem = libuserd_instance.nodes_per_element(libuserd.ElementType.HEX08)
|
|
355
371
|
>>> conn.shape = (len(conn)//nodes_per_elem, nodes_per_elem)
|
|
356
372
|
>>> for element in conn:
|
|
357
373
|
... print(element)
|
|
358
374
|
|
|
359
375
|
"""
|
|
360
|
-
if elem_type >=
|
|
376
|
+
if elem_type >= ElementType.NSIDED: # type: ignore
|
|
361
377
|
raise RuntimeError(f"Element type {elem_type} is not valid for this call")
|
|
362
378
|
pb = libuserd_pb2.Part_element_connRequest()
|
|
363
379
|
pb.part_id = self.id
|
|
@@ -375,7 +391,7 @@ class Part(object):
|
|
|
375
391
|
error = self._userd.libuserd_exception(e)
|
|
376
392
|
# if we get an "UNKNOWN" error, then return an empty array
|
|
377
393
|
if isinstance(error, LibUserdError):
|
|
378
|
-
if error.code ==
|
|
394
|
+
if error.code == ErrorCodes.UNKNOWN: # type: ignore
|
|
379
395
|
return numpy.empty(0, dtype=numpy.uint32)
|
|
380
396
|
raise error
|
|
381
397
|
return conn
|
|
@@ -601,6 +617,79 @@ class Reader(object):
|
|
|
601
617
|
for key in pb.metadata.keys():
|
|
602
618
|
self.metadata[key] = pb.metadata[key]
|
|
603
619
|
self.raw_metadata = pb.raw_metadata
|
|
620
|
+
self._timesets: List["numpy.array"] = []
|
|
621
|
+
self._update_timesets()
|
|
622
|
+
|
|
623
|
+
def _update_timesets(self) -> None:
|
|
624
|
+
"""
|
|
625
|
+
To simplify the interface to time, the timesets are all queried and
|
|
626
|
+
cached. Additionally, a "common timeset" is generated that combines
|
|
627
|
+
all the timevalues from all timesets into a single timeset which is
|
|
628
|
+
saved as "timeset 0".
|
|
629
|
+
|
|
630
|
+
This method reads all the timesets and generates the common timeset.
|
|
631
|
+
"""
|
|
632
|
+
if len(self._timesets):
|
|
633
|
+
return
|
|
634
|
+
num_timesets = self.get_number_of_time_sets()
|
|
635
|
+
# The common timeset
|
|
636
|
+
common = set()
|
|
637
|
+
self._timesets = [numpy.array([], dtype="float32")]
|
|
638
|
+
# The other timesets
|
|
639
|
+
for ts in range(1, num_timesets + 1):
|
|
640
|
+
v = self.timevalues(timeset=ts)
|
|
641
|
+
# merge into the common timeset
|
|
642
|
+
common.update(v)
|
|
643
|
+
self._timesets.append(v)
|
|
644
|
+
self._timesets[0] = numpy.array(sorted(list(common)))
|
|
645
|
+
|
|
646
|
+
def _common_set_step(self, s: int) -> None:
|
|
647
|
+
"""
|
|
648
|
+
When the common timeset is used in a ``set_timestep()`` call, this
|
|
649
|
+
method selects the time value from the common timeset and then calls
|
|
650
|
+
``_common_set_time()`` to change the current simulation time.
|
|
651
|
+
|
|
652
|
+
Parameters
|
|
653
|
+
----------
|
|
654
|
+
s : int
|
|
655
|
+
The index (timestep) in the common timeset to change the current time to.
|
|
656
|
+
|
|
657
|
+
Raises
|
|
658
|
+
------
|
|
659
|
+
RuntimeError
|
|
660
|
+
If the timestep index is invalid.
|
|
661
|
+
|
|
662
|
+
"""
|
|
663
|
+
try:
|
|
664
|
+
v = self._timesets[0][s]
|
|
665
|
+
self._common_set_time(v)
|
|
666
|
+
except IndexError:
|
|
667
|
+
raise RuntimeError(f"Invalid step number {s}.") from None
|
|
668
|
+
|
|
669
|
+
def _common_set_time(self, t: float) -> None:
|
|
670
|
+
"""
|
|
671
|
+
Change the current time value to the passed time value. This method
|
|
672
|
+
walks all the timesets. It selects the largest time value in each timeset
|
|
673
|
+
that is less than or equal to the specified time value. It then sets
|
|
674
|
+
the time value for each timeset accordingly.
|
|
675
|
+
|
|
676
|
+
Parameters
|
|
677
|
+
----------
|
|
678
|
+
t : float
|
|
679
|
+
The time value (in the common timeset) to change the reader simulation time to.
|
|
680
|
+
|
|
681
|
+
"""
|
|
682
|
+
# given the time float from the common timeline,
|
|
683
|
+
# change the timestep in all the timesets to match.
|
|
684
|
+
for timeset in range(1, len(self._timesets)):
|
|
685
|
+
# check for perfect match first (avoids rounding)
|
|
686
|
+
where = numpy.where(self._timesets[timeset] == t)
|
|
687
|
+
if len(where[0]):
|
|
688
|
+
timestep = where[0][0]
|
|
689
|
+
else:
|
|
690
|
+
timestep = numpy.searchsorted(self._timesets[timeset], t)
|
|
691
|
+
timestep = min(timestep, len(self._timesets[timeset]) - 1)
|
|
692
|
+
self.set_timestep(timestep, timeset=timeset)
|
|
604
693
|
|
|
605
694
|
def parts(self) -> List[Part]:
|
|
606
695
|
"""
|
|
@@ -671,6 +760,8 @@ class Reader(object):
|
|
|
671
760
|
int
|
|
672
761
|
The number of timesets.
|
|
673
762
|
"""
|
|
763
|
+
if len(self._timesets):
|
|
764
|
+
return len(self._timesets) - 1
|
|
674
765
|
self._userd.connect_check()
|
|
675
766
|
pb = libuserd_pb2.Reader_get_number_of_time_setsRequest()
|
|
676
767
|
try:
|
|
@@ -681,20 +772,27 @@ class Reader(object):
|
|
|
681
772
|
raise self._userd.libuserd_exception(e)
|
|
682
773
|
return reply.numberOfTimeSets
|
|
683
774
|
|
|
684
|
-
def timevalues(self, timeset: int =
|
|
775
|
+
def timevalues(self, timeset: int = 0) -> List[float]:
|
|
685
776
|
"""
|
|
686
|
-
Get a list of the time step values in this dataset.
|
|
777
|
+
Get a list of the time step values in this dataset for the specified timeset.
|
|
778
|
+
The default timeset is ``0`` which is a special, "common" timeset formed by
|
|
779
|
+
merging all the timesets in the data into a single timeset.
|
|
687
780
|
|
|
688
781
|
Parameters
|
|
689
782
|
----------
|
|
690
783
|
timeset : int, optional
|
|
691
|
-
The timestep to query (default is
|
|
784
|
+
The timestep to query (default is 0)
|
|
692
785
|
|
|
693
786
|
Returns
|
|
694
787
|
-------
|
|
695
|
-
|
|
696
|
-
|
|
788
|
+
numpy.array
|
|
789
|
+
The simulation time value floats.
|
|
697
790
|
"""
|
|
791
|
+
if timeset == 0:
|
|
792
|
+
try:
|
|
793
|
+
return self._timesets[timeset]
|
|
794
|
+
except IndexError:
|
|
795
|
+
return numpy.array([], dtype="float32")
|
|
698
796
|
self._userd.connect_check()
|
|
699
797
|
pb = libuserd_pb2.Reader_timevaluesRequest()
|
|
700
798
|
pb.timeSetNumber = timeset
|
|
@@ -704,18 +802,43 @@ class Reader(object):
|
|
|
704
802
|
raise self._userd.libuserd_exception(e)
|
|
705
803
|
return numpy.array(timevalues.timeValues)
|
|
706
804
|
|
|
707
|
-
def set_timevalue(self, timevalue: float, timeset: int =
|
|
805
|
+
def set_timevalue(self, timevalue: float, timeset: int = 0) -> None:
|
|
708
806
|
"""
|
|
709
|
-
Change the current time to the specified value.
|
|
710
|
-
|
|
807
|
+
Change the current time within the selected timeset to the specified value.
|
|
808
|
+
The default timeset selected is the merged "common" timeset ``0``. If the
|
|
809
|
+
"common" timeset is used, the appropriate time value will be set for
|
|
810
|
+
all timesets by this method.
|
|
711
811
|
|
|
712
812
|
Parameters
|
|
713
813
|
----------
|
|
714
814
|
timevalue : float
|
|
715
815
|
The time value to change the timestep closest to.
|
|
716
816
|
timeset : int, optional
|
|
717
|
-
The
|
|
718
|
-
|
|
817
|
+
The timeset to change (default is 0)
|
|
818
|
+
|
|
819
|
+
Examples
|
|
820
|
+
--------
|
|
821
|
+
>>> from ansys.pyensight.core import libuserd
|
|
822
|
+
>>> import numpy
|
|
823
|
+
>>> s = libuserd.LibUserd()
|
|
824
|
+
>>> s.initialize()
|
|
825
|
+
>>> opt = {'Long names': 0, 'Number of timesteps': 5, 'Number of scalars': 3,
|
|
826
|
+
... 'Number of spheres': 2, 'Number of cubes': 2}
|
|
827
|
+
>>> d = s.load_data("foo", file_format="Synthetic", reader_options=opt)
|
|
828
|
+
>>> parts = d.parts()
|
|
829
|
+
>>> for t in d.timevalues():
|
|
830
|
+
... d.set_timevalue(t)
|
|
831
|
+
... for p in parts:
|
|
832
|
+
... nodes = p.nodes()
|
|
833
|
+
... nodes.shape = (len(nodes)//3, 3)
|
|
834
|
+
... centroid = numpy.average(nodes, 0)
|
|
835
|
+
... print(f"Time: {t} Part: {p.name} Centroid: {centroid}")
|
|
836
|
+
>>> s.shutdown()
|
|
837
|
+
|
|
838
|
+
"""
|
|
839
|
+
if timeset == 0:
|
|
840
|
+
self._common_set_time(timevalue)
|
|
841
|
+
return
|
|
719
842
|
self._userd.connect_check()
|
|
720
843
|
pb = libuserd_pb2.Reader_set_timevalueRequest()
|
|
721
844
|
pb.timesetNumber = timeset
|
|
@@ -725,18 +848,24 @@ class Reader(object):
|
|
|
725
848
|
except grpc.RpcError as e:
|
|
726
849
|
raise self._userd.libuserd_exception(e)
|
|
727
850
|
|
|
728
|
-
def set_timestep(self, timestep: int, timeset: int =
|
|
851
|
+
def set_timestep(self, timestep: int, timeset: int = 0) -> None:
|
|
729
852
|
"""
|
|
730
853
|
Change the current time to the specified timestep. This call is the same as:
|
|
731
854
|
``reader.set_timevalue(reader.timevalues()[timestep])``.
|
|
855
|
+
The default timeset selected is the merged "common" timeset ``0``. If the
|
|
856
|
+
"common" timeset is used, the appropriate time value will be set for
|
|
857
|
+
all timesets by this method.
|
|
732
858
|
|
|
733
859
|
Parameters
|
|
734
860
|
----------
|
|
735
861
|
timestep : int
|
|
736
862
|
The timestep to change to.
|
|
737
863
|
timeset : int, optional
|
|
738
|
-
The
|
|
864
|
+
The timeset to change (default is 0)
|
|
739
865
|
"""
|
|
866
|
+
if timeset == 0:
|
|
867
|
+
self._common_set_step(timestep)
|
|
868
|
+
return
|
|
740
869
|
self._userd.connect_check()
|
|
741
870
|
pb = libuserd_pb2.Reader_set_timestepRequest()
|
|
742
871
|
pb.timeSetNumber = timeset
|
|
@@ -1034,27 +1163,12 @@ class LibUserd(object):
|
|
|
1034
1163
|
raise RuntimeError(f"Unable to start the gRPC server ({str(self.server_pathname)})")
|
|
1035
1164
|
|
|
1036
1165
|
def _build_enums(self) -> None:
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
self.
|
|
1042
|
-
|
|
1043
|
-
for v in libuserd_pb2.ElementType.items():
|
|
1044
|
-
values[v[0]] = v[1]
|
|
1045
|
-
self.ElementType = enum.IntEnum("ElementType", values) # type: ignore
|
|
1046
|
-
values = {}
|
|
1047
|
-
for v in libuserd_pb2.VariableLocation.items():
|
|
1048
|
-
values[v[0]] = v[1]
|
|
1049
|
-
self.VariableLocation = enum.IntEnum("VariableLocation", values) # type: ignore
|
|
1050
|
-
values = {}
|
|
1051
|
-
for v in libuserd_pb2.VariableType.items():
|
|
1052
|
-
values[v[0]] = v[1]
|
|
1053
|
-
self.VariableType = enum.IntEnum("VariableType", values) # type: ignore
|
|
1054
|
-
values = {}
|
|
1055
|
-
for v in libuserd_pb2.PartHints.items():
|
|
1056
|
-
values[v[0]] = v[1]
|
|
1057
|
-
self.PartHints = enum.IntEnum("PartHints", values) # type: ignore
|
|
1166
|
+
# retained for backward compatibility
|
|
1167
|
+
self.ErrorCodes = ErrorCodes
|
|
1168
|
+
self.ElementType = ElementType
|
|
1169
|
+
self.VariableLocation = VariableLocation
|
|
1170
|
+
self.VariableType = VariableType
|
|
1171
|
+
self.PartHints = PartHints
|
|
1058
1172
|
|
|
1059
1173
|
def _pull_docker_image(self) -> None:
|
|
1060
1174
|
"""Pull the docker image if not available"""
|
|
@@ -1216,6 +1330,13 @@ class LibUserd(object):
|
|
|
1216
1330
|
# ways, we'll add that one too, just in case.
|
|
1217
1331
|
dirs_to_check.append(os.path.join(env_inst, "CEI"))
|
|
1218
1332
|
|
|
1333
|
+
try:
|
|
1334
|
+
import enve
|
|
1335
|
+
|
|
1336
|
+
dirs_to_check.append(enve.home())
|
|
1337
|
+
except ModuleNotFoundError:
|
|
1338
|
+
pass
|
|
1339
|
+
|
|
1219
1340
|
if "CEI_HOME" in os.environ:
|
|
1220
1341
|
env_inst = os.environ["CEI_HOME"]
|
|
1221
1342
|
dirs_to_check.append(env_inst)
|
|
@@ -1464,7 +1585,7 @@ class LibUserd(object):
|
|
|
1464
1585
|
Parameters
|
|
1465
1586
|
----------
|
|
1466
1587
|
element_type
|
|
1467
|
-
The element type:
|
|
1588
|
+
The element type: ElementType enum value
|
|
1468
1589
|
|
|
1469
1590
|
Returns
|
|
1470
1591
|
-------
|
|
@@ -1489,7 +1610,7 @@ class LibUserd(object):
|
|
|
1489
1610
|
Parameters
|
|
1490
1611
|
----------
|
|
1491
1612
|
element_type
|
|
1492
|
-
The element type:
|
|
1613
|
+
The element type: ElementType enum value
|
|
1493
1614
|
|
|
1494
1615
|
Returns
|
|
1495
1616
|
-------
|
|
@@ -1512,7 +1633,7 @@ class LibUserd(object):
|
|
|
1512
1633
|
Parameters
|
|
1513
1634
|
----------
|
|
1514
1635
|
element_type
|
|
1515
|
-
The element type:
|
|
1636
|
+
The element type: ElementType enum value
|
|
1516
1637
|
|
|
1517
1638
|
Returns
|
|
1518
1639
|
-------
|
|
@@ -1535,7 +1656,7 @@ class LibUserd(object):
|
|
|
1535
1656
|
Parameters
|
|
1536
1657
|
----------
|
|
1537
1658
|
element_type
|
|
1538
|
-
The element type:
|
|
1659
|
+
The element type: ElementType enum value
|
|
1539
1660
|
|
|
1540
1661
|
Returns
|
|
1541
1662
|
-------
|
|
@@ -1558,7 +1679,7 @@ class LibUserd(object):
|
|
|
1558
1679
|
Parameters
|
|
1559
1680
|
----------
|
|
1560
1681
|
element_type
|
|
1561
|
-
The element type:
|
|
1682
|
+
The element type: ElementType enum value
|
|
1562
1683
|
|
|
1563
1684
|
Returns
|
|
1564
1685
|
-------
|
|
@@ -1580,7 +1701,7 @@ class LibUserd(object):
|
|
|
1580
1701
|
Part.element_conn() method. This function returns the number of those elements
|
|
1581
1702
|
and may be useful in common element type handling code.
|
|
1582
1703
|
|
|
1583
|
-
Note: The value is effectively int(
|
|
1704
|
+
Note: The value is effectively int(ElementType.NSIDED).
|
|
1584
1705
|
|
|
1585
1706
|
Returns
|
|
1586
1707
|
-------
|
|
@@ -1733,7 +1854,7 @@ class LibUserd(object):
|
|
|
1733
1854
|
try:
|
|
1734
1855
|
output = the_reader.read_dataset(data_file, result_file)
|
|
1735
1856
|
except Exception:
|
|
1736
|
-
raise RuntimeError("Unable to open the specified dataset.")
|
|
1857
|
+
raise RuntimeError("Unable to open the specified dataset.") from None
|
|
1737
1858
|
|
|
1738
1859
|
return output
|
|
1739
1860
|
|
{ansys_pyensight_core-0.8.10 → ansys_pyensight_core-0.8.12}/src/ansys/pyensight/core/renderable.py
RENAMED
|
@@ -389,10 +389,17 @@ class RenderableDeepPixel(Renderable):
|
|
|
389
389
|
for script in ["geotiff.js", "geotiff_nexus.js", "bootstrap.min.js"]:
|
|
390
390
|
name = base_name + f"'{script}')"
|
|
391
391
|
cmd += f'shutil.copy({name}, r"""{self._session.launcher.session_directory}""")\n'
|
|
392
|
+
name = "os.path.join(enve.home(), f'nexus{ceiversion.nexus_suffix}', 'django', "
|
|
393
|
+
name += "'website', 'static', 'website', 'content', 'bootstrap.min.css')"
|
|
394
|
+
cmd += f'shutil.copy({name}, r"""{self._session.launcher.session_directory}""")\n'
|
|
395
|
+
self._session.cmd(cmd, do_eval=False)
|
|
396
|
+
# With Bootstrap 5 (2025 R1), class names have '-bs-' in them, e.g. 'data-bs-toggle' vs 'data-toggle'
|
|
397
|
+
bs_prefix = "bs-"
|
|
398
|
+
jquery_version = ""
|
|
392
399
|
if int(self._session._cei_suffix) < 251:
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
400
|
+
bs_prefix = ""
|
|
401
|
+
jquery_version = "-3.4.1"
|
|
402
|
+
jquery = f"jquery{jquery_version}.min.js"
|
|
396
403
|
cmd = "import shutil, enve, ceiversion, os.path\n"
|
|
397
404
|
name = base_name + f"'{jquery}')"
|
|
398
405
|
cmd += "try:"
|
|
@@ -409,6 +416,8 @@ class RenderableDeepPixel(Renderable):
|
|
|
409
416
|
html = html.replace("TIFF_URL", tiff_url)
|
|
410
417
|
html = html.replace("ITEMID", self._guid)
|
|
411
418
|
html = html.replace("OPTIONAL_QUERY", optional_query)
|
|
419
|
+
html = html.replace("JQUERY_VERSION", jquery_version)
|
|
420
|
+
html = html.replace("BS_PREFIX", bs_prefix)
|
|
412
421
|
# refresh the remote HTML
|
|
413
422
|
self._save_remote_html_page(html)
|
|
414
423
|
super().update()
|
|
@@ -101,6 +101,12 @@ class Part(object):
|
|
|
101
101
|
self.tcoords[
|
|
102
102
|
cmd.chunk_offset : cmd.chunk_offset + len(cmd.flt_array)
|
|
103
103
|
] = cmd.flt_array
|
|
104
|
+
|
|
105
|
+
# Add the variable hash to the Part's hash, to pick up palette changes
|
|
106
|
+
var_cmd = self.session.variables.get(cmd.variable_id, None)
|
|
107
|
+
if var_cmd is not None:
|
|
108
|
+
self.hash.update(var_cmd.hash.encode("utf-8"))
|
|
109
|
+
|
|
104
110
|
if self.cmd.node_size_variableid == cmd.variable_id: # type: ignore
|
|
105
111
|
# Receive the node size var values
|
|
106
112
|
if self.node_sizes.size != cmd.total_array_size:
|
|
@@ -618,6 +624,15 @@ class DSGSession(object):
|
|
|
618
624
|
"""
|
|
619
625
|
logging.warning(s)
|
|
620
626
|
|
|
627
|
+
@staticmethod
|
|
628
|
+
def error(s: str) -> None:
|
|
629
|
+
"""Issue an error to the logging system
|
|
630
|
+
|
|
631
|
+
The logging message is mapped to "error" and cannot be blocked via verbosity
|
|
632
|
+
checks.
|
|
633
|
+
"""
|
|
634
|
+
logging.error(s)
|
|
635
|
+
|
|
621
636
|
def start(self) -> int:
|
|
622
637
|
"""Start a gRPC connection to an EnSight instance
|
|
623
638
|
|
|
@@ -741,6 +756,13 @@ class DSGSession(object):
|
|
|
741
756
|
except queue.Empty:
|
|
742
757
|
return None
|
|
743
758
|
|
|
759
|
+
def _reset(self):
|
|
760
|
+
self._variables = {}
|
|
761
|
+
self._groups = {}
|
|
762
|
+
self._part = Part(self)
|
|
763
|
+
self._scene_bounds = None
|
|
764
|
+
self._mesh_block_count = 0 # reset when a new group shows up
|
|
765
|
+
|
|
744
766
|
def handle_one_update(self) -> None:
|
|
745
767
|
"""Monitor the DSG stream and handle a single update operation
|
|
746
768
|
|
|
@@ -759,11 +781,7 @@ class DSGSession(object):
|
|
|
759
781
|
cmd = self._get_next_message()
|
|
760
782
|
|
|
761
783
|
# Start anew
|
|
762
|
-
self.
|
|
763
|
-
self._groups = {}
|
|
764
|
-
self._part = Part(self)
|
|
765
|
-
self._scene_bounds = None
|
|
766
|
-
self._mesh_block_count = 0 # reset when a new group shows up
|
|
784
|
+
self._reset()
|
|
767
785
|
self._callback_handler.begin_update()
|
|
768
786
|
|
|
769
787
|
# Update our status
|
|
@@ -839,7 +857,11 @@ class DSGSession(object):
|
|
|
839
857
|
try:
|
|
840
858
|
self._callback_handler.finalize_part(self.part)
|
|
841
859
|
except Exception as e:
|
|
860
|
+
import traceback
|
|
861
|
+
|
|
842
862
|
self.warn(f"Error encountered while finalizing part geometry: {str(e)}")
|
|
863
|
+
traceback_str = "".join(traceback.format_tb(e.__traceback__))
|
|
864
|
+
logging.debug(f"Traceback: {traceback_str}")
|
|
843
865
|
self._mesh_block_count += 1
|
|
844
866
|
|
|
845
867
|
def _handle_part(self, part_cmd: Any) -> None:
|
|
@@ -44,7 +44,7 @@ class Omniverse:
|
|
|
44
44
|
>>> from ansys.pyensight.core import LocalLauncher
|
|
45
45
|
>>> session = LocalLauncher().start()
|
|
46
46
|
>>> ov = session.ensight.utils.omniverse
|
|
47
|
-
>>> ov.create_connection()
|
|
47
|
+
>>> ov.create_connection(r"D:\Omniverse\Example")
|
|
48
48
|
>>> ov.update()
|
|
49
49
|
>>> ov.close_connection()
|
|
50
50
|
|
|
@@ -202,8 +202,8 @@ class Omniverse:
|
|
|
202
202
|
Parameters
|
|
203
203
|
----------
|
|
204
204
|
omniverse_path : str
|
|
205
|
-
The
|
|
206
|
-
"
|
|
205
|
+
The directory name where the USD files should be saved. For example:
|
|
206
|
+
"C:/Users/test/OV/usdfiles"
|
|
207
207
|
include_camera : bool
|
|
208
208
|
If True, apply the EnSight camera to the Omniverse scene. This option
|
|
209
209
|
should be used if the target viewer is in AR/VR mode. Defaults to False.
|