Skip to content

feat: switch to ansys tools and decouple requirements #532

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Apr 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
eed9b7a
tests: add test on plot method
SMoraisAnsys Mar 27, 2025
3245ebc
chore: adding changelog file 521.test.md [dependabot-skip]
pyansys-ci-bot Mar 27, 2025
de7baf2
test: avoid patch and use xvfb
SMoraisAnsys Mar 27, 2025
34fad26
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Mar 27, 2025
1354d33
ci: split install in two steps
SMoraisAnsys Mar 27, 2025
ab9020f
Merge branch 'tests/show-methods' of github.com:ansys-internal/pyspeo…
SMoraisAnsys Mar 27, 2025
55ba348
ci: update libs to match ubuntu 24.04
SMoraisAnsys Mar 27, 2025
3e044e3
feature: allow saving image in tests dir
SMoraisAnsys Mar 27, 2025
c924eb7
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Mar 27, 2025
a7adb7b
test: add off_screen=true by default
SMoraisAnsys Mar 27, 2025
30de62a
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Mar 27, 2025
948bb63
test: extend test with asserts
SMoraisAnsys Mar 27, 2025
3d445e3
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Mar 27, 2025
e6a2e44
Merge branch 'main' into tests/show-methods
SMoraisAnsys Mar 27, 2025
a42dced
chore: adding changelog file 521.added.md [dependabot-skip]
pyansys-ci-bot Mar 27, 2025
5961e87
fix bug and improve tests
StefanThoene Mar 28, 2025
bcd03bc
Merge branch 'main' into tests/show-methods
pluAtAnsys Mar 28, 2025
675724e
Apply suggestions from code review
StefanThoene Mar 31, 2025
0fe20f1
Merge branch 'main' into tests/show-methods
StefanThoene Mar 31, 2025
89e3eac
add notes to highlight correct way to close pyvista
StefanThoene Mar 31, 2025
6aa1bd5
switch to ansys-tools-visualization-interface
StefanThoene Apr 1, 2025
22faa97
add test requirements
StefanThoene Apr 1, 2025
531595a
add jupyter requirements
StefanThoene Apr 1, 2025
c3518c4
add jupyter and doc requirements
StefanThoene Apr 1, 2025
bc9f9b8
Merge branch 'main' into feat/switch_to_ansys_tools
StefanThoene Apr 1, 2025
54e248b
add jupyter and doc requirements
StefanThoene Apr 1, 2025
588072d
chore: adding changelog file 532.added.md [dependabot-skip]
pyansys-ci-bot Apr 1, 2025
1d98b4d
change add_mesh to plot
StefanThoene Apr 1, 2025
85f2689
add simple error management and warnings
StefanThoene Apr 1, 2025
08ca049
improve error msg
StefanThoene Apr 1, 2025
fd0c578
chore: adding changelog file 532.added.md [dependabot-skip]
pyansys-ci-bot Apr 1, 2025
b9b4e1b
add coverage info
StefanThoene Apr 1, 2025
adebc73
Merge remote-tracking branch 'origin/feat/switch_to_ansys_tools' into…
StefanThoene Apr 1, 2025
a8ff6f7
switch to decorator
StefanThoene Apr 1, 2025
5fefcdc
fix tests
StefanThoene Apr 1, 2025
fbaf284
correct coverage information in general_methods.py
StefanThoene Apr 1, 2025
11d42b6
Merge branch 'main' into feat/switch_to_ansys_tools
pluAtAnsys Apr 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changelog.d/532.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
switch to ansys tools and decouple requirements
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,18 @@ dependencies=[
"grpcio-health-checking>=1.45.0,<1.68",
"ansys-api-speos==0.14.2",
"numpy>=1.20.3,<3",
"pyvista>=0.40.0,<0.45",
"comtypes>=1.4,<1.5",
]

[project.optional-dependencies]
graphics = [
"pyvista>=0.40.0,<0.45",
"ansys-tools-visualization-interface>=0.8.3",
]
tests = [
"pytest==8.3.5",
"pyvista>=0.40.0,<0.45",
"ansys-tools-visualization-interface>=0.8.3",
"ansys-platform-instancemanagement>=1.0.3",
"pytest-cov==6.0.0",
]
Expand All @@ -47,6 +52,7 @@ jupyter = [
"jupyterlab>=3",
"ipywidgets",
"pyvista[jupyter]>=0.43,<0.45",
"ansys-tools-visualization-interface>=0.8.3",
"notebook==7.3.3",
]
doc = [
Expand All @@ -65,6 +71,7 @@ doc = [
"jupyter-server==2.15.0",
"nbconvert==7.16.6",
"pyvista[jupyter]>=0.43,<0.45",
"ansys-tools-visualization-interface>=0.8.3",
]

[project.urls]
Expand Down
46 changes: 46 additions & 0 deletions src/ansys/speos/core/generic/general_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
from functools import wraps
import warnings

__GRAPHICS_AVAILABLE = None
GRAPHICS_ERROR = (
"Preview unsupported without 'ansys-tools-visualization_interface' installed. "
"You can install this using `pip install ansys-speos-core[graphics]`."
)


def deprecate_kwargs(old_arguments: dict, removed_version="0.3.0"):
"""Issues deprecation warnings for arguments.
Expand Down Expand Up @@ -62,3 +68,43 @@ def wrapper(*args, **kwargs):
return wrapper

return decorator


def run_if_graphics_required(warning=False):
"""Check if graphics are available."""
global __GRAPHICS_AVAILABLE
if __GRAPHICS_AVAILABLE is None:
try:
import pyvista as pv # noqa: F401

from ansys.tools.visualization_interface import Plotter # noqa: F401

__GRAPHICS_AVAILABLE = True
except ImportError: # pragma: no cover
__GRAPHICS_AVAILABLE = False

if __GRAPHICS_AVAILABLE is False and warning is False: # pragma: no cover
raise ImportError(GRAPHICS_ERROR)
elif __GRAPHICS_AVAILABLE is False: # pragma: no cover
warnings.warn(GRAPHICS_ERROR)


def graphics_required(method):
"""Decorate a method as requiring graphics.

Parameters
----------
method : callable
Method to decorate.

Returns
-------
callable
Decorated method.
"""

def wrapper(*args, **kwargs):
run_if_graphics_required()
return method(*args, **kwargs)

return wrapper
33 changes: 24 additions & 9 deletions src/ansys/speos/core/lxp.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,22 @@

import os
from pathlib import Path
from typing import Optional, Union

import pyvista as pv
from typing import TYPE_CHECKING, Optional, Union

import ansys.api.speos.lpf.v2.lpf_file_reader_pb2 as lpf_file_reader__v2__pb2
import ansys.api.speos.lpf.v2.lpf_file_reader_pb2_grpc as lpf_file_reader__v2__pb2_grpc
from ansys.speos.core.generic.general_methods import graphics_required
from ansys.speos.core.project import Project, Speos

if TYPE_CHECKING: # pragma: no cover
from ansys.tools.visualization_interface import Plotter
try:
from ansys.speos.core.generic.general_methods import run_if_graphics_required

run_if_graphics_required(warning=True)
except ImportError as err: # pragma: no cover
raise err

ERROR_IDS = [7, 8, 9, 10, 11, 12, 13, 14, 15]
"""Intersection types indicating an error state."""

Expand Down Expand Up @@ -420,18 +428,21 @@ def remove_error_rays(self) -> LightPathFinder:
return self

@staticmethod
def __add_ray_to_pv(plotter: pv.Plotter, ray: RayPath, max_ray_length: float):
@graphics_required
def __add_ray_to_pv(plotter: Plotter, ray: RayPath, max_ray_length: float):
"""Add a ray to pyvista plotter.

Parameters
----------
plotter : pv.Plotter
Pyvista plotter object to which rays should be added.
plotter : Plotter
Ansys plotter object to which rays should be added.
ray : script.RayPath
RayPath object which contains ray information to be added.
max_ray_length : float
Length of the last ray.
"""
import pyvista as pv

temp = ray.impacts.copy()
if not 7 <= ray.intersection_type[-1] <= 15:
temp.append(
Expand All @@ -445,8 +456,9 @@ def __add_ray_to_pv(plotter: pv.Plotter, ray: RayPath, max_ray_length: float):
mesh = pv.MultipleLines(temp)
else:
mesh = pv.Line(temp[0], temp[1])
plotter.add_mesh(mesh, color=wavelength_to_rgb(ray.wl), line_width=2)
plotter.plot(mesh, color=wavelength_to_rgb(ray.wl), line_width=2)

@graphics_required
def preview(
self,
nb_ray: int = 100,
Expand All @@ -468,7 +480,8 @@ def preview(
project : ansys.speos.core.project.Project
Speos Project/Geometry to be added to pyvista visualisation.
screenshot : str or Path or ``None``
Path to save a screenshot of the plotter.
Path to save a screenshot of the plotter. If defined Plotter will only create the
screenshot

Returns
-------
Expand All @@ -481,6 +494,8 @@ def preview(
operating systems (namely Windows) will experience issues
saving a screenshot if the exit button in the GUI is pressed.
"""
from ansys.tools.visualization_interface import Plotter

if ray_filter:
if len(self._filtered_rays) > 0:
temp_rays = self._filtered_rays
Expand All @@ -490,7 +505,7 @@ def preview(
else:
temp_rays = self._rays
if not project:
plotter = pv.Plotter()
plotter = Plotter()
if nb_ray > len(temp_rays):
for ray in temp_rays:
self.__add_ray_to_pv(plotter, ray, max_ray_length)
Expand Down
33 changes: 27 additions & 6 deletions src/ansys/speos/core/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
import os
from pathlib import Path
import re
from typing import List, Mapping, Optional, Union
from typing import TYPE_CHECKING, List, Mapping, Optional, Union
import uuid

from google.protobuf.internal.containers import RepeatedScalarFieldContainer
import numpy as np
import pyvista as pv

import ansys.speos.core.body as body
import ansys.speos.core.face as face
from ansys.speos.core.generic.general_methods import graphics_required
from ansys.speos.core.kernel.body import BodyLink
from ansys.speos.core.kernel.face import FaceLink
from ansys.speos.core.kernel.part import ProtoPart
Expand All @@ -59,6 +59,18 @@
)
from ansys.speos.core.speos import Speos

try:
from ansys.speos.core.generic.general_methods import run_if_graphics_required

run_if_graphics_required(warning=True)
except ImportError as err: # pragma: no cover
raise err

if TYPE_CHECKING: # pragma: no cover
import pyvista as pv

from ansys.tools.visualization_interface import Plotter


class Project:
"""A project describes all Speos features.
Expand Down Expand Up @@ -829,6 +841,7 @@ def __extract_part_mesh_info(
pv.PolyData
mesh data extracted.
"""
import pyvista as pv

def local2absolute(local_vertice: np.ndarray, coordinates) -> np.ndarray:
"""Convert local coordinate to global coordinate.
Expand Down Expand Up @@ -888,7 +901,8 @@ def local2absolute(local_vertice: np.ndarray, coordinates) -> np.ndarray:
part_mesh_info = part_mesh_info.append_polydata(face_mesh_data)
return part_mesh_info

def _create_preview(self, viz_args=None) -> pv.Plotter:
@graphics_required
def _create_preview(self, viz_args=None) -> Plotter:
"""Create preview pyvista plotter object.

Parameters
Expand All @@ -900,6 +914,10 @@ def _create_preview(self, viz_args=None) -> pv.Plotter:
- {'style': 'surface', 'color':'white'},
- {'opacity': 0.7, 'color':'white', 'show_edges': False},
"""
import pyvista as pv

from ansys.tools.visualization_interface import Plotter

if viz_args is None:
viz_args = {}
_preview_mesh = pv.PolyData()
Expand All @@ -921,10 +939,12 @@ def _create_preview(self, viz_args=None) -> pv.Plotter:
poly_data = self.__extract_part_mesh_info(part_data=root_part_data)
if poly_data is not None:
_preview_mesh = _preview_mesh.append_polydata(poly_data)
p = pv.Plotter()
p.add_mesh(_preview_mesh, show_edges=True, **viz_args)
p = Plotter()
viz_args["show_edges"] = True
p.plot(_preview_mesh, **viz_args)
return p

@graphics_required
def preview(
self,
viz_args=None,
Expand All @@ -942,7 +962,8 @@ def preview(
- {'opacity': 0.7, 'color':'white', 'show_edges': False}.

screenshot : str or Path or ``None``
Path to save a screenshot of the plotter.
Path to save a screenshot of the plotter. If defined Plotter will only create the
screenshot

"""
if viz_args is None:
Expand Down