From 01f96664c4d738ab59ac7c773890fe4d8f231686 Mon Sep 17 00:00:00 2001 From: Alex Fernandez Luces Date: Fri, 26 Sep 2025 09:42:42 +0200 Subject: [PATCH 1/5] fix: Avoid importing VTK on startup --- .../backends/pyvista/pyvista.py | 11 ++++++++--- .../backends/pyvista/widgets/button.py | 5 ++++- .../backends/pyvista/widgets/hide_buttons.py | 7 +++++-- .../backends/pyvista/widgets/measure.py | 6 ++++-- .../backends/pyvista/widgets/mesh_slider.py | 5 ++++- .../backends/pyvista/widgets/pick_rotation_center.py | 4 +++- .../backends/pyvista/widgets/ruler.py | 3 ++- .../backends/pyvista/widgets/screenshot.py | 3 ++- 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py b/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py index d99ddedd..cbd933fd 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py @@ -26,9 +26,6 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union import pyvista as pv -from vtkmodules.vtkCommonCore import vtkCommand -from vtkmodules.vtkInteractionWidgets import vtkHoverWidget -from vtkmodules.vtkRenderingCore import vtkPointPicker import ansys.tools.visualization_interface from ansys.tools.visualization_interface.backends._base import BaseBackend @@ -110,6 +107,10 @@ def __init__( **plotter_kwargs, ) -> None: """Initialize the ``use_trame`` parameter and save the current ``pv.OFF_SCREEN`` value.""" + + from vtkmodules.vtkInteractionWidgets import vtkHoverWidget + from vtkmodules.vtkRenderingCore import vtkPointPicker + # Check if the use of trame was requested if use_trame is None: use_trame = ansys.tools.visualization_interface.USE_TRAME @@ -417,6 +418,10 @@ def enable_set_focus_center(self): def enable_hover(self): """Enable hover capabilities in the plotter.""" + + from vtkmodules.vtkCommonCore import vtkCommand + from vtkmodules.vtkInteractionWidgets import vtkHoverWidget + self._hover_widget = vtkHoverWidget() self._hover_widget.SetInteractor(self._pl.scene.iren.interactor) self._hover_widget.SetTimerDuration(100) # Time (ms) required to trigger a hover event diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/button.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/button.py index 462861a2..9309f1ec 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/button.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/button.py @@ -25,7 +25,6 @@ from pathlib import Path from pyvista import Plotter -from vtk import vtkButtonWidget, vtkPNGReader from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget @@ -49,6 +48,8 @@ class Button(PlotterWidget): def __init__(self, plotter: Plotter, button_config: tuple, dark_mode: bool = False) -> None: """Initialize the ``Button`` class.""" + from vtk import vtkButtonWidget + super().__init__(plotter) self._dark_mode = dark_mode self._button: vtkButtonWidget = self.plotter.add_checkbox_button_widget( @@ -70,6 +71,8 @@ def callback(self, state: bool) -> None: def update(self) -> None: """Assign the image that represents the button.""" + from vtk import vtkPNGReader + if self._dark_mode: is_inv = "_inv" else: diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/hide_buttons.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/hide_buttons.py index 360f9a9c..514d3e30 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/hide_buttons.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/hide_buttons.py @@ -23,8 +23,6 @@ from pathlib import Path from typing import TYPE_CHECKING -from vtk import vtkActor, vtkButtonWidget, vtkPNGReader - from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget if TYPE_CHECKING: @@ -45,6 +43,9 @@ class HideButton(PlotterWidget): def __init__(self, plotter: "Plotter", dark_mode: bool = False) -> None: """Initialize the ``HideButton`` class.""" + from vtk import vtkActor, vtkButtonWidget + + # Call PlotterWidget ctor super().__init__(plotter._pl.scene) self._dark_mode = dark_mode @@ -77,6 +78,8 @@ def callback(self, state: bool) -> None: def update(self) -> None: """Define the hide widget button parameters.""" + from vtk import vtkPNGReader + if self._dark_mode: is_inv = "_inv" else: diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/measure.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/measure.py index db01d18a..275fbf33 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/measure.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/measure.py @@ -23,8 +23,6 @@ from pathlib import Path from typing import TYPE_CHECKING -from vtk import vtkActor, vtkButtonWidget, vtkPNGReader - from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget if TYPE_CHECKING: @@ -45,6 +43,8 @@ class MeasureWidget(PlotterWidget): def __init__(self, plotter_helper: "Plotter", dark_mode: bool = False) -> None: """Initialize the ``MeasureWidget`` class.""" + from vtk import vtkActor, vtkButtonWidget + # Call PlotterWidget ctor super().__init__(plotter_helper._pl.scene) self._dark_mode = dark_mode @@ -88,6 +88,8 @@ def callback(self, state: bool) -> None: self._widget = self.plotter_helper._pl.scene.add_measurement_widget() def update(self) -> None: + from vtk import vtkPNGReader + """Define the measurement widget button parameters.""" if self._dark_mode: is_inv = "_inv" diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/mesh_slider.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/mesh_slider.py index 11c26d1b..3fe0d392 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/mesh_slider.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/mesh_slider.py @@ -24,7 +24,6 @@ from typing import TYPE_CHECKING import pyvista as pv -from vtk import vtkActor, vtkButtonWidget, vtkPNGReader from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget @@ -45,6 +44,8 @@ class MeshSliderWidget(PlotterWidget): def __init__(self, plotter_helper: "Plotter", dark_mode: bool = False) -> None: """Initialize the ``MeshSliderWidget`` class.""" + from vtk import vtkActor, vtkButtonWidget + # Call PlotterWidget ctor super().__init__(plotter_helper._pl.scene) self._dark_mode = dark_mode @@ -103,6 +104,8 @@ def callback(self, state: bool) -> None: def update(self) -> None: """Define the mesh slider widget button parameters.""" + from vtk import vtkPNGReader + if self._dark_mode: is_inv = "_inv" else: diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py index 30c6d5e6..bbe5d4cf 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py @@ -23,7 +23,6 @@ from pathlib import Path from typing import TYPE_CHECKING -from vtk import vtkActor, vtkButtonWidget, vtkPNGReader from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget @@ -45,6 +44,7 @@ class PickRotCenterButton(PlotterWidget): def __init__(self, plotter_helper: "Plotter", dark_mode: bool = False) -> None: """Initialize the ``PickRotCenterWidget`` class.""" + from vtk import vtkActor, vtkButtonWidget # Call PlotterWidget ctor super().__init__(plotter_helper._pl.scene) self._dark_mode = dark_mode @@ -94,6 +94,8 @@ def callback(self, state: bool) -> None: def update(self) -> None: """Define the measurement widget button parameters.""" + + from vtk import vtkPNGReader if self._dark_mode: is_inv = "_inv" else: diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/ruler.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/ruler.py index ea013974..95112813 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/ruler.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/ruler.py @@ -24,7 +24,6 @@ from pathlib import Path from pyvista import Plotter -from vtk import vtkActor, vtkButtonWidget, vtkPNGReader from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget @@ -43,6 +42,7 @@ class Ruler(PlotterWidget): def __init__(self, plotter: Plotter, dark_mode: bool = False) -> None: """Initialize the ``Ruler`` class.""" + from vtk import vtkActor, vtkButtonWidget # Call PlotterWidget ctor super().__init__(plotter) self._dark_mode = dark_mode @@ -85,6 +85,7 @@ def callback(self, state: bool) -> None: def update(self) -> None: """Define the configuration and representation of the ruler widget button.""" + from vtk import vtkPNGReader if self._dark_mode: is_inv = "_inv" else: diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/screenshot.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/screenshot.py index c23281aa..f5aa7d5f 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/screenshot.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/screenshot.py @@ -24,7 +24,6 @@ from pathlib import Path from pyvista import Plotter -from vtk import vtkActor, vtkButtonWidget, vtkPNGReader from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget @@ -43,6 +42,7 @@ class ScreenshotButton(PlotterWidget): def __init__(self, plotter: Plotter, dark_mode: bool = False) -> None: """Initialize the ``ScreenshotButton`` class.""" + from vtk import vtkActor, vtkButtonWidget # Call PlotterWidget ctor super().__init__(plotter) self._dark_mode = dark_mode @@ -77,6 +77,7 @@ def callback(self, state: bool) -> None: def update(self) -> None: """Define the configuration and representation of the screenshot widget button.""" + from vtk import vtkPNGReader if self._dark_mode: is_inv = "_inv" else: From 49e3cc6ae43556c14e5380184d284c37de9d0b20 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Fri, 26 Sep 2025 07:44:59 +0000 Subject: [PATCH 2/5] chore: adding changelog file 358.miscellaneous.md [dependabot-skip] --- doc/changelog.d/358.miscellaneous.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/358.miscellaneous.md diff --git a/doc/changelog.d/358.miscellaneous.md b/doc/changelog.d/358.miscellaneous.md new file mode 100644 index 00000000..6d6bc633 --- /dev/null +++ b/doc/changelog.d/358.miscellaneous.md @@ -0,0 +1 @@ +Fix: Avoid importing VTK on startup From 718991ecf0e8abce331474240970b84732358829 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 07:47:50 +0000 Subject: [PATCH 3/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../tools/visualization_interface/backends/pyvista/pyvista.py | 2 -- .../backends/pyvista/widgets/pick_rotation_center.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py b/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py index cbd933fd..8e3a5ae3 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py @@ -107,7 +107,6 @@ def __init__( **plotter_kwargs, ) -> None: """Initialize the ``use_trame`` parameter and save the current ``pv.OFF_SCREEN`` value.""" - from vtkmodules.vtkInteractionWidgets import vtkHoverWidget from vtkmodules.vtkRenderingCore import vtkPointPicker @@ -418,7 +417,6 @@ def enable_set_focus_center(self): def enable_hover(self): """Enable hover capabilities in the plotter.""" - from vtkmodules.vtkCommonCore import vtkCommand from vtkmodules.vtkInteractionWidgets import vtkHoverWidget diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py index bbe5d4cf..2d1f529e 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py @@ -23,7 +23,6 @@ from pathlib import Path from typing import TYPE_CHECKING - from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget if TYPE_CHECKING: @@ -94,7 +93,6 @@ def callback(self, state: bool) -> None: def update(self) -> None: """Define the measurement widget button parameters.""" - from vtk import vtkPNGReader if self._dark_mode: is_inv = "_inv" From 06cdb253438108d9cbe8347b8c862a93b7f42f94 Mon Sep 17 00:00:00 2001 From: Alex Fernandez Luces Date: Fri, 26 Sep 2025 11:22:28 +0200 Subject: [PATCH 4/5] fix: Pre-commit --- .../tools/visualization_interface/backends/pyvista/pyvista.py | 2 -- .../backends/pyvista/widgets/pick_rotation_center.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py b/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py index cbd933fd..8e3a5ae3 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/pyvista.py @@ -107,7 +107,6 @@ def __init__( **plotter_kwargs, ) -> None: """Initialize the ``use_trame`` parameter and save the current ``pv.OFF_SCREEN`` value.""" - from vtkmodules.vtkInteractionWidgets import vtkHoverWidget from vtkmodules.vtkRenderingCore import vtkPointPicker @@ -418,7 +417,6 @@ def enable_set_focus_center(self): def enable_hover(self): """Enable hover capabilities in the plotter.""" - from vtkmodules.vtkCommonCore import vtkCommand from vtkmodules.vtkInteractionWidgets import vtkHoverWidget diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py index bbe5d4cf..2d1f529e 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/pick_rotation_center.py @@ -23,7 +23,6 @@ from pathlib import Path from typing import TYPE_CHECKING - from ansys.tools.visualization_interface.backends.pyvista.widgets.widget import PlotterWidget if TYPE_CHECKING: @@ -94,7 +93,6 @@ def callback(self, state: bool) -> None: def update(self) -> None: """Define the measurement widget button parameters.""" - from vtk import vtkPNGReader if self._dark_mode: is_inv = "_inv" From 6c75f0fa5ecffe0796e28bc7da6258224c574efb Mon Sep 17 00:00:00 2001 From: Alex Fernandez Luces Date: Fri, 26 Sep 2025 12:14:00 +0200 Subject: [PATCH 5/5] fix: Pre-commit --- .../visualization_interface/backends/pyvista/widgets/measure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/measure.py b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/measure.py index 275fbf33..86224d1e 100644 --- a/src/ansys/tools/visualization_interface/backends/pyvista/widgets/measure.py +++ b/src/ansys/tools/visualization_interface/backends/pyvista/widgets/measure.py @@ -88,9 +88,9 @@ def callback(self, state: bool) -> None: self._widget = self.plotter_helper._pl.scene.add_measurement_widget() def update(self) -> None: + """Define the measurement widget button parameters.""" from vtk import vtkPNGReader - """Define the measurement widget button parameters.""" if self._dark_mode: is_inv = "_inv" else: