ansys-pyensight-core 0.8.8__py3-none-any.whl → 0.8.9__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.

Potentially problematic release.


This version of ansys-pyensight-core might be problematic. Click here for more details.

Files changed (34) hide show
  1. ansys/pyensight/core/dockerlauncher.py +6 -0
  2. ansys/pyensight/core/launcher.py +6 -1
  3. ansys/pyensight/core/locallauncher.py +4 -0
  4. ansys/pyensight/core/session.py +1 -1
  5. ansys/pyensight/core/utils/dsg_server.py +227 -35
  6. ansys/pyensight/core/utils/omniverse.py +84 -24
  7. ansys/pyensight/core/utils/omniverse_cli.py +481 -0
  8. ansys/pyensight/core/utils/omniverse_dsg_server.py +236 -426
  9. ansys/pyensight/core/utils/omniverse_glb_server.py +279 -0
  10. {ansys_pyensight_core-0.8.8.dist-info → ansys_pyensight_core-0.8.9.dist-info}/METADATA +11 -5
  11. ansys_pyensight_core-0.8.9.dist-info/RECORD +34 -0
  12. ansys/pyensight/core/exts/ansys.geometry.service/ansys/geometry/service/__init__.py +0 -1
  13. ansys/pyensight/core/exts/ansys.geometry.service/ansys/geometry/service/extension.py +0 -407
  14. ansys/pyensight/core/exts/ansys.geometry.service/config/extension.toml +0 -59
  15. ansys/pyensight/core/exts/ansys.geometry.service/data/icon.png +0 -0
  16. ansys/pyensight/core/exts/ansys.geometry.service/data/preview.png +0 -0
  17. ansys/pyensight/core/exts/ansys.geometry.service/docs/CHANGELOG.md +0 -11
  18. ansys/pyensight/core/exts/ansys.geometry.service/docs/README.md +0 -13
  19. ansys/pyensight/core/exts/ansys.geometry.service/docs/index.rst +0 -18
  20. ansys/pyensight/core/exts/ansys.geometry.serviceui/ansys/geometry/serviceui/__init__.py +0 -1
  21. ansys/pyensight/core/exts/ansys.geometry.serviceui/ansys/geometry/serviceui/extension.py +0 -193
  22. ansys/pyensight/core/exts/ansys.geometry.serviceui/config/extension.toml +0 -49
  23. ansys/pyensight/core/exts/ansys.geometry.serviceui/data/icon.png +0 -0
  24. ansys/pyensight/core/exts/ansys.geometry.serviceui/data/preview.png +0 -0
  25. ansys/pyensight/core/exts/ansys.geometry.serviceui/docs/CHANGELOG.md +0 -11
  26. ansys/pyensight/core/exts/ansys.geometry.serviceui/docs/README.md +0 -13
  27. ansys/pyensight/core/exts/ansys.geometry.serviceui/docs/index.rst +0 -18
  28. ansys/pyensight/core/utils/resources/Materials/Fieldstone/Fieldstone_BaseColor.png +0 -0
  29. ansys/pyensight/core/utils/resources/Materials/Fieldstone/Fieldstone_N.png +0 -0
  30. ansys/pyensight/core/utils/resources/Materials/Fieldstone/Fieldstone_ORM.png +0 -0
  31. ansys/pyensight/core/utils/resources/Materials/Fieldstone.mdl +0 -54
  32. ansys_pyensight_core-0.8.8.dist-info/RECORD +0 -52
  33. {ansys_pyensight_core-0.8.8.dist-info → ansys_pyensight_core-0.8.9.dist-info}/LICENSE +0 -0
  34. {ansys_pyensight_core-0.8.8.dist-info → ansys_pyensight_core-0.8.9.dist-info}/WHEEL +0 -0
@@ -0,0 +1,279 @@
1
+ import json
2
+ import logging
3
+ import os
4
+ import sys
5
+ import time
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ from ansys.api.pyensight.v0 import dynamic_scene_graph_pb2
9
+ import pygltflib
10
+
11
+ sys.path.insert(0, os.path.dirname(__file__))
12
+ from dsg_server import Part, UpdateHandler # noqa: E402
13
+
14
+
15
+ class GLBSession(object):
16
+ def __init__(
17
+ self,
18
+ verbose: int = 0,
19
+ normalize_geometry: bool = False,
20
+ time_scale: float = 1.0,
21
+ handler: UpdateHandler = UpdateHandler(),
22
+ ):
23
+ """
24
+ Provide an interface to read a GLB file and link it to an UpdateHandler instance
25
+
26
+ This class reads GLB files and provides the data to an UpdateHandler instance for
27
+ further processing.
28
+
29
+ Parameters
30
+ ----------
31
+ verbose : int
32
+ The verbosity level. If set to 1 or higher the class will call logging.info
33
+ for log output. The default is ``0``.
34
+ normalize_geometry : bool
35
+ If True, the scene coordinates will be remapped into the volume [-1,-1,-1] - [1,1,1]
36
+ The default is not to remap coordinates.
37
+ time_scale : float
38
+ Scale time values by this factor after being read. The default is ``1.0``.
39
+ handler : UpdateHandler
40
+ This is an UpdateHandler subclass that is called back when the state of
41
+ a scene transfer changes. For example, methods are called when the
42
+ transfer begins or ends and when a Part (mesh block) is ready for processing.
43
+ """
44
+ super().__init__()
45
+ self._callback_handler = handler
46
+ self._verbose = verbose
47
+ self._normalize_geometry = normalize_geometry
48
+ self._time_scale = time_scale
49
+ self._time_limits = [
50
+ sys.float_info.max,
51
+ -sys.float_info.max,
52
+ ] # Min/max across all time steps
53
+ self._mesh_block_count = 0
54
+ self._node_idx: int = -1
55
+ self._variables: Dict[int, Any] = dict()
56
+ self._groups: Dict[int, Any] = dict()
57
+ self._part: Part = Part(self)
58
+ self._scene_bounds: Optional[List] = None
59
+ self._cur_timeline: List = [0.0, 0.0] # Start/End time for current update
60
+ self._callback_handler.session = self
61
+ # log any status changes to this file. external apps will be monitoring
62
+ self._status_file = os.environ.get("ANSYS_OV_SERVER_STATUS_FILENAME", "")
63
+ self._status = dict(status="idle", start_time=0.0, processed_buffers=0, total_buffers=0)
64
+ self._gltf: pygltflib.GLTF2 = pygltflib.GLTF2()
65
+ self._id_num: int = 0
66
+
67
+ def _reset(self):
68
+ self._variables = dict()
69
+ self._groups = dict()
70
+ self._part = Part(self)
71
+ self._scene_bounds = None
72
+ self._cur_timeline = [0.0, 0.0] # Start/End time for current update
73
+ self._status = dict(status="idle", start_time=0.0, processed_buffers=0, total_buffers=0)
74
+ self._gltf = pygltflib.GLTF2()
75
+ self._node_idx = -1
76
+ self._mesh_block_count = 0
77
+ self._id_num = 0
78
+
79
+ def _next_id(self) -> int:
80
+ self._id_num += 1
81
+ return self._id_num
82
+
83
+ @property
84
+ def scene_bounds(self) -> Optional[List]:
85
+ return self._scene_bounds
86
+
87
+ @property
88
+ def mesh_block_count(self) -> int:
89
+ return self._mesh_block_count
90
+
91
+ @property
92
+ def normalize_geometry(self) -> bool:
93
+ return self._normalize_geometry
94
+
95
+ @normalize_geometry.setter
96
+ def normalize_geometry(self, value: bool) -> None:
97
+ self._normalize_geometry = value
98
+
99
+ @property
100
+ def variables(self) -> dict:
101
+ return self._variables
102
+
103
+ @property
104
+ def groups(self) -> dict:
105
+ return self._groups
106
+
107
+ @property
108
+ def part(self) -> Part:
109
+ return self._part
110
+
111
+ @property
112
+ def time_limits(self) -> List:
113
+ return self._time_limits
114
+
115
+ @property
116
+ def cur_timeline(self) -> List:
117
+ return self._cur_timeline
118
+
119
+ @cur_timeline.setter
120
+ def cur_timeline(self, timeline: List) -> None:
121
+ self._cur_timeline = timeline
122
+ self._time_limits[0] = min(self._time_limits[0], self._cur_timeline[0])
123
+ self._time_limits[1] = max(self._time_limits[1], self._cur_timeline[1])
124
+
125
+ @property
126
+ def vrmode(self) -> bool:
127
+ """No camera support for the present."""
128
+ return True
129
+
130
+ def log(self, s: str, level: int = 0) -> None:
131
+ """Log a string to the logging system
132
+
133
+ If the message level is less than the current verbosity,
134
+ emit the message.
135
+ """
136
+ if level < self._verbose:
137
+ logging.info(s)
138
+
139
+ def _update_status_file(self, timed: bool = False):
140
+ """
141
+ Update the status file contents. The status file will contain the
142
+ following json object, stored as: self._status
143
+
144
+ {
145
+ 'status' : "working|idle",
146
+ 'start_time' : timestamp_of_update_begin,
147
+ 'processed_buffers' : number_of_protobuffers_processed,
148
+ 'total_buffers' : number_of_protobuffers_total,
149
+ }
150
+
151
+ Parameters
152
+ ----------
153
+ timed : bool, optional:
154
+ if True, only update every second.
155
+
156
+ """
157
+ if self._status_file:
158
+ current_time = time.time()
159
+ if timed:
160
+ last_time = self._status.get("last_time", 0.0)
161
+ if current_time - last_time < 1.0: # type: ignore
162
+ return
163
+ self._status["last_time"] = current_time
164
+ try:
165
+ message = json.dumps(self._status)
166
+ with open(self._status_file, "w") as status_file:
167
+ status_file.write(message)
168
+ except IOError:
169
+ pass # Note failure is expected here in some cases
170
+
171
+ def _parse_mesh(self, meshid: Any) -> None:
172
+ mesh = self._gltf.meshes[meshid]
173
+ logging.warning(f"mesh id: {meshid}, {mesh}")
174
+ for prim in mesh.primitives:
175
+ # TODO: GLB Prim -> DSG Part
176
+ self.log(f"prim {prim}")
177
+ # TODO: GLB Attributes -> DSG Geom
178
+
179
+ # mesh.mode, mesh.indices
180
+ # mesh.attributes(POSITION, NORMAL, COLOR_0, TEXCOORD_0, TEXCOORD_1)
181
+ # mesh.material
182
+ # mesh.images
183
+
184
+ def _walk_node(self, nodeid: Any) -> None:
185
+ node = self._gltf.nodes[nodeid]
186
+ self.log(f"node id: {nodeid}, {node}")
187
+ # TODO: GLB node -> DSG Group
188
+
189
+ if node.mesh is not None:
190
+ self._parse_mesh(node.mesh)
191
+
192
+ # Handle node.rotation, node.translation, node.scale, node.matrix
193
+ for child_id in node.children:
194
+ self._walk_node(child_id)
195
+
196
+ def upload_file(self, glb_filename: str) -> bool:
197
+ """Parse a GLB file and call out to the handler to present the data
198
+ to another interface (e.g. Omniverse)
199
+
200
+ Parameters
201
+ ----------
202
+ glb_filename : str
203
+ The name of the GLB file to parse
204
+
205
+ Returns
206
+ -------
207
+ bool:
208
+ returns True on success, False otherwise
209
+ """
210
+ try:
211
+ ok = True
212
+ self._gltf = pygltflib.GLTF2().load(glb_filename)
213
+ self.log(f"File: {glb_filename} Info: {self._gltf.asset}")
214
+
215
+ self._callback_handler.begin_update()
216
+ self._update_status_file()
217
+
218
+ # TODO: Variables, Textures
219
+
220
+ # TODO: GLB Scene -> DSG View
221
+
222
+ # for present, just the default scene
223
+ for node_id in self._gltf.scenes[self._gltf.scene].nodes:
224
+ self._walk_node(node_id)
225
+
226
+ self._finish_part()
227
+ self._callback_handler.end_update()
228
+
229
+ except Exception as e:
230
+ self.log(f"Error: Unable to process: {glb_filename} : {e}")
231
+ ok = False
232
+
233
+ self._reset()
234
+ self._update_status_file()
235
+ return ok
236
+
237
+ def _finish_part(self) -> None:
238
+ """Complete the current part
239
+
240
+ There is always a part being modified. This method completes the current part, committing
241
+ it to the handler.
242
+ """
243
+ self._callback_handler.finalize_part(self.part)
244
+ self._mesh_block_count += 1
245
+
246
+ def _name(self, node: Any) -> str:
247
+ if node.name:
248
+ return node.name
249
+ self._node_idx += 1
250
+ if self._node_idx == 0:
251
+ return "Root"
252
+ return f"Node_{self._node_idx}"
253
+
254
+ def _create_pb(
255
+ self, cmd_type: str, parent_id: int = -1, name: str = ""
256
+ ) -> "dynamic_scene_graph_pb2.SceneUpdateCommand":
257
+ cmd = dynamic_scene_graph_pb2.SceneUpdateCommand()
258
+ if cmd_type == "PART":
259
+ cmd.command_type = dynamic_scene_graph_pb2.SceneUpdateCommand.UPDATE_PART
260
+ subcmd = cmd.update_part
261
+ elif cmd_type == "GROUP":
262
+ cmd.command_type = dynamic_scene_graph_pb2.SceneUpdateCommand.UPDATE_GROUP
263
+ subcmd = cmd.update_group
264
+ elif cmd_type == "VARIABLE":
265
+ cmd.command_type = dynamic_scene_graph_pb2.SceneUpdateCommand.UPDATE_VARIABLE
266
+ subcmd = cmd.update_variable
267
+ elif cmd_type == "GEOM":
268
+ cmd.command_type = dynamic_scene_graph_pb2.SceneUpdateCommand.UPDATE_GEOM
269
+ subcmd = cmd.update_geom
270
+ elif cmd_type == "VIEW":
271
+ cmd.command_type = dynamic_scene_graph_pb2.SceneUpdateCommand.UPDATE_VIEW
272
+ subcmd = cmd.update_view
273
+ subcmd.id = self._next_id()
274
+ if parent_id >= 0:
275
+ subcmd.parent_id = parent_id
276
+ if cmd_type not in ("GEOM", "VIEW"):
277
+ if name:
278
+ subcmd.name = name
279
+ return cmd, subcmd
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ansys-pyensight-core
3
- Version: 0.8.8
3
+ Version: 0.8.9
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>
@@ -29,26 +29,32 @@ Requires-Dist: bump2version>=1.0.1 ; extra == "dev"
29
29
  Requires-Dist: ipdb>=0.9.4 ; extra == "dev"
30
30
  Requires-Dist: dill>=0.3.5.1 ; extra == "dev"
31
31
  Requires-Dist: pre-commit>=3.3.3 ; extra == "dev"
32
- Requires-Dist: Sphinx==7.2.6 ; extra == "doc"
32
+ Requires-Dist: usd-core>=24.8 ; extra == "dev"
33
+ Requires-Dist: pygltflib>=1.16.2 ; extra == "dev"
34
+ Requires-Dist: Sphinx==8.0.2 ; extra == "doc"
33
35
  Requires-Dist: numpydoc==1.5.0 ; extra == "doc"
34
36
  Requires-Dist: ansys-sphinx-theme==0.9.9 ; extra == "doc"
35
37
  Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "doc"
36
38
  Requires-Dist: sphinx-gallery==0.13.0 ; extra == "doc"
37
39
  Requires-Dist: sphinxcontrib-mermaid==0.9.2 ; extra == "doc"
38
40
  Requires-Dist: docker>=6.1.0 ; extra == "doc"
39
- Requires-Dist: matplotlib==3.7.2 ; extra == "doc"
41
+ Requires-Dist: matplotlib==3.9.1.post1 ; extra == "doc"
40
42
  Requires-Dist: requests>=2.28.2 ; extra == "doc"
41
43
  Requires-Dist: sphinxcontrib.jquery==4.1 ; extra == "doc"
42
44
  Requires-Dist: coverage-badge==1.1.0 ; extra == "doc"
43
45
  Requires-Dist: sphinxcontrib-openapi==0.8.1 ; extra == "doc"
44
46
  Requires-Dist: sphinxcontrib-video==0.2.0 ; extra == "doc"
45
- Requires-Dist: pytest==7.1.2 ; extra == "tests"
47
+ Requires-Dist: usd-core>=24.8 ; extra == "doc"
48
+ Requires-Dist: pygltflib>=1.16.2 ; extra == "doc"
49
+ Requires-Dist: pytest==8.3.2 ; extra == "tests"
46
50
  Requires-Dist: pytest-cov==4.1.0 ; extra == "tests"
47
51
  Requires-Dist: dill>=0.3.5.1 ; extra == "tests"
48
52
  Requires-Dist: pytest-mock==3.10.0 ; extra == "tests"
49
- Requires-Dist: urllib3==1.26.10 ; extra == "tests"
53
+ Requires-Dist: urllib3==2.2.2 ; extra == "tests"
50
54
  Requires-Dist: requests>=2.28.2 ; extra == "tests"
51
55
  Requires-Dist: docker>=6.1.0 ; extra == "tests"
56
+ Requires-Dist: usd-core>=24.8 ; extra == "tests"
57
+ Requires-Dist: pygltflib>=1.16.2 ; extra == "tests"
52
58
  Project-URL: Changelog, https://github.com/ansys/pyensight/blob/main/CHANGELOG.rst
53
59
  Project-URL: Documentation, https://ensight.docs.pyansys.com/
54
60
  Project-URL: Homepage, https://github.com/ansys/pyensight
@@ -0,0 +1,34 @@
1
+ ansys/pyensight/core/__init__.py,sha256=6iKVEEtxt-6mw7wu_AocOGYO1T1WYHAnk-X_jeTeA8k,828
2
+ ansys/pyensight/core/deep_pixel_view.html,sha256=oZmcCIS3Dqqsoj8oheYubLAH2ZVKXao3iJM2WXYBEKs,3421
3
+ ansys/pyensight/core/dockerlauncher.py,sha256=AEuBA24hdWn82vPSyBkx66OyEHeIyozICWeF_zDx-yA,28540
4
+ ansys/pyensight/core/enscontext.py,sha256=GSKkjZt1QEPyHEQ59EEBgKGMik9vjCdR9coR4uX7fEw,12141
5
+ ansys/pyensight/core/enshell_grpc.py,sha256=ijRcByqdG0ZIi958Co860w2mnBIklfguI6s8sewcR8Q,15904
6
+ ansys/pyensight/core/ensight_grpc.py,sha256=BJaErleSPrtI8myTIh0m9awFWPaUxrQmHpbuyR3RpM4,16847
7
+ ansys/pyensight/core/ensobj.py,sha256=uDtM2KHcAwd4hu5pcUYWbSD729ApHGIvuqZhEq8PxTI,18558
8
+ ansys/pyensight/core/launch_ensight.py,sha256=UyTDDmxru864YAihTY9EQ5NIbKFRiLpWGPHMu7JUgyY,6175
9
+ ansys/pyensight/core/launcher.py,sha256=J9yZnP3ygfGmw26hCYS_H1zk_YI_IE6QS8ItWJ80vwU,12659
10
+ ansys/pyensight/core/listobj.py,sha256=Trw87IxIMXtmUd1DzywRmMzORU704AG4scX4fqYmO6M,9340
11
+ ansys/pyensight/core/locallauncher.py,sha256=s70b7sYurRy1VD5ZI2JFVhruX3bmxCOTp7_YWQXoZs8,14376
12
+ ansys/pyensight/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ ansys/pyensight/core/renderable.py,sha256=hm4sXV-ZcpdfC_AJexycAX8zdsbWnsd-tMeUvewGekE,35003
14
+ ansys/pyensight/core/session.py,sha256=W7sSuZEK648va69lE6EiiOqd_h9YRwgRXihZoNB9V78,74386
15
+ ansys/pyensight/core/sgeo_poll.html,sha256=1M4BIc5CZpYA3b40qzk22NcPCLhjFnWdoS2PrS6Rhn4,752
16
+ ansys/pyensight/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ ansys/pyensight/core/utils/adr.py,sha256=XslZhlwcrSGzOlnhzprOv3ju_ppxxsWBjCnQL5KiNms,3570
18
+ ansys/pyensight/core/utils/dsg_server.py,sha256=zPvIHlgiJxiy0NQm3uIsh2nPY8TyAHaHaXtDMN28jiY,38869
19
+ ansys/pyensight/core/utils/export.py,sha256=ZNpU3earAnRMBHZa6I8nTwMYY54WctXApJfMTkREBNA,23189
20
+ ansys/pyensight/core/utils/omniverse.py,sha256=GWTYQhhVMT9x4kpMPpI51mHNiV1ths2zk8YzBZ2eeD0,14222
21
+ ansys/pyensight/core/utils/omniverse_cli.py,sha256=aePr-2AWla2mMgPx8NlwIApAD1rAdVLmNOBWKjMXNQA,18786
22
+ ansys/pyensight/core/utils/omniverse_dsg_server.py,sha256=SjKY8-q-M26tge13HW6Js71RoQnFgkjWELtHpXk707c,28185
23
+ ansys/pyensight/core/utils/omniverse_glb_server.py,sha256=VYSbIwKMZASAmgYwRGbN5PrCjbSdaL7MaFxMnOJlTFg,9793
24
+ ansys/pyensight/core/utils/parts.py,sha256=zST00r76kjsLLclBaKoOtuYhDUSdQr0vAooOG7AUea0,53372
25
+ ansys/pyensight/core/utils/query.py,sha256=OXKDbf1sOTX0sUvtKcp64LhVl-BcrEsE43w8uMxLOYI,19828
26
+ ansys/pyensight/core/utils/readers.py,sha256=WUpmCtMo9BHlUOwGtIrD5jjyS9HE9wDak8eEjrYeR2Y,11764
27
+ ansys/pyensight/core/utils/support.py,sha256=QI3z9ex7zJxjFbkCPba9DWqWgPFIThORqr0nvRfVjuc,4089
28
+ ansys/pyensight/core/utils/variables.py,sha256=T96aL-qR2FtxH6QafeD9ddcWL9BB6IRSOYs2JauRTlg,95133
29
+ ansys/pyensight/core/utils/views.py,sha256=ZKhJ6vMT7Rdd4bwJ0egMYTV7-D7Q7I19fF2_j_CMQ0o,12489
30
+ ansys/pyensight/core/utils/resources/Materials/000_sky.exr,sha256=xAR1gFd2uxPZDnvgfegdhEhRaqKtZldQDiR_-1rHKO0,8819933
31
+ ansys_pyensight_core-0.8.9.dist-info/LICENSE,sha256=qQWivZ12ETN5l3QxvTARY-QI5eoRRlyHdwLlAj0Bg5I,1089
32
+ ansys_pyensight_core-0.8.9.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
33
+ ansys_pyensight_core-0.8.9.dist-info/METADATA,sha256=Tvyi5fhWgWo09nNEPF99-_iSKrHtNHkj6AlAbGcA19A,12133
34
+ ansys_pyensight_core-0.8.9.dist-info/RECORD,,