ansys-pyensight-core 0.9.10__py3-none-any.whl → 0.9.12__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.
- ansys/pyensight/core/dockerlauncher.py +2 -1
- ansys/pyensight/core/launcher.py +1 -1
- ansys/pyensight/core/locallauncher.py +13 -1
- ansys/pyensight/core/session.py +19 -11
- ansys/pyensight/core/utils/dsg_server.py +74 -49
- ansys/pyensight/core/utils/omniverse_dsg_server.py +52 -32
- {ansys_pyensight_core-0.9.10.dist-info → ansys_pyensight_core-0.9.12.dist-info}/METADATA +8 -8
- {ansys_pyensight_core-0.9.10.dist-info → ansys_pyensight_core-0.9.12.dist-info}/RECORD +10 -10
- {ansys_pyensight_core-0.9.10.dist-info → ansys_pyensight_core-0.9.12.dist-info}/WHEEL +1 -1
- {ansys_pyensight_core-0.9.10.dist-info → ansys_pyensight_core-0.9.12.dist-info/licenses}/LICENSE +0 -0
|
@@ -403,6 +403,7 @@ class DockerLauncher(Launcher):
|
|
|
403
403
|
cmd += f" --ensight-ws-port {ws_port}"
|
|
404
404
|
cmd += f" --ensight-session-directory {self._session_directory}"
|
|
405
405
|
cmd += f" --ensight-secret-key {self._secret_key}"
|
|
406
|
+
cmd += "--main-show-gui 'False'"
|
|
406
407
|
logging.debug(f"Starting WebUI: {cmd}\n")
|
|
407
408
|
ret = self._enshell.start_other(cmd, extra_env=container_env_str)
|
|
408
409
|
if ret[0] != 0: # pragma: no cover
|
|
@@ -619,7 +620,7 @@ class DockerLauncher(Launcher):
|
|
|
619
620
|
pass
|
|
620
621
|
try:
|
|
621
622
|
logging.debug("Removing the Docker Container.\n")
|
|
622
|
-
self._container.remove()
|
|
623
|
+
self._container.remove(force=True)
|
|
623
624
|
except Exception:
|
|
624
625
|
pass
|
|
625
626
|
self._container = None
|
ansys/pyensight/core/launcher.py
CHANGED
|
@@ -234,7 +234,7 @@ class Launcher:
|
|
|
234
234
|
for process in psutil.process_iter():
|
|
235
235
|
try:
|
|
236
236
|
process_cmdline = process.cmdline()
|
|
237
|
-
except (psutil.AccessDenied, psutil.ZombieProcess, OSError):
|
|
237
|
+
except (psutil.AccessDenied, psutil.ZombieProcess, OSError, psutil.NoSuchProcess):
|
|
238
238
|
continue
|
|
239
239
|
if not process_cmdline:
|
|
240
240
|
continue
|
|
@@ -107,9 +107,20 @@ class LocalLauncher(Launcher):
|
|
|
107
107
|
cmd += [webui_script]
|
|
108
108
|
version = re.findall(r"nexus(\d+)", webui_script)[0]
|
|
109
109
|
path_to_webui = self._install_path
|
|
110
|
-
|
|
110
|
+
# Dev environment
|
|
111
|
+
path_to_webui_internal = os.path.join(
|
|
111
112
|
path_to_webui, f"nexus{version}", f"ansys{version}", "ensight", "WebUI", "web", "ui"
|
|
112
113
|
)
|
|
114
|
+
# Ansys environment
|
|
115
|
+
paths_to_webui_ansys = [
|
|
116
|
+
os.path.join(os.path.dirname(path_to_webui), "simcfd", "web", "ui"),
|
|
117
|
+
os.path.join(os.path.dirname(path_to_webui), "fluidsone", "web", "ui"),
|
|
118
|
+
]
|
|
119
|
+
path_to_webui = path_to_webui_internal
|
|
120
|
+
for path in paths_to_webui_ansys:
|
|
121
|
+
if os.path.exists(path):
|
|
122
|
+
path_to_webui = path
|
|
123
|
+
break
|
|
113
124
|
cmd += ["--server-listen-port", str(self._ports[5])]
|
|
114
125
|
cmd += ["--server-web-roots", path_to_webui]
|
|
115
126
|
cmd += ["--ensight-grpc-port", str(self._ports[0])]
|
|
@@ -117,6 +128,7 @@ class LocalLauncher(Launcher):
|
|
|
117
128
|
cmd += ["--ensight-ws-port", str(self._ports[3])]
|
|
118
129
|
cmd += ["--ensight-session-directory", self._session_directory]
|
|
119
130
|
cmd += ["--ensight-secret-key", self._secret_key]
|
|
131
|
+
cmd += ["--main-show-gui", "'False'"]
|
|
120
132
|
if "PYENSIGHT_DEBUG" in os.environ:
|
|
121
133
|
try:
|
|
122
134
|
if int(os.environ["PYENSIGHT_DEBUG"]) > 0:
|
ansys/pyensight/core/session.py
CHANGED
|
@@ -213,6 +213,7 @@ class Session:
|
|
|
213
213
|
# Because this session can have allocated significant external resources
|
|
214
214
|
# we very much want a chance to close it up cleanly. It is legal to
|
|
215
215
|
# call close() twice on this class if needed.
|
|
216
|
+
self._already_closed = False
|
|
216
217
|
atexit.register(self.close)
|
|
217
218
|
|
|
218
219
|
# Speed up subtype lookups:
|
|
@@ -1050,17 +1051,24 @@ class Session:
|
|
|
1050
1051
|
Close the current session and its gRPC connection.
|
|
1051
1052
|
"""
|
|
1052
1053
|
# if version 242 or higher, free any objects we have cached there
|
|
1053
|
-
if self.
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
#
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1054
|
+
if not self._already_closed:
|
|
1055
|
+
if self.cei_suffix >= "242":
|
|
1056
|
+
try:
|
|
1057
|
+
self._release_remote_objects()
|
|
1058
|
+
except RuntimeError: # pragma: no cover
|
|
1059
|
+
# handle some intermediate EnSight builds.
|
|
1060
|
+
pass
|
|
1061
|
+
except IOError: # pragma: no cover
|
|
1062
|
+
# The session might already have been closed via another
|
|
1063
|
+
# session object. If grpc is inactive, there's no sense
|
|
1064
|
+
# in raising an exception since we are closing it anyway
|
|
1065
|
+
pass
|
|
1066
|
+
if self._launcher and self._halt_ensight_on_close:
|
|
1067
|
+
self._launcher.close(self)
|
|
1068
|
+
else:
|
|
1069
|
+
# lightweight shtudown, just close the gRC connection
|
|
1070
|
+
self._grpc.shutdown(stop_ensight=False)
|
|
1071
|
+
self._already_closed = True
|
|
1064
1072
|
self._launcher = None
|
|
1065
1073
|
|
|
1066
1074
|
def _build_utils_interface(self) -> None:
|
|
@@ -12,6 +12,13 @@ from ansys.api.pyensight.v0 import dynamic_scene_graph_pb2
|
|
|
12
12
|
from ansys.pyensight.core import ensight_grpc
|
|
13
13
|
import numpy
|
|
14
14
|
|
|
15
|
+
try:
|
|
16
|
+
import dsgutils
|
|
17
|
+
|
|
18
|
+
dsgutils_loaded = True
|
|
19
|
+
except ModuleNotFoundError:
|
|
20
|
+
dsgutils_loaded = False
|
|
21
|
+
|
|
15
22
|
if TYPE_CHECKING:
|
|
16
23
|
from ansys.pyensight.core import Session
|
|
17
24
|
|
|
@@ -238,36 +245,51 @@ class Part(object):
|
|
|
238
245
|
self.session.log("Warning: zero length normals!")
|
|
239
246
|
else:
|
|
240
247
|
new_normals = numpy.ndarray((num_prims * verts_per_prim * 3,), dtype="float32")
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
248
|
+
if dsgutils_loaded:
|
|
249
|
+
dsgutils.build_nodal_surface_rep(
|
|
250
|
+
verts_per_prim,
|
|
251
|
+
self.normals_elem,
|
|
252
|
+
self.tcoords_elem,
|
|
253
|
+
conn,
|
|
254
|
+
verts,
|
|
255
|
+
normals,
|
|
256
|
+
tcoords,
|
|
257
|
+
new_conn,
|
|
258
|
+
new_verts,
|
|
259
|
+
new_normals,
|
|
260
|
+
new_tcoords,
|
|
261
|
+
)
|
|
262
|
+
else:
|
|
263
|
+
j = 0
|
|
264
|
+
for i0 in range(num_prims):
|
|
265
|
+
for i1 in range(verts_per_prim):
|
|
266
|
+
idx = conn[i0 * verts_per_prim + i1]
|
|
267
|
+
# new connectivity (identity)
|
|
268
|
+
new_conn[j] = j
|
|
269
|
+
# copy the vertex
|
|
270
|
+
new_verts[j * 3 + 0] = verts[idx * 3 + 0]
|
|
271
|
+
new_verts[j * 3 + 1] = verts[idx * 3 + 1]
|
|
272
|
+
new_verts[j * 3 + 2] = verts[idx * 3 + 2]
|
|
273
|
+
if new_normals is not None:
|
|
274
|
+
if self.normals_elem:
|
|
275
|
+
# copy the normal associated with the face
|
|
276
|
+
new_normals[j * 3 + 0] = normals[i0 * 3 + 0]
|
|
277
|
+
new_normals[j * 3 + 1] = normals[i0 * 3 + 1]
|
|
278
|
+
new_normals[j * 3 + 2] = normals[i0 * 3 + 2]
|
|
279
|
+
else:
|
|
280
|
+
# copy the same normal as the vertex
|
|
281
|
+
new_normals[j * 3 + 0] = normals[idx * 3 + 0]
|
|
282
|
+
new_normals[j * 3 + 1] = normals[idx * 3 + 1]
|
|
283
|
+
new_normals[j * 3 + 2] = normals[idx * 3 + 2]
|
|
284
|
+
if new_tcoords is not None:
|
|
285
|
+
# remember, 1D texture coords at this point
|
|
286
|
+
if self.tcoords_elem:
|
|
287
|
+
# copy the texture coord associated with the face
|
|
288
|
+
new_tcoords[j] = tcoords[i0]
|
|
289
|
+
else:
|
|
290
|
+
# copy the same texture coord as the vertex
|
|
291
|
+
new_tcoords[j] = tcoords[idx]
|
|
292
|
+
j += 1
|
|
271
293
|
# new arrays.
|
|
272
294
|
verts = new_verts
|
|
273
295
|
conn = new_conn
|
|
@@ -349,24 +371,27 @@ class Part(object):
|
|
|
349
371
|
var_minmax: List[float] = [v_min, v_max] # type: ignore
|
|
350
372
|
# build a power of two x 1 texture
|
|
351
373
|
num_texels = len(var_cmd.texture) // 4
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
s
|
|
368
|
-
|
|
369
|
-
|
|
374
|
+
if dsgutils_loaded:
|
|
375
|
+
tmp = dsgutils.build_st_coords(tcoords, v_min, v_max, num_texels)
|
|
376
|
+
else:
|
|
377
|
+
half_texel = 1 / (num_texels * 2.0)
|
|
378
|
+
tmp = numpy.ndarray((num_verts * 2,), dtype="float32")
|
|
379
|
+
tmp.fill(0.5) # fill in the T coordinate...
|
|
380
|
+
tex_width = half_texel * 2 * (num_texels - 1) # center to center of num_texels
|
|
381
|
+
# if the range is 0, adjust the min by -1. The result is that the texture
|
|
382
|
+
# coords will get mapped to S=1.0 which is what EnSight does in this situation
|
|
383
|
+
if (var_minmax[1] - var_minmax[0]) == 0.0:
|
|
384
|
+
var_minmax[0] = var_minmax[0] - 1.0
|
|
385
|
+
var_width = var_minmax[1] - var_minmax[0]
|
|
386
|
+
for idx in range(num_verts):
|
|
387
|
+
# normalized S coord value (clamp)
|
|
388
|
+
s = (tcoords[idx] - var_minmax[0]) / var_width
|
|
389
|
+
if s < 0.0:
|
|
390
|
+
s = 0.0
|
|
391
|
+
if s > 1.0:
|
|
392
|
+
s = 1.0
|
|
393
|
+
# map to the texture range and set the S value
|
|
394
|
+
tmp[idx * 2] = s * tex_width + half_texel
|
|
370
395
|
return tmp, var_cmd
|
|
371
396
|
|
|
372
397
|
def line_rep(self):
|
|
@@ -925,7 +950,7 @@ class DSGSession(object):
|
|
|
925
950
|
except Exception:
|
|
926
951
|
self._shutdown = True
|
|
927
952
|
self.log("DSG connection broken, calling exit")
|
|
928
|
-
|
|
953
|
+
sys.exit(0)
|
|
929
954
|
|
|
930
955
|
def _get_next_message(self, wait: bool = True) -> Any:
|
|
931
956
|
"""Get the next queued up protobuffer message
|
|
@@ -49,12 +49,14 @@ class OmniverseWrapper(object):
|
|
|
49
49
|
self._stage = None
|
|
50
50
|
self._destinationPath: str = ""
|
|
51
51
|
self._old_stages: list = []
|
|
52
|
-
self._stagename = "dsg_scene.usd"
|
|
52
|
+
self._stagename: str = "dsg_scene.usd"
|
|
53
53
|
self._live_edit: bool = live_edit
|
|
54
54
|
if self._live_edit:
|
|
55
55
|
self._stagename = "dsg_scene.live"
|
|
56
56
|
# USD time slider will have 120 tick marks per second of animation time
|
|
57
|
-
self._time_codes_per_second = 120.0
|
|
57
|
+
self._time_codes_per_second: float = 120.0
|
|
58
|
+
# Omniverse content currently only scales correctly for scenes in cm. DJB, Feb 2025
|
|
59
|
+
self._units_per_meter: float = 100.0
|
|
58
60
|
|
|
59
61
|
if destination:
|
|
60
62
|
self.destination = destination
|
|
@@ -149,8 +151,7 @@ class OmniverseWrapper(object):
|
|
|
149
151
|
# record the stage in the "_old_stages" list.
|
|
150
152
|
self._old_stages.append(self.stage_url())
|
|
151
153
|
UsdGeom.SetStageUpAxis(self._stage, UsdGeom.Tokens.y)
|
|
152
|
-
|
|
153
|
-
UsdGeom.SetStageMetersPerUnit(self._stage, 1.0)
|
|
154
|
+
UsdGeom.SetStageMetersPerUnit(self._stage, 1.0 / self._units_per_meter)
|
|
154
155
|
logging.info(f"Created stage: {self.stage_url()}")
|
|
155
156
|
|
|
156
157
|
def save_stage(self, comment: str = "") -> None:
|
|
@@ -288,6 +289,8 @@ class OmniverseWrapper(object):
|
|
|
288
289
|
|
|
289
290
|
if not os.path.exists(part_stage_url):
|
|
290
291
|
part_stage = Usd.Stage.CreateNew(part_stage_url)
|
|
292
|
+
UsdGeom.SetStageUpAxis(part_stage, UsdGeom.Tokens.y)
|
|
293
|
+
UsdGeom.SetStageMetersPerUnit(part_stage, 1.0 / self._units_per_meter)
|
|
291
294
|
self._old_stages.append(part_stage_url)
|
|
292
295
|
xform = UsdGeom.Xform.Define(part_stage, "/" + partname)
|
|
293
296
|
mesh = UsdGeom.Mesh.Define(part_stage, "/" + partname + "/Mesh")
|
|
@@ -362,6 +365,7 @@ class OmniverseWrapper(object):
|
|
|
362
365
|
parent_prim,
|
|
363
366
|
verts,
|
|
364
367
|
tcoords,
|
|
368
|
+
width,
|
|
365
369
|
matrix=[1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
366
370
|
diffuse=[1.0, 1.0, 1.0, 1.0],
|
|
367
371
|
variable=None,
|
|
@@ -369,20 +373,6 @@ class OmniverseWrapper(object):
|
|
|
369
373
|
first_timestep=False,
|
|
370
374
|
mat_info={},
|
|
371
375
|
):
|
|
372
|
-
# TODO: GLB extension maps to DSG PART attribute map
|
|
373
|
-
width = self.line_width
|
|
374
|
-
wireframe = width == 0.0
|
|
375
|
-
if width < 0.0:
|
|
376
|
-
tmp = verts.reshape(-1, 3)
|
|
377
|
-
mins = numpy.min(tmp, axis=0)
|
|
378
|
-
maxs = numpy.max(tmp, axis=0)
|
|
379
|
-
dx = maxs[0] - mins[0]
|
|
380
|
-
dy = maxs[1] - mins[1]
|
|
381
|
-
dz = maxs[2] - mins[2]
|
|
382
|
-
diagonal = math.sqrt(dx * dx + dy * dy + dz * dz)
|
|
383
|
-
width = diagonal * math.fabs(width)
|
|
384
|
-
self.line_width = width
|
|
385
|
-
|
|
386
376
|
# include the line width in the hash
|
|
387
377
|
part_hash.update(str(self.line_width).encode("utf-8"))
|
|
388
378
|
|
|
@@ -397,6 +387,8 @@ class OmniverseWrapper(object):
|
|
|
397
387
|
|
|
398
388
|
if not os.path.exists(part_stage_url):
|
|
399
389
|
part_stage = Usd.Stage.CreateNew(part_stage_url)
|
|
390
|
+
UsdGeom.SetStageUpAxis(part_stage, UsdGeom.Tokens.y)
|
|
391
|
+
UsdGeom.SetStageMetersPerUnit(part_stage, 1.0 / self._units_per_meter)
|
|
400
392
|
self._old_stages.append(part_stage_url)
|
|
401
393
|
xform = UsdGeom.Xform.Define(part_stage, "/" + partname)
|
|
402
394
|
lines = UsdGeom.BasisCurves.Define(part_stage, "/" + partname + "/Lines")
|
|
@@ -415,6 +407,7 @@ class OmniverseWrapper(object):
|
|
|
415
407
|
endCaps.Set(2) # Rounded = 2
|
|
416
408
|
|
|
417
409
|
prim = lines.GetPrim()
|
|
410
|
+
wireframe = width == 0.0
|
|
418
411
|
prim.CreateAttribute(
|
|
419
412
|
"omni:scene:visualization:drawWireframe", Sdf.ValueTypeNames.Bool
|
|
420
413
|
).Set(wireframe)
|
|
@@ -479,6 +472,8 @@ class OmniverseWrapper(object):
|
|
|
479
472
|
|
|
480
473
|
if not os.path.exists(part_stage_url):
|
|
481
474
|
part_stage = Usd.Stage.CreateNew(part_stage_url)
|
|
475
|
+
UsdGeom.SetStageUpAxis(part_stage, UsdGeom.Tokens.y)
|
|
476
|
+
UsdGeom.SetStageMetersPerUnit(part_stage, 1.0 / self._units_per_meter)
|
|
482
477
|
self._old_stages.append(part_stage_url)
|
|
483
478
|
xform = UsdGeom.Xform.Define(part_stage, "/" + partname)
|
|
484
479
|
|
|
@@ -639,8 +634,8 @@ class OmniverseWrapper(object):
|
|
|
639
634
|
cam = geom_cam.GetCamera()
|
|
640
635
|
# LOL, not sure why is might be correct, but so far it seems to work???
|
|
641
636
|
cam.focalLength = camera.fieldofview
|
|
642
|
-
dist = (target_pos - cam_pos).GetLength()
|
|
643
|
-
cam.clippingRange = Gf.Range1f(0.1 * dist,
|
|
637
|
+
dist = (target_pos - cam_pos).GetLength() * self._units_per_meter
|
|
638
|
+
cam.clippingRange = Gf.Range1f(0.1 * dist, 1000.0 * dist)
|
|
644
639
|
look_at = Gf.Matrix4d()
|
|
645
640
|
look_at.SetLookAt(cam_pos, target_pos, up_vec)
|
|
646
641
|
trans_row = look_at.GetRow(3)
|
|
@@ -724,7 +719,6 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
724
719
|
self._group_prims: Dict[int, Any] = dict()
|
|
725
720
|
self._root_prim = None
|
|
726
721
|
self._sent_textures = False
|
|
727
|
-
self._updated_camera = False
|
|
728
722
|
|
|
729
723
|
def add_group(self, id: int, view: bool = False) -> None:
|
|
730
724
|
super().add_group(id, view)
|
|
@@ -745,7 +739,7 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
745
739
|
matrix = group.matrix4x4
|
|
746
740
|
# Is this a "case" group (it will contain part of the camera view in the matrix)
|
|
747
741
|
if obj_type == "ENS_CASE":
|
|
748
|
-
if
|
|
742
|
+
if not self.session.vrmode:
|
|
749
743
|
# if in camera mode, we need to update the camera matrix so we can
|
|
750
744
|
# use the identity matrix on this group. The camera should have been
|
|
751
745
|
# created in the "view" handler
|
|
@@ -757,7 +751,8 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
757
751
|
c = cam.transform
|
|
758
752
|
m = Gf.Matrix4d(*matrix).GetTranspose()
|
|
759
753
|
# move the model transform to the camera transform
|
|
760
|
-
|
|
754
|
+
sc = Gf.Matrix4d(self._omni._units_per_meter)
|
|
755
|
+
cam.transform = c * m.GetInverse() * sc
|
|
761
756
|
# set the updated camera
|
|
762
757
|
geom_cam.SetFromCamera(cam)
|
|
763
758
|
# apply the inverse cam transform to move the center of interest
|
|
@@ -771,8 +766,8 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
771
766
|
)
|
|
772
767
|
coi_attr.Set(
|
|
773
768
|
Gf.Vec3d(
|
|
774
|
-
|
|
775
|
-
|
|
769
|
+
0,
|
|
770
|
+
0,
|
|
776
771
|
coi_cam[2] / coi_cam[3],
|
|
777
772
|
)
|
|
778
773
|
)
|
|
@@ -780,9 +775,6 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
780
775
|
self._omni._stage.GetRootLayer().customLayerData = { # type: ignore
|
|
781
776
|
"cameraSettings": {"boundCamera": "/Root/Cam"}
|
|
782
777
|
}
|
|
783
|
-
|
|
784
|
-
# We only want to do this once
|
|
785
|
-
self._updated_camera = True
|
|
786
778
|
matrix = [
|
|
787
779
|
1.0,
|
|
788
780
|
0.0,
|
|
@@ -852,6 +844,8 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
852
844
|
if part.cmd.render == part.cmd.CONNECTIVITY:
|
|
853
845
|
has_triangles = False
|
|
854
846
|
command, verts, conn, normals, tcoords, var_cmd = part.nodal_surface_rep()
|
|
847
|
+
if verts is not None:
|
|
848
|
+
verts = numpy.multiply(verts, self._omni._units_per_meter)
|
|
855
849
|
if command is not None:
|
|
856
850
|
has_triangles = True
|
|
857
851
|
# Generate the mesh block
|
|
@@ -872,6 +866,8 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
872
866
|
mat_info=mat_info,
|
|
873
867
|
)
|
|
874
868
|
command, verts, tcoords, var_cmd = part.line_rep()
|
|
869
|
+
if verts is not None:
|
|
870
|
+
verts = numpy.multiply(verts, self._omni._units_per_meter)
|
|
875
871
|
if command is not None:
|
|
876
872
|
# If there are no triangle (ideally if these are not hidden line
|
|
877
873
|
# edges), then use the base color for the part. If there are
|
|
@@ -885,9 +881,30 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
885
881
|
part.cmd.line_color[2] * part.cmd.diffuse,
|
|
886
882
|
part.cmd.line_color[3],
|
|
887
883
|
]
|
|
888
|
-
# TODO: texture coordinates on lines are
|
|
884
|
+
# TODO: texture coordinates on lines are currently invalid in Omniverse
|
|
889
885
|
var_cmd = None
|
|
890
886
|
tcoords = None
|
|
887
|
+
# line info can come from self or our parent group
|
|
888
|
+
width = self._omni.line_width
|
|
889
|
+
# Allow the group to override
|
|
890
|
+
group = self.session.find_group_pb(part.cmd.parent_id)
|
|
891
|
+
if group:
|
|
892
|
+
try:
|
|
893
|
+
width = float(group.attributes.get("ANSYS_linewidth", str(width)))
|
|
894
|
+
except ValueError:
|
|
895
|
+
pass
|
|
896
|
+
if width < 0.0:
|
|
897
|
+
tmp = verts.reshape(-1, 3)
|
|
898
|
+
mins = numpy.min(tmp, axis=0)
|
|
899
|
+
maxs = numpy.max(tmp, axis=0)
|
|
900
|
+
dx = maxs[0] - mins[0]
|
|
901
|
+
dy = maxs[1] - mins[1]
|
|
902
|
+
dz = maxs[2] - mins[2]
|
|
903
|
+
diagonal = math.sqrt(dx * dx + dy * dy + dz * dz)
|
|
904
|
+
width = diagonal * math.fabs(width) / self._omni._units_per_meter
|
|
905
|
+
if self._omni.line_width < 0.0:
|
|
906
|
+
self._omni.line_width = width
|
|
907
|
+
width = width * self._omni._units_per_meter
|
|
891
908
|
# Generate the lines
|
|
892
909
|
_ = self._omni.create_dsg_lines(
|
|
893
910
|
name,
|
|
@@ -896,6 +913,7 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
896
913
|
parent_prim,
|
|
897
914
|
verts,
|
|
898
915
|
tcoords,
|
|
916
|
+
width,
|
|
899
917
|
matrix=matrix,
|
|
900
918
|
diffuse=line_color,
|
|
901
919
|
variable=var_cmd,
|
|
@@ -905,6 +923,10 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
905
923
|
|
|
906
924
|
elif part.cmd.render == part.cmd.NODES:
|
|
907
925
|
command, verts, sizes, colors, var_cmd = part.point_rep()
|
|
926
|
+
if verts is not None:
|
|
927
|
+
verts = numpy.multiply(verts, self._omni._units_per_meter)
|
|
928
|
+
if sizes is not None:
|
|
929
|
+
sizes = numpy.multiply(sizes, self._omni._units_per_meter)
|
|
908
930
|
if command is not None:
|
|
909
931
|
_ = self._omni.create_dsg_points(
|
|
910
932
|
name,
|
|
@@ -915,7 +937,7 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
915
937
|
sizes,
|
|
916
938
|
colors,
|
|
917
939
|
matrix=matrix,
|
|
918
|
-
default_size=part.cmd.node_size_default,
|
|
940
|
+
default_size=part.cmd.node_size_default * self._omni._units_per_meter,
|
|
919
941
|
default_color=color,
|
|
920
942
|
timeline=self.session.cur_timeline,
|
|
921
943
|
first_timestep=(self.session.cur_timeline[0] == self.session.time_limits[0]),
|
|
@@ -942,8 +964,6 @@ class OmniverseUpdateHandler(UpdateHandler):
|
|
|
942
964
|
# Upload a material to the Omniverse server
|
|
943
965
|
self._omni.uploadMaterial()
|
|
944
966
|
self._sent_textures = False
|
|
945
|
-
# We want to update the camera a single time within this update
|
|
946
|
-
self._updated_camera = False
|
|
947
967
|
|
|
948
968
|
def end_update(self) -> None:
|
|
949
969
|
super().end_update()
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: ansys-pyensight-core
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.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>
|
|
7
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.10,<3.14
|
|
8
8
|
Description-Content-Type: text/x-rst
|
|
9
9
|
Classifier: Development Status :: 4 - Beta
|
|
10
10
|
Classifier: Intended Audience :: Science/Research
|
|
11
11
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
12
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
License-File: LICENSE
|
|
18
18
|
Requires-Dist: importlib-metadata>=4.0; python_version<='3.8'
|
|
19
19
|
Requires-Dist: ansys-api-pyensight==0.4.7
|
|
20
20
|
Requires-Dist: requests>=2.28.2
|
|
@@ -32,7 +32,7 @@ Requires-Dist: bump2version>=1.0.1 ; extra == "dev"
|
|
|
32
32
|
Requires-Dist: ipdb>=0.9.4 ; extra == "dev"
|
|
33
33
|
Requires-Dist: dill>=0.3.5.1 ; extra == "dev"
|
|
34
34
|
Requires-Dist: pre-commit>=3.3.3 ; extra == "dev"
|
|
35
|
-
Requires-Dist: Sphinx==8.
|
|
35
|
+
Requires-Dist: Sphinx==8.1.3 ; extra == "doc"
|
|
36
36
|
Requires-Dist: numpydoc==1.8.0 ; extra == "doc"
|
|
37
37
|
Requires-Dist: ansys-sphinx-theme==1.1.1 ; extra == "doc"
|
|
38
38
|
Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "doc"
|
|
@@ -47,11 +47,11 @@ Requires-Dist: coverage-badge==1.1.2 ; extra == "doc"
|
|
|
47
47
|
Requires-Dist: sphinxcontrib-video==0.2.1 ; extra == "doc"
|
|
48
48
|
Requires-Dist: usd-core>=24.8 ; extra == "doc"
|
|
49
49
|
Requires-Dist: pygltflib>=1.16.2 ; extra == "doc"
|
|
50
|
-
Requires-Dist: pytest==8.3.
|
|
50
|
+
Requires-Dist: pytest==8.3.5 ; extra == "tests"
|
|
51
51
|
Requires-Dist: pytest-cov==5.0.0 ; extra == "tests"
|
|
52
52
|
Requires-Dist: dill>=0.3.5.1 ; extra == "tests"
|
|
53
53
|
Requires-Dist: pytest-mock==3.10.0 ; extra == "tests"
|
|
54
|
-
Requires-Dist: urllib3==2.
|
|
54
|
+
Requires-Dist: urllib3==2.3.0 ; extra == "tests"
|
|
55
55
|
Requires-Dist: requests>=2.28.2 ; extra == "tests"
|
|
56
56
|
Requires-Dist: docker>=6.1.0 ; extra == "tests"
|
|
57
57
|
Requires-Dist: pytest-xdist==3.6.1 ; extra == "tests"
|
|
@@ -139,7 +139,7 @@ Installation
|
|
|
139
139
|
------------
|
|
140
140
|
To use PyEnSight, you must have a locally installed and licensed copy of
|
|
141
141
|
Ansys EnSight 2022 R2 or later. The ``ansys-pyensight-core`` package supports
|
|
142
|
-
Python 3.
|
|
142
|
+
Python 3.10 through Python 3.12 on Windows and Linux.
|
|
143
143
|
|
|
144
144
|
Two modes of installation are available:
|
|
145
145
|
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
ansys/pyensight/core/__init__.py,sha256=BCfpDonS2OZRM2O6wjcyOYhLSgdy9hMQRl6G-_9Bvkg,845
|
|
2
2
|
ansys/pyensight/core/common.py,sha256=f28uGaJhpSmOE1i6MwzqFH0_jKpIByglM2plB2K4Hdk,7574
|
|
3
3
|
ansys/pyensight/core/deep_pixel_view.html,sha256=6u4mGOuzJiPze8N8pIKJsEGPv5y6-zb38m9IfrarATE,3510
|
|
4
|
-
ansys/pyensight/core/dockerlauncher.py,sha256=
|
|
4
|
+
ansys/pyensight/core/dockerlauncher.py,sha256=9JYXbUbKimr4C6uILdsVCAELtARiTleaCCjN2V-OcRg,28494
|
|
5
5
|
ansys/pyensight/core/dvs.py,sha256=xL2LeJ9uja3mFBuU8vsE26O_NFgaR9uhDvxZKAHGGvg,31284
|
|
6
6
|
ansys/pyensight/core/enscontext.py,sha256=GSKkjZt1QEPyHEQ59EEBgKGMik9vjCdR9coR4uX7fEw,12141
|
|
7
7
|
ansys/pyensight/core/enshell_grpc.py,sha256=-OxSdFI_p3DmQnqh1jT_a_aSh_w-EUD2IaWGKxrnyjI,17122
|
|
8
8
|
ansys/pyensight/core/ensight_grpc.py,sha256=IitEgMzBJTyTgQff0sXPvGkVnC2E9qRKw-HXCF-mVvA,29713
|
|
9
9
|
ansys/pyensight/core/ensobj.py,sha256=uDtM2KHcAwd4hu5pcUYWbSD729ApHGIvuqZhEq8PxTI,18558
|
|
10
10
|
ansys/pyensight/core/launch_ensight.py,sha256=iZJM6GdpzGRDLzrv1V2QZ5veIOpNSB5xPpJUFY7rBuo,10254
|
|
11
|
-
ansys/pyensight/core/launcher.py,sha256=
|
|
11
|
+
ansys/pyensight/core/launcher.py,sha256=x6L1E6OGpqL2jrDdIGI0p4BxQZhHt93yl1Pwj_2lAiQ,13143
|
|
12
12
|
ansys/pyensight/core/libuserd.py,sha256=YKXY1aaaTBT2uwcyhPEW-f93KLtCYQNMJXTlBsenWDI,75459
|
|
13
13
|
ansys/pyensight/core/listobj.py,sha256=Trw87IxIMXtmUd1DzywRmMzORU704AG4scX4fqYmO6M,9340
|
|
14
|
-
ansys/pyensight/core/locallauncher.py,sha256=
|
|
14
|
+
ansys/pyensight/core/locallauncher.py,sha256=ptvbVoGYrb9OHawMpi9RRj_KVxR60mMaZaIPW4CPERI,17122
|
|
15
15
|
ansys/pyensight/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
ansys/pyensight/core/renderable.py,sha256=KidVTVCZ4hKYq54pP9KoJ8OCxeWBXNUJYyKSwMZ2Sls,36362
|
|
17
|
-
ansys/pyensight/core/session.py,sha256=
|
|
17
|
+
ansys/pyensight/core/session.py,sha256=6UEMn6X_08JzaAhmpIi4TQfv8zdONDG1cH8UaO7MQR8,74114
|
|
18
18
|
ansys/pyensight/core/sgeo_poll.html,sha256=1M4BIc5CZpYA3b40qzk22NcPCLhjFnWdoS2PrS6Rhn4,752
|
|
19
19
|
ansys/pyensight/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
ansys/pyensight/core/utils/adr.py,sha256=XslZhlwcrSGzOlnhzprOv3ju_ppxxsWBjCnQL5KiNms,3570
|
|
21
|
-
ansys/pyensight/core/utils/dsg_server.py,sha256=
|
|
21
|
+
ansys/pyensight/core/utils/dsg_server.py,sha256=C1rNlL5M36Ee5kMroQrqAykGICpjJsx_qhJspQ0x4LE,46381
|
|
22
22
|
ansys/pyensight/core/utils/export.py,sha256=UAJQcrElo3esQD0CWdxxjMQ8yE1vB4cdAhF33_uZfQw,22605
|
|
23
23
|
ansys/pyensight/core/utils/omniverse.py,sha256=irghU1wcIvo_lHhZV2VxYKCSQkNWCF8njJjWfExiFgI,18455
|
|
24
24
|
ansys/pyensight/core/utils/omniverse_cli.py,sha256=aVYu4HsSZBl7A9_xU3DfItNB-hpxCdMPXm_oMAOU_HQ,20261
|
|
25
|
-
ansys/pyensight/core/utils/omniverse_dsg_server.py,sha256=
|
|
25
|
+
ansys/pyensight/core/utils/omniverse_dsg_server.py,sha256=JCklPQC4xqwnvB7zVdLW80RpB9DlKN3hgs_Sj4sPhFY,39995
|
|
26
26
|
ansys/pyensight/core/utils/omniverse_glb_server.py,sha256=aWAsGTxSl0w6VYRXCx8FaKGlLtfii2OUm_wBmP2Ay0I,30100
|
|
27
27
|
ansys/pyensight/core/utils/parts.py,sha256=222XFRCjLgH7hho-cK9JrGCg3-KlTf54KIgc7y50sTE,52173
|
|
28
28
|
ansys/pyensight/core/utils/query.py,sha256=OXKDbf1sOTX0sUvtKcp64LhVl-BcrEsE43w8uMxLOYI,19828
|
|
@@ -31,7 +31,7 @@ ansys/pyensight/core/utils/support.py,sha256=QI3z9ex7zJxjFbkCPba9DWqWgPFIThORqr0
|
|
|
31
31
|
ansys/pyensight/core/utils/variables.py,sha256=ZUiJdDIeRcowrnLXaJQqGwA0RbrfXhc1s4o4v9A4PiY,95133
|
|
32
32
|
ansys/pyensight/core/utils/views.py,sha256=ZKhJ6vMT7Rdd4bwJ0egMYTV7-D7Q7I19fF2_j_CMQ0o,12489
|
|
33
33
|
ansys/pyensight/core/utils/resources/Materials/000_sky.exr,sha256=xAR1gFd2uxPZDnvgfegdhEhRaqKtZldQDiR_-1rHKO0,8819933
|
|
34
|
-
ansys_pyensight_core-0.9.
|
|
35
|
-
ansys_pyensight_core-0.9.
|
|
36
|
-
ansys_pyensight_core-0.9.
|
|
37
|
-
ansys_pyensight_core-0.9.
|
|
34
|
+
ansys_pyensight_core-0.9.12.dist-info/licenses/LICENSE,sha256=K6LiJHOa9IbWFelXmXNRzFr3zG45SOGZIN7vdLdURGU,1097
|
|
35
|
+
ansys_pyensight_core-0.9.12.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
36
|
+
ansys_pyensight_core-0.9.12.dist-info/METADATA,sha256=FfsDSxRXKKCjmBpNwYB3J0lf3l8jUD_C7hVYUAx57_M,12121
|
|
37
|
+
ansys_pyensight_core-0.9.12.dist-info/RECORD,,
|
{ansys_pyensight_core-0.9.10.dist-info → ansys_pyensight_core-0.9.12.dist-info/licenses}/LICENSE
RENAMED
|
File without changes
|