Source code for solidipes.viewers.pyvista_plotter

import pyvista as pv
from streamlit_pyvista.mesh_viewer_component import MeshViewerComponent
from streamlit_pyvista.server_managers import ServerManagerProxified
from streamlit_pyvista.trame_viewers import get_advanced_viewer_path

import solidipes.loaders.data_container
from .viewer import Viewer
from .. import loaders
from ..loaders import FileSequence
from ..utils import viewer_backends


[docs] class PyvistaPlotter(Viewer): """Viewer for pyvista meshes Args: **kwargs: keyword arguments passed to the pyvista.Plotter constructor """ def __init__(self, data_container=None, add_kwargs={}, show_kwargs={}, **kwargs): self.compatible_data_types = [loaders.PyvistaMesh] #: keeps track of whether the plotter has already been shown self.shown = False #: Pyvista plotter self.plotter = None if viewer_backends.current_backend == "streamlit": self.plotter = pv.Plotter(off_screen=True, **kwargs) else: # python or jupyter notebook self.plotter = pv.Plotter(**kwargs) self.plotter.background_color = "black" self.meshes = [] self.points = [] self.path_list = [] super().__init__(data_container, add_kwargs=add_kwargs, show_kwargs=show_kwargs) self._update_path_list(data_container)
[docs] def add(self, data_container, **kwargs): """Add mesh to the viewer Args: **kwargs: keyword arguments passed to the pyvista.Plotter.add_mesh method """ self.check_data_compatibility(data_container) if isinstance(data_container, loaders.Abaqus): for name, m in data_container.meshes.items(): self.meshes.append((m, kwargs)) elif isinstance(data_container, loaders.DataContainer): self.add_mesh(data_container, **kwargs)
[docs] def add_mesh(self, data_container: solidipes.loaders.data_container.DataContainer, **kwargs): """Add mesh to the viewer Args: **kwargs: keyword arguments passed to the pyvista.Plotter.add_mesh method """ data = data_container.mesh self.meshes.append((data, kwargs)) self._update_path_list(data_container)
[docs] def _update_path_list(self, data_container): if isinstance(data_container, FileSequence): path = data_container.paths.copy() self.path_list.extend(path) else: if data_container is not None: path = data_container.file_info.path self.path_list.append(path)
[docs] def add_points(self, data_container, **kwargs): """Add mesh as points to the viewer Args: **kwargs: keyword arguments passed to the pyvista.Plotter.add_points method """ data = data_container.mesh self.points.append((data, kwargs))
[docs] def show(self, auto_close=False, **kwargs): """Show the viewer Args: auto_close: whether to close the viewer after showing it **kwargs: keyword arguments passed to the pyvista.Plotter.show method """ for p, _kwargs in self.points: self.plotter.add_points(p, **_kwargs) for m, _kwargs in self.meshes: self.plotter.add_mesh(m, **_kwargs) if viewer_backends.current_backend == "streamlit": key = f"pyvista_ploter_{self.path_list}" import streamlit as st for p, _ in self.points: st.write(p) # Display arrays of the raw data for i, (m, kw) in enumerate(self.meshes): options_key = key + f"mesh_{i}_options" if options_key not in st.session_state: st.session_state[options_key] = ["None"] + m.array_names st.write(m) if len(self.path_list) == 0: st.error("No mesh passed to the PyvistaPlotter") return self.shown = True # Instantiate the viewer MeshViewerComponent(self.path_list, trame_viewer_class=get_advanced_viewer_path(), server_manager_class=ServerManagerProxified).show() elif viewer_backends.current_backend == "python": self.shown = True self.plotter.show(kwargs) else: self.shown = True MeshViewerComponent(self.path_list, trame_viewer_class=get_advanced_viewer_path(), server_manager_class=ServerManagerProxified).show()
[docs] def save(self, path, **kwargs): """Save the view to a file Args: path: path to the file **kwargs: keyword arguments passed to the pyvista.Plotter.screenshot method """ # Pyvista Plotter must be shown before saving if not self.shown: self.plotter.show(auto_close=False) # also for streamlit backend self.shown = True self.plotter.screenshot(path, **kwargs)