
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "gallery/scene/volume_plane.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        Click :ref:`here <sphx_glr_download_gallery_scene_volume_plane.py>`
        to download the full example code

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_gallery_scene_volume_plane.py:


Rendering Planes through 3D Data
================================

Controls:
* 1  - toggle between volume rendering methods
* 2 -  toggle between volume rendering modes ('volume', 'plane')
* [] - shift plane along plane normal
* {} - decrease/increase plane thickness
* Spacebar - stop/start animation

* x/y/z/o - set plane normal along x/y/z or [1,1,1] oblique axis

.. GENERATED FROM PYTHON SOURCE LINES 20-150



.. image-sg:: /gallery/scene/images/sphx_glr_volume_plane_001.gif
   :alt: volume plane
   :srcset: /gallery/scene/images/sphx_glr_volume_plane_001.gif
   :class: sphx-glr-single-img





.. code-block:: default

    import sys

    import numpy as np

    from vispy import app, scene, io
    from vispy.visuals.transforms import STTransform

    # Read volume
    vol = np.load(io.load_data_file('volume/stent.npz'))['arr_0']

    # Prepare canvas
    canvas = scene.SceneCanvas(keys='interactive', show=True)
    view = canvas.central_widget.add_view()

    # Create the volume visual for plane rendering
    plane = scene.visuals.Volume(
        vol,
        parent=view.scene,
        raycasting_mode='plane',
        method='mip',
        plane_thickness=3.0,
        plane_position=(128, 60, 64),
        plane_normal=(1, 0, 0),
    )

    volume = scene.visuals.Volume(
        vol,
        parent=view.scene,
        raycasting_mode='volume',
        method='mip',
    )
    volume.set_gl_state('additive')
    volume.opacity = 0.25

    # Create a camera
    cam = scene.cameras.TurntableCamera(
        parent=view.scene, fov=60.0, azimuth=-42.0, elevation=30.0
    )
    view.camera = cam

    # Create an XYZAxis visual
    axis = scene.visuals.XYZAxis(parent=view)
    s = STTransform(translate=(50, 50), scale=(50, 50, 50, 1))
    affine = s.as_matrix()
    axis.transform = affine


    def update_axis_visual():
        """Sync XYZAxis visual with camera angles"""
        axis.transform.reset()

        axis.transform.rotate(cam.roll, (0, 0, 1))
        axis.transform.rotate(cam.elevation, (1, 0, 0))
        axis.transform.rotate(cam.azimuth, (0, 1, 0))
        axis.transform.scale((50, 50, 0.001))
        axis.transform.translate((50., 50.))

        axis.update()


    update_axis_visual()


    @canvas.events.mouse_move.connect
    def on_mouse_move(event):
        if event.button == 1 and event.is_dragging:
            update_axis_visual()


    # Implement key presses
    @canvas.events.key_press.connect
    def on_key_press(event):
        if event.text == '1':
            methods = ['mip', 'average']
            method = methods[(methods.index(plane.method) + 1) % 2]
            print("Volume render method: %s" % method)
            plane.method = method
        elif event.text == '2':
            modes = ['volume', 'plane']
            if plane.raycasting_mode == modes[0]:
                plane.raycasting_mode = modes[1]
                print(modes[1])
            else:
                plane.raycasting_mode = modes[0]
                print(modes[0])
        elif event.text != '' and event.text in '{}':
            t = -1 if event.text == '{' else 1
            plane.plane_thickness += t
            plane.plane_thickness += t
            print(f"plane thickness: {plane.plane_thickness}")
        elif event.text != '' and event.text in '[]':
            shift = plane.plane_normal / np.linalg.norm(plane.plane_normal)
            if event.text == '[':
                plane.plane_position -= 2 * shift
            elif event.text == ']':
                plane.plane_position += 2 * shift
            print(f"plane position: {plane.plane_position}")
        elif event.text == 'x':
            plane.plane_normal = [0, 0, 1]
        elif event.text == 'y':
            plane.plane_normal = [0, 1, 0]
        elif event.text == 'z':
            plane.plane_normal = [1, 0, 0]
        elif event.text == 'o':
            plane.plane_normal = [1, 1, 1]
        elif event.text == ' ':
            if timer.running:
                timer.stop()
            else:
                timer.start()


    def move_plane(event):
        z_pos = plane.plane_position[0]
        if z_pos < 32:
            plane.plane_position = plane.plane_position + [1, 0, 0]
        elif 32 < z_pos <= 220:
            plane.plane_position = plane.plane_position - [1, 0, 0]
        else:
            plane.plane_position = (220, 64, 64)


    timer = app.Timer('auto', connect=move_plane, start=True)

    if __name__ == '__main__':
        canvas.show()
        print(__doc__)
        if sys.flags.interactive == 0:
            plane.plane_position = (220, 64, 64)
            app.run()


.. rst-class:: sphx-glr-timing

   **Total running time of the script:** ( 0 minutes  17.057 seconds)


.. _sphx_glr_download_gallery_scene_volume_plane.py:


.. only :: html

 .. container:: sphx-glr-footer
    :class: sphx-glr-footer-example



  .. container:: sphx-glr-download sphx-glr-download-python

     :download:`Download Python source code: volume_plane.py <volume_plane.py>`



  .. container:: sphx-glr-download sphx-glr-download-jupyter

     :download:`Download Jupyter notebook: volume_plane.ipynb <volume_plane.ipynb>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
