예제 #1
0
def test_background_plotting_menu_bar(qtbot):
    with pytest.raises(TypeError, match='menu_bar'):
        BackgroundPlotter(off_screen=False, menu_bar="foo")

    plotter = BackgroundPlotter(off_screen=False, menu_bar=False)
    assert plotter.main_menu is None
    assert plotter._menu_close_action is None
    plotter.close()

    plotter = BackgroundPlotter(off_screen=False)  # menu_bar=True

    assert _hasattr(plotter, "app_window", MainWindow)
    assert _hasattr(plotter, "main_menu", QMenuBar)
    assert _hasattr(plotter, "_menu_close_action", QAction)

    window = plotter.app_window
    main_menu = plotter.main_menu
    assert not main_menu.isNativeMenuBar()

    with qtbot.wait_exposed(window, timeout=500):
        window.show()

    assert main_menu.isVisible()
    plotter.close()
    assert not main_menu.isVisible()
예제 #2
0
def test_background_plotting_toolbar(qtbot, plotting):
    with pytest.raises(TypeError, match='toolbar'):
        p = BackgroundPlotter(off_screen=False, toolbar="foo")
        p.close()

    plotter = BackgroundPlotter(off_screen=False, toolbar=False)
    assert plotter.default_camera_tool_bar is None
    assert plotter.saved_camera_positions is None
    assert plotter.saved_cameras_tool_bar is None
    plotter.close()

    plotter = BackgroundPlotter(off_screen=False)

    assert_hasattr(plotter, "app_window", MainWindow)
    assert_hasattr(plotter, "default_camera_tool_bar", QToolBar)
    assert_hasattr(plotter, "saved_camera_positions", list)
    assert_hasattr(plotter, "saved_cameras_tool_bar", QToolBar)

    window = plotter.app_window
    default_camera_tool_bar = plotter.default_camera_tool_bar
    saved_cameras_tool_bar = plotter.saved_cameras_tool_bar

    with qtbot.wait_exposed(window):
        window.show()

    assert default_camera_tool_bar.isVisible()
    assert saved_cameras_tool_bar.isVisible()

    # triggering a view action
    plotter._view_action.trigger()

    plotter.close()
예제 #3
0
def _create_testing_scene(empty_scene, show=False, off_screen=False):
    if empty_scene:
        plotter = BackgroundPlotter(show=show, off_screen=off_screen)
    else:
        plotter = BackgroundPlotter(shape=(2, 2),
                                    border=True,
                                    border_width=10,
                                    border_color='grey',
                                    show=show,
                                    off_screen=off_screen)
        plotter.set_background('black', top='blue')
        plotter.subplot(0, 0)
        cone = pyvista.Cone(resolution=4)
        actor = plotter.add_mesh(cone)
        plotter.remove_actor(actor)
        plotter.add_text('Actor is removed')
        plotter.subplot(0, 1)
        plotter.add_mesh(pyvista.Box(), color='green', opacity=0.8)
        plotter.subplot(1, 0)
        cylinder = pyvista.Cylinder(resolution=6)
        plotter.add_mesh(cylinder, smooth_shading=True)
        plotter.show_bounds()
        plotter.subplot(1, 1)
        sphere = pyvista.Sphere(phi_resolution=6, theta_resolution=6)
        plotter.add_mesh(sphere)
        plotter.enable_cell_picking()
    return plotter
예제 #4
0
def test_off_screen(qtbot):
    plotter = BackgroundPlotter(off_screen=False)
    qtbot.addWidget(plotter.app_window)
    assert not plotter.ren_win.GetOffScreenRendering()
    plotter.close()
    plotter = BackgroundPlotter(off_screen=True)
    qtbot.addWidget(plotter.app_window)
    assert plotter.ren_win.GetOffScreenRendering()
    plotter.close()
예제 #5
0
def test_editor(qtbot):
    timeout = 1000  # adjusted timeout for MacOS

    # editor=True by default
    plotter = BackgroundPlotter(shape=(2, 1))
    qtbot.addWidget(plotter.app_window)
    assert_hasattr(plotter, "editor", Editor)

    # add at least an actor
    plotter.subplot(0, 0)
    plotter.add_mesh(pyvista.Sphere())
    plotter.subplot(1, 0)
    plotter.show_axes()

    editor = plotter.editor
    assert not editor.isVisible()
    with qtbot.wait_exposed(editor, timeout=timeout):
        editor.toggle()
    assert editor.isVisible()

    assert_hasattr(editor, "tree_widget", QTreeWidget)
    tree_widget = editor.tree_widget
    top_item = tree_widget.topLevelItem(0)  # any renderer will do
    assert top_item is not None

    # simulate selection
    with qtbot.wait_signals([tree_widget.itemSelectionChanged],
                            timeout=timeout):
        top_item.setSelected(True)

    # toggle all the renderer-associated checkboxes twice
    # to ensure that slots are called for True and False
    assert_hasattr(editor, "stacked_widget", QStackedWidget)
    stacked_widget = editor.stacked_widget
    page_idx = top_item.data(0, Qt.ItemDataRole.UserRole)
    page_widget = stacked_widget.widget(page_idx)
    page_layout = page_widget.layout()
    number_of_widgets = page_layout.count()
    for widget_idx in range(number_of_widgets):
        widget_item = page_layout.itemAt(widget_idx)
        widget = widget_item.widget()
        if isinstance(widget, QCheckBox):
            with qtbot.wait_signals([widget.toggled], timeout=500):
                widget.toggle()
            with qtbot.wait_signals([widget.toggled], timeout=500):
                widget.toggle()

    # hide the editor for coverage
    editor.toggle()
    plotter.close()

    plotter = BackgroundPlotter(editor=False)
    qtbot.addWidget(plotter.app_window)
    assert plotter.editor is None
    plotter.close()
예제 #6
0
def test_depth_peeling(qtbot):
    plotter = BackgroundPlotter()
    qtbot.addWidget(plotter.app_window)
    assert not plotter.renderer.GetUseDepthPeeling()
    plotter.close()
    global_theme.depth_peeling["enabled"] = True
    plotter = BackgroundPlotter()
    qtbot.addWidget(plotter.app_window)
    assert plotter.renderer.GetUseDepthPeeling()
    plotter.close()
    global_theme.depth_peeling["enabled"] = False
예제 #7
0
def test_smoothing(qtbot):
    plotter = BackgroundPlotter()
    qtbot.addWidget(plotter.app_window)
    assert not plotter.ren_win.GetPolygonSmoothing()
    assert not plotter.ren_win.GetLineSmoothing()
    assert not plotter.ren_win.GetPointSmoothing()
    plotter.close()
    plotter = BackgroundPlotter(
        polygon_smoothing=True,
        line_smoothing=True,
        point_smoothing=True,
    )
    qtbot.addWidget(plotter.app_window)
    assert plotter.ren_win.GetPolygonSmoothing()
    assert plotter.ren_win.GetLineSmoothing()
    assert plotter.ren_win.GetPointSmoothing()
    plotter.close()
예제 #8
0
def test_background_plotting_menu_bar(qtbot, plotting):
    with pytest.raises(TypeError, match='menu_bar'):
        p = BackgroundPlotter(off_screen=False, menu_bar="foo")
        p.close()

    plotter = BackgroundPlotter(off_screen=False, menu_bar=False)
    assert plotter.main_menu is None
    assert plotter._menu_close_action is None
    plotter.close()

    plotter = BackgroundPlotter(off_screen=False)  # menu_bar=True

    assert_hasattr(plotter, "app_window", MainWindow)
    assert_hasattr(plotter, "main_menu", QMenuBar)
    assert_hasattr(plotter, "_menu_close_action", QAction)
    assert_hasattr(plotter, "_edl_action", QAction)
    assert_hasattr(plotter, "_parallel_projection_action", QAction)

    window = plotter.app_window
    main_menu = plotter.main_menu
    assert not main_menu.isNativeMenuBar()

    with qtbot.wait_exposed(window):
        window.show()

    # EDL action
    assert not hasattr(plotter.renderer, 'edl_pass')
    plotter._edl_action.trigger()
    assert hasattr(plotter.renderer, 'edl_pass')
    # and now test reset
    plotter._edl_action.trigger()

    # Parallel projection action
    assert not plotter.camera.GetParallelProjection()
    plotter._parallel_projection_action.trigger()
    assert plotter.camera.GetParallelProjection()
    # and now test reset
    plotter._parallel_projection_action.trigger()

    assert main_menu.isVisible()
    plotter.close()
    assert not main_menu.isVisible()
    assert plotter._last_update_time == -np.inf
예제 #9
0
def test_background_plotting_add_callback(qtbot):
    class CallBack(object):
        def __init__(self, sphere):
            self.sphere = sphere

        def __call__(self):
            self.sphere.points *= 0.5

    plotter = BackgroundPlotter(show=False,
                                off_screen=False,
                                title='Testing Window')
    sphere = pyvista.Sphere()
    mycallback = CallBack(sphere)
    plotter.add_mesh(sphere)
    plotter.add_callback(mycallback, interval=200, count=3)

    # check that timers are set properly in add_callback()
    assert _hasattr(plotter, "app_window", MainWindow)
    assert _hasattr(plotter, "_callback_timer", QTimer)
    assert _hasattr(plotter, "counters", list)

    window = plotter.app_window  # MainWindow
    callback_timer = plotter._callback_timer  # QTimer
    counter = plotter.counters[-1]  # Counter

    # ensure that the window is showed
    assert not window.isVisible()
    with qtbot.wait_exposed(window, timeout=500):
        window.show()
    assert window.isVisible()
    # ensure that self.callback_timer send a signal
    callback_blocker = qtbot.wait_signals([callback_timer.timeout],
                                          timeout=300)
    callback_blocker.wait()
    # ensure that self.counters send a signal
    counter_blocker = qtbot.wait_signals([counter.signal_finished],
                                         timeout=700)
    counter_blocker.wait()
    assert not callback_timer.isActive()  # counter stops the callback

    plotter.add_callback(mycallback, interval=200)
    callback_timer = plotter._callback_timer  # QTimer

    # ensure that self.callback_timer send a signal
    callback_blocker = qtbot.wait_signals([callback_timer.timeout],
                                          timeout=300)
    callback_blocker.wait()

    assert callback_timer.isActive()
    plotter.close()
    assert not callback_timer.isActive()  # window stops the callback
예제 #10
0
    def draw_3D(
        self,
        opacity: float = 1,
        display_p_int: bool = True,
        molecule_opacity: float = 1,
        atom_scale: float = 1,
    ) -> None:
        """Draw surface with mapped P_int values.

        Args:
            opacity: Surface opacity
            display_p_int: Whether to display P_int mapped onto the surface
            molecule_opacity: Molecule opacity
            atom_scale: Scale factor for atom size
        """
        # Set up plotter
        p = BackgroundPlotter()

        # Draw molecule
        for atom in self._atoms:
            color = hex2color(jmol_colors[atom.element])
            radius = atom.radius * atom_scale
            sphere = pv.Sphere(center=list(atom.coordinates), radius=radius)
            p.add_mesh(sphere,
                       color=color,
                       opacity=molecule_opacity,
                       name=str(atom.index))

        cmap: Optional[str]
        # Set up plotting of mapped surface
        if display_p_int is True:
            color = None
            cmap = "coolwarm"
        else:
            color = "tan"
            cmap = None

        # Draw surface
        if self._surface:
            p.add_mesh(self._surface, opacity=opacity, color=color, cmap=cmap)
        else:
            point_cloud = pv.PolyData(self._points)
            point_cloud["values"] = self.p_values
            p.add_mesh(
                point_cloud,
                opacity=opacity,
                color=color,
                cmap=cmap,
                render_points_as_spheres=True,
            )
예제 #11
0
    def draw_3D(
        self,
        atom_scale: float = 1,
        background_color: str = "white",
        cone_color: str = "steelblue",
        cone_opacity: float = 0.75,
    ) -> None:
        """Draw a 3D representation of the molecule with the cone.

        Args:
            atom_scale: Scaling factor for atom size
            background_color: Background color for plot
            cone_color: Cone color
            cone_opacity: Cone opacity
        """
        # Set up plotter
        p = BackgroundPlotter()
        p.set_background(background_color)

        # Draw molecule
        for atom in self._atoms:
            color = hex2color(jmol_colors[atom.element])
            radius = atom.radius * atom_scale
            sphere = pv.Sphere(center=list(atom.coordinates), radius=radius)
            p.add_mesh(sphere, color=color, opacity=1, name=str(atom.index))

        # Determine direction and extension of cone
        angle = math.degrees(self._cone.angle)
        coordinates: Array2DFloat = np.array([atom.coordinates for atom in self._atoms])
        radii: Array1DFloat = np.array([atom.radius for atom in self._atoms])
        if angle > 180:
            normal = -self._cone.normal
        else:
            normal = self._cone.normal
        projected = np.dot(normal, coordinates.T) + np.array(radii)

        max_extension = np.max(projected)
        if angle > 180:
            max_extension += 1

        # Make the cone
        cone = get_drawing_cone(
            center=[0, 0, 0] + (max_extension * normal) / 2,
            direction=-normal,
            angle=angle,
            height=max_extension,
            capping=False,
            resolution=100,
        )
        p.add_mesh(cone, opacity=cone_opacity, color=cone_color)
예제 #12
0
def test_background_plotter_export_vtkjs(qtbot, tmpdir, show_plotter, plotting):
    # setup filesystem
    output_dir = str(tmpdir.mkdir("tmpdir"))
    assert os.path.isdir(output_dir)

    plotter = BackgroundPlotter(
        show=show_plotter,
        off_screen=False,
        title='Testing Window'
    )
    assert_hasattr(plotter, "app_window", MainWindow)
    window = plotter.app_window  # MainWindow
    qtbot.addWidget(window)  # register the window

    # show the window
    if not show_plotter:
        assert not window.isVisible()
        with qtbot.wait_exposed(window):
            window.show()
    assert window.isVisible()

    plotter.add_mesh(pyvista.Sphere())
    assert_hasattr(plotter, "renderer", Renderer)
    renderer = plotter.renderer
    assert len(renderer._actors) == 1
    assert np.any(plotter.mesh.points)

    dlg = plotter._qt_export_vtkjs(show=False)  # FileDialog
    qtbot.addWidget(dlg)  # register the dialog

    filename = str(os.path.join(output_dir, "tmp"))
    dlg.selectFile(filename)

    # show the dialog
    assert not dlg.isVisible()
    with qtbot.wait_exposed(dlg):
        dlg.show()
    assert dlg.isVisible()

    # synchronise signal and callback
    with qtbot.wait_signals([dlg.dlg_accepted], timeout=1000):
        dlg.accept()
    assert not dlg.isVisible()  # dialog is closed after accept()

    plotter.close()
    assert not window.isVisible()
    assert os.path.isfile(filename + '.vtkjs')
예제 #13
0
def test_background_plotting_axes_scale(qtbot, show_plotter, plotting):
    plotter = BackgroundPlotter(
        show=show_plotter,
        off_screen=False,
        title='Testing Window'
    )
    assert_hasattr(plotter, "app_window", MainWindow)
    window = plotter.app_window  # MainWindow
    qtbot.addWidget(window)  # register the window

    # show the window
    if not show_plotter:
        assert not window.isVisible()
        with qtbot.wait_exposed(window):
            window.show()
    assert window.isVisible()

    plotter.add_mesh(pyvista.Sphere())
    assert_hasattr(plotter, "renderer", Renderer)
    renderer = plotter.renderer
    assert len(renderer._actors) == 1
    assert np.any(plotter.mesh.points)

    dlg = plotter.scale_axes_dialog(show=False)  # ScaleAxesDialog
    qtbot.addWidget(dlg)  # register the dialog

    # show the dialog
    assert not dlg.isVisible()
    with qtbot.wait_exposed(dlg):
        dlg.show()
    assert dlg.isVisible()

    value = 2.0
    dlg.x_slider_group.value = value
    assert plotter.scale[0] == value
    dlg.x_slider_group.spinbox.setValue(-1)
    assert dlg.x_slider_group.value == 0
    dlg.x_slider_group.spinbox.setValue(1000.0)
    assert dlg.x_slider_group.value < 100

    plotter._last_update_time = 0.0
    plotter.update()
    plotter.update_app_icon()
    plotter.close()
    assert not window.isVisible()
    assert not dlg.isVisible()
예제 #14
0
def test_background_plotting_camera(qtbot, plotting):
    plotter = BackgroundPlotter(off_screen=False, title='Testing Window')
    plotter.add_mesh(pyvista.Sphere())

    cpos = [(0.0, 0.0, 1.0), (0.0, 0.0, 0.0), (0.0, 1.0, 0.0)]
    plotter.camera_position = cpos
    plotter.save_camera_position()
    plotter.camera_position = [(0.0, 0.0, 3.0), (0.0, 0.0, 0.0), (0.0, 1.0, 0.0)]

    # load existing position
    # NOTE: 2 because first two (0 and 1) buttons save and clear positions
    plotter.saved_cameras_tool_bar.actions()[2].trigger()
    assert plotter.camera_position == cpos

    plotter.clear_camera_positions()
    # 2 because the first two buttons are save and clear
    assert len(plotter.saved_cameras_tool_bar.actions()) == 2
    plotter.close()
예제 #15
0
 def plot_boreholes(self, notebook=False, background=False, **kwargs):
     """
     Uses the previously calculated borehole tubes in self._get_polygon_data()
     when a borehole dictionary is available
     This will generate a pyvista object that can be visualized with .show()
     Args:
         notebook: If using in notebook to show inline
         background:
     Returns:
         Pyvista object with all the boreholes
     """
     self._get_polygon_data()
     if background:
         try:
             p = pv.BackgroundPlotter(**kwargs)
         except pv.QtDeprecationError:
             from pyvistaqt import BackgroundPlotter
             p = BackgroundPlotter(**kwargs)
     else:
         p = pv.Plotter(notebook=notebook, **kwargs)
     for i in range(len(self.borehole_tube)):
         cmap = self.colors_bh[i]
         p.add_mesh(self.borehole_tube[i], cmap=[cmap[j] for j in range(len(cmap)-1)], smooth_shading=False)
     # for i in range(len(self.faults_bh)):
     # for plotting the faults
     # TODO: Messing with the colors when faults
     if len(self.faults_bh) > 0:
         point = pv.PolyData(self.faults_bh)
         p.add_mesh(point, render_points_as_spheres=True, point_size=self._radius_borehole)
         # p.add_mesh(point, cmap = self.faults_color_bh[i],
         # render_points_as_spheres=True, point_size=self._radius_borehole)
     extent = numpy.copy(self._model_extent)
     # extent[-1] = numpy.ceil(self.modelspace_arucos.box_z.max()/100)*100
     p.show_bounds(bounds=extent)
     p.show_grid()
     p.set_scale(zscale=self._ve)
     # self.vtk = pn.panel(p.ren_win, sizing_mode='stretch_width', orientation_widget=True)
     # self.vtk = pn.Row(pn.Column(pan, pan.construct_colorbars()), pn.pane.Str(type(p.ren_win), width=500))
     return p
예제 #16
0
    def __init__(self, parent=None, show=True):
        Qt.QMainWindow.__init__(self, parent)
        self.ds = reader.DataSet("")
        self.meshes = []
        self.plotter = BackgroundPlotter(shape=(1, 2),
                                         border_color='white',
                                         title="MMR Visualization")
        self.setWindowTitle('MMR UI')
        self.frame = Qt.QFrame()
        vlayout = Qt.QVBoxLayout()
        self.normalizer = Normalizer()
        self.frame.setLayout(vlayout)
        self.setCentralWidget(self.frame)
        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('File')
        exitButton = Qt.QAction('Exit', self)
        exitButton.setShortcut('Ctrl+Q')
        exitButton.triggered.connect(self.close)
        fileMenu.addAction(exitButton)
        meshMenu = mainMenu.addMenu('Mesh')

        self.load_mesh = Qt.QAction('Load mesh', self)
        self.load_mesh.triggered.connect(
            lambda: self.add_mesh(self.open_file_name_dialog()))
        meshMenu.addAction(self.load_mesh)

        self.show_norm_pipeline = Qt.QAction('Show norm pipeline', self)
        self.show_norm_pipeline.triggered.connect(
            lambda: self.show_processing(self.open_file_name_dialog()))
        meshMenu.addAction(self.show_norm_pipeline)

        self.extract_features = Qt.QAction('Extract features', self)
        self.extract_features.triggered.connect(lambda: print(
            FeatureExtractor.mono_run_pipeline(self.open_file_name_dialog())))
        meshMenu.addAction(self.extract_features)

        if show:
            self.show()
예제 #17
0
파일: sasa.py 프로젝트: kjelljorner/morfeus
    def draw_3D(
        self,
        atom_scale: float = 1,
        background_color: str = "white",
        point_color: str = "steelblue",
        opacity: float = 0.25,
        size: float = 1,
    ) -> None:
        """Draw a 3D representation.

        Draws the molecule with the solvent accessible surface area.

        Args:
            atom_scale: Scaling factor for atom size
            background_color: Background color for plot
            point_color: Color of surface points
            opacity: Point opacity
            size: Point size
        """
        # Set up plotter
        p = BackgroundPlotter()
        p.set_background(background_color)

        # Draw molecule
        for atom in self._atoms:
            color = hex2color(jmol_colors[atom.element])
            radius = atom.radius * atom_scale - self._probe_radius
            sphere = pv.Sphere(center=list(atom.coordinates), radius=radius)
            p.add_mesh(sphere, color=color, opacity=1, name=str(atom.index))

        # Draw surface points
        surface_points: Array2DFloat = np.vstack(
            [atom.accessible_points for atom in self._atoms])
        p.add_points(surface_points,
                     color=point_color,
                     opacity=opacity,
                     point_size=size)
예제 #18
0
    def show_processing(self, mesh):
        if not mesh:
            print(f"Can't render mesh of type {type(mesh)}")
            return None

        new_data = self.normalizer.mono_run_pipeline(mesh)
        history = new_data["history"]
        num_of_operations = len(history)
        plt = BackgroundPlotter(shape=(2, num_of_operations // 2))
        elements = history
        plt.show_axes_all()
        for idx in range(num_of_operations):
            plt.subplot(int(idx / 3), idx % 3)
            if elements[idx]["op"] == "Center":
                plt.add_mesh(pv.Cube().extract_all_edges())
            curr_mesh = pv.PolyData(elements[idx]["data"]["vertices"],
                                    elements[idx]["data"]["faces"])
            plt.add_mesh(curr_mesh, color='w', show_edges=True)
            plt.reset_camera()
            plt.view_isometric()
            plt.add_text(elements[idx]["op"] + "\nVertices: " +
                         str(len(curr_mesh.points)) + "\nFaces: " +
                         str(curr_mesh.n_faces))
            plt.show_grid()
예제 #19
0
    def __init__(self,
                 model,
                 plotter_type: str = 'basic',
                 extent=None,
                 lith_c=None,
                 live_updating=False,
                 **kwargs):
        """GemPy 3-D visualization using pyVista.

        Args:
            model (gp.Model): Geomodel instance with solutions.
            plotter_type (str): Set the plotter type. Defaults to 'basic'.
            extent (List[float], optional): Custom extent. Defaults to None.
            lith_c (pn.DataFrame, optional): Custom color scheme in the form of
                a look-up table. Defaults to None.
            live_updating (bool, optional): Toggles real-time updating of the
                plot. Defaults to False.
            **kwargs:

        """

        # Override default notebook value
        pv.set_plot_theme("document")
        kwargs['notebook'] = kwargs.get('notebook', False)

        # Model properties
        self.model = model
        self.extent = model._grid.regular_grid.extent if extent is None else extent

        # plotting options
        self.live_updating = live_updating

        # Choosing plotter
        if plotter_type == 'basic':
            self.p = pv.Plotter(**kwargs)
            self.p.view_isometric(negative=False)
        elif plotter_type == 'notebook':
            raise NotImplementedError
            # self.p = pv.PlotterITK()
        elif plotter_type == 'background':
            try:
                self.p = pv.BackgroundPlotter(**kwargs)
            except pv.QtDeprecationError:
                from pyvistaqt import BackgroundPlotter
                self.p = BackgroundPlotter(**kwargs)
            self.p.view_isometric(negative=False)
        else:
            raise AttributeError(
                'Plotter type must be basic, background or notebook.')

        self.plotter_type = plotter_type
        # Default camera and bounds
        self.set_bounds()
        self.p.view_isometric(negative=False)

        # Actors containers
        self.surface_actors = {}
        self.surface_poly = {}

        self.regular_grid_actor = None
        self.regular_grid_mesh = None

        self.surface_points_actor = None
        self.surface_points_mesh = None
        self.surface_points_widgets = {}

        self.orientations_actor = None
        self.orientations_mesh = None
        self.orientations_widgets = {}

        # Private attributes
        self._grid_values = None
        col = matplotlib.cm.get_cmap('viridis')(np.linspace(0, 1, 255)) * 255
        nv = numpy_to_vtk(col, array_type=3)
        self._cmaps = {'viridis': nv}

        # Topology properties
        self.topo_edges = None
        self.topo_ctrs = None
예제 #20
0
    def draw_3D(
        self,
        atom_scale: float = 0.5,
        background_color: str = "white",
        arrow_color: str = "steelblue",
    ) -> None:
        """Draw a 3D representation of the molecule with the Sterimol vectors.

        Args:
            atom_scale: Scaling factor for atom size
            background_color: Background color for plot
            arrow_color: Arrow color
        """
        # Set up plotter
        p = BackgroundPlotter()
        p.set_background(background_color)

        # Draw molecule
        for atom in self._atoms:
            color = hex2color(jmol_colors[atom.element])
            if atom.element == 0:
                radius = 0.5 * atom_scale
            else:
                radius = atom.radius * atom_scale
            sphere = pv.Sphere(center=list(atom.coordinates), radius=radius)
            if atom.index in self._excluded_atoms:
                opacity = 0.25
            else:
                opacity = 1
            p.add_mesh(sphere,
                       color=color,
                       opacity=opacity,
                       name=str(atom.index))

        # Draw sphere for Buried Sterimol
        if hasattr(self, "_sphere_radius"):
            sphere = pv.Sphere(center=self._dummy_atom.coordinates,
                               radius=self._sphere_radius)
            p.add_mesh(sphere, opacity=0.25)

        if hasattr(self, "_points"):
            p.add_points(self._points, color="gray")

        # Get arrow starting points
        start_L = self._dummy_atom.coordinates
        start_B = self._attached_atom.coordinates

        # Add L arrow with label
        length = np.linalg.norm(self.L)
        direction = self.L / length
        stop_L = start_L + length * direction
        L_arrow = get_drawing_arrow(start=start_L,
                                    direction=direction,
                                    length=length)
        p.add_mesh(L_arrow, color=arrow_color)

        # Add B_1 arrow
        length = np.linalg.norm(self.B_1)
        direction = self.B_1 / length
        stop_B_1 = start_B + length * direction
        B_1_arrow = get_drawing_arrow(start=start_B,
                                      direction=direction,
                                      length=length)
        p.add_mesh(B_1_arrow, color=arrow_color)

        # Add B_5 arrow
        length = np.linalg.norm(self.B_5)
        direction = self.B_5 / length
        stop_B_5 = start_B + length * direction
        B_5_arrow = get_drawing_arrow(start=start_B,
                                      direction=direction,
                                      length=length)
        p.add_mesh(B_5_arrow, color=arrow_color)

        # Add labels
        points = np.vstack([stop_L, stop_B_1, stop_B_5])
        labels = ["L", "B1", "B5"]
        p.add_point_labels(
            points,
            labels,
            text_color="black",
            font_size=30,
            bold=False,
            show_points=False,
            point_size=1,
        )

        self._plotter = p
예제 #21
0
def test_background_plotting_add_callback(qtbot, monkeypatch, plotting):
    class CallBack(object):
        def __init__(self, sphere):
            self.sphere = sphere

        def __call__(self):
            self.sphere.points *= 0.5

    update_count = [0]
    orig_update_app_icon = BackgroundPlotter.update_app_icon

    def update_app_icon(slf):
        update_count[0] = update_count[0] + 1
        return orig_update_app_icon(slf)

    monkeypatch.setattr(BackgroundPlotter, 'update_app_icon', update_app_icon)
    plotter = BackgroundPlotter(
        show=False,
        off_screen=False,
        title='Testing Window',
        update_app_icon=True,  # also does add_callback
    )
    assert plotter._last_update_time == -np.inf
    sphere = pyvista.Sphere()
    mycallback = CallBack(sphere)
    plotter.add_mesh(sphere)
    plotter.add_callback(mycallback, interval=200, count=3)

    # check that timers are set properly in add_callback()
    assert_hasattr(plotter, "app_window", MainWindow)
    assert_hasattr(plotter, "_callback_timer", QTimer)
    assert_hasattr(plotter, "counters", list)

    window = plotter.app_window  # MainWindow
    callback_timer = plotter._callback_timer  # QTimer
    counter = plotter.counters[-1]  # Counter

    # ensure that the window is showed
    assert not window.isVisible()
    with qtbot.wait_exposed(window):
        window.show()
    assert window.isVisible()
    assert update_count[0] in [0, 1]  # macOS sometimes updates (1)
    # don't check _last_update_time for non-inf-ness, won't be updated on Win
    plotter.update_app_icon()  # the timer doesn't call it right away, so do it
    assert update_count[0] in [1, 2]
    plotter.update_app_icon()  # should be a no-op
    assert update_count[0] in [2, 3]
    with pytest.raises(ValueError, match="ndarray with shape"):
        plotter.set_icon(0.)
    # Maybe someday manually setting "set_icon" should disable update_app_icon?
    # Strings also supported directly by QIcon
    plotter.set_icon(os.path.join(
        os.path.dirname(pyvistaqt.__file__), "data",
        "pyvista_logo_square.png"))

    # ensure that self.callback_timer send a signal
    callback_blocker = qtbot.wait_signals([callback_timer.timeout], timeout=300)
    callback_blocker.wait()
    # ensure that self.counters send a signal
    counter_blocker = qtbot.wait_signals([counter.signal_finished], timeout=700)
    counter_blocker.wait()
    assert not callback_timer.isActive()  # counter stops the callback

    plotter.add_callback(mycallback, interval=200)
    callback_timer = plotter._callback_timer  # QTimer

    # ensure that self.callback_timer send a signal
    callback_blocker = qtbot.wait_signals([callback_timer.timeout], timeout=300)
    callback_blocker.wait()

    assert callback_timer.isActive()
    plotter.close()
    assert not callback_timer.isActive()  # window stops the callback
# -*- coding: utf-8 -*-
"""
    Simplest possible PyVista Background plotter code

    Author: Jari Honkanen

"""

import pyvista as pv
from pyvistaqt import BackgroundPlotter

# Get Sphere shape
sphere = pv.Sphere()

# Instantiate Background Plotter
plotter = BackgroundPlotter()
plotter.add_mesh(sphere)

# Run in Python (iPython not needed)
plotter.app.exec_()

예제 #23
0
def test_background_plotting_orbit(qtbot, plotting):
    plotter = BackgroundPlotter(off_screen=False, title='Testing Window')
    plotter.add_mesh(pyvista.Sphere())
    # perform the orbit:
    plotter.orbit_on_path(threaded=True, step=0.0)
    plotter.close()