diff --git a/src/ansys/pyensight/core/utils/omniverse.py b/src/ansys/pyensight/core/utils/omniverse.py index f2f5f663d74..220a8339e74 100644 --- a/src/ansys/pyensight/core/utils/omniverse.py +++ b/src/ansys/pyensight/core/utils/omniverse.py @@ -190,6 +190,7 @@ def create_connection( live: bool = True, debug_filename: str = "", time_scale: float = 1.0, + line_width: float = 0.0, options: dict = {}, ) -> None: """Ensure that an EnSight dsg -> omniverse server is running @@ -224,6 +225,9 @@ def create_connection( If the name of a file is provided, it will be used to save logging information on the connection between EnSight and Omniverse. This option is no longer supported, but the API remains for backwards compatibility. + line_width : float + If set, line objects will be represented as "tubes" of the size specified by + this factor. The default is 0.0 and causes lines not to be exported. options : dict Allows for a fallback for the grpc host/port and the security token. """ @@ -259,6 +263,8 @@ def create_connection( cmd.extend(["--normalize_geometry", "true"]) if time_scale != 1.0: cmd.extend(["--time_scale", str(time_scale)]) + if line_width != 0.0: + cmd.extend(["--line_width", str(line_width)]) if not live: cmd.extend(["--oneshot", "1"]) cmd.extend(["--dsg_uri", dsg_uri]) @@ -336,7 +342,7 @@ def close_connection(self) -> None: self._server_pid = None self._new_status_file(new=False) - def update(self, temporal: bool = False) -> None: + def update(self, temporal: bool = False, line_width: float = 0.0) -> None: """Update the geometry in Omniverse Export the current EnSight scene to the current Omniverse connection. @@ -345,10 +351,20 @@ def update(self, temporal: bool = False) -> None: ---------- temporal : bool If True, export all timesteps. + line_width : float + If set to a non-zero value, lines will be exported with this thickness. + This feature is only available in 2025 R2 and later. """ update_cmd = "dynamicscenegraph://localhost/client/update" + prefix = "?" if temporal: - update_cmd += "?timesteps=1" + update_cmd += f"{prefix}timesteps=1" + prefix = "&" + if line_width != 0.0: + # only in 2025 R2 and beyond + if self._ensight._session.ensight_version_check("2025 R2", exception=False): + update_cmd += f"{prefix}line_width={line_width}" + prefix = "&" self._check_modules() if not self.is_running_omniverse(): raise RuntimeError("No Omniverse server connection is currently active.") diff --git a/src/ansys/pyensight/core/utils/omniverse_glb_server.py b/src/ansys/pyensight/core/utils/omniverse_glb_server.py index 2c8364edba3..2974ae3edbc 100644 --- a/src/ansys/pyensight/core/utils/omniverse_glb_server.py +++ b/src/ansys/pyensight/core/utils/omniverse_glb_server.py @@ -148,10 +148,17 @@ def _parse_mesh(self, meshid: int, parentid: int, parentname: str) -> None: continue glb_materialid = prim.material + line_width = self._callback_handler._omni.line_width + # TODO: override from scene extension: ANSYS_linewidth + # GLB Prim -> DSG Part part_name = f"{parentname}_prim{prim_idx}_" cmd, part_pb = self._create_pb("PART", parent_id=parentid, name=part_name) - part_pb.render = dynamic_scene_graph_pb2.UpdatePart.RenderingMode.CONNECTIVITY + if mode == pygltflib.POINTS: + part_pb.render = dynamic_scene_graph_pb2.UpdatePart.RenderingMode.NODES + part_pb.node_size_default = line_width + else: + part_pb.render = dynamic_scene_graph_pb2.UpdatePart.RenderingMode.CONNECTIVITY part_pb.shading = dynamic_scene_graph_pb2.UpdatePart.ShadingMode.NODAL self._map_material(glb_materialid, part_pb) part_dsg_id = part_pb.id @@ -208,6 +215,7 @@ def _parse_mesh(self, meshid: int, parentid: int, parentname: str) -> None: normals_pb.total_array_size = len(normals) self._handle_update_command(cmd) + # Texture coords if prim.attributes.TEXCOORD_0 is not None: # Note: texture coords are stored as VEC2, so we get 2 components back texcoords = self._get_data(prim.attributes.TEXCOORD_0, components=2)