.. include:: ../macros.hrst
.. include:: ../abbreviations.hrst

.. _chapter:DisplayingData:
.. _ch:DisplayingData:

Displaying data
###############

The goal of any visualization process is to produce visual representations of
the data. The visual representations are shown in modules called views.
*Views*   provide the canvas on which to display such visual representations,
as well as to dictate how these representations are generated from the raw data.
The role of the visualization pipeline is often to transform the data so that
relevant information can be represented in these views.

Referring back to the visualization pipeline from
:numref:`sec:BasicsOfVisualization`, views are sinks that take in input data
but do not produce any data output (i.e., one cannot connect other pipeline
modules such as filters to process the results in a view). However,
views often provide mechanisms to save the results as images or in other formats
including PDF, VRML, and X3D.

Different types of views provide different ways of visualizing data. These can
be broadly grouped as follows:

* *Rendering Views* are views that render geometries or volumes in a graphical context. The  ``Render View``   is one such view. Other Render View-based views, such as  ``Slice View``   and  ``Quad View``  , extend the basic render view to add the ability to add mechanisms to easily inspect slices or generate orthogonal views.

* *Chart Views* cover a wide array of graphs and plots used for visualizing non-geometric data. These include views such as line charts ( ``Line Chart View``  ), bar charts ( ``Bar Chart View``  ), bag charts ( ``Bag Chart View``  ), parallel coordinates ( ``Parallel Coordinates View``  ), etc.

* *Comparative Views* are used to quickly generate side-by-side views for parameter study, i.e., to visualize the effects of parameter changes. Comparative variants of  ``Render View``   and several types of the  ``Chart Views``   are available in |ParaView|.

In this chapter, we take a close look at the various views available in |ParaView|
and how to use these views for displaying data.

Multiple views
==============

.. figure:: ../images/MultipleViewsInParaView.png
    :name: fig:MultipleViewsInParaView
    :width: 70%
    :align: center

    Using multiple views in |paraview| to generate different types of visualizations from a dataset.

With multiple types of views comes the need for creating and viewing multiple
views at the same time. In this section, we look at how you can create multiple
views and lay them out.

.. admonition:: **Did you know?**
  :class: tip

  Multiple views were first supported in |ParaView| 3.0. Before that, all data was
  shown in a single 3D render view, including line plots!

Multiple views in ``paraview``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

|paraview| shows all views in the central part of the application
window. When |paraview| starts up, the  ``Render View``   is created
and shown in the application window by default.

.. \fixme{add image with the viewport window with components labeled}

New views can be created by splitting the
view frame using the  ``Split View``   controls at the top-right corner of the
view frame. Splitting a view divides the view into two equal parts, either
vertically or horizontally, based on the button used for the split.
On splitting a view, an empty frame with buttons for all known types
of views is shown. Simply click on one of those buttons to create a new view of
a chosen type.

You can move views by clicking and dragging the title bar for the view (or
empty view frame) and dropping it on the title bar on another view (or empty
view frame). This will swap the positions of the two views.

Similar to the notion of active source, there is a notion of *active
view*  .
Several panels, toolbars, and menus will update based on the active view. The
``Display``   properties section on the  ``Properties``   panel, for example,
reflects the display properties of the active source in the active view.
Similarly, the eyeball icons in the  ``Pipeline Browser``   show the visibility
status of the pipeline module in the active view. Active view is marked in the
UI by a blue border around the view frame. Only one view can be active at any time
in the application.

Besides being able to create multiple views and laying them out in a pane,
|paraview| also supports placing views in multiple layouts under
separate tabs. To create new tabs, use the |TabWidgetPlus|
button in the tab bar. You can close a tab, which will destroy all views laid out
in that tab, by clicking on the |TitleBarCloseButton| button.
To pop out an entire tab as a
separate window, use the |TitleBarMaxButton| button on the
tab bar.

The active view is always present in the active tab. Thus, if you change the
active tab, the active view will also be changed to be a view in the active tab
layout. Conversely, if the active view is changed (by using the  ``Python
Shell``  , for example), the active tab will automatically be updated to be the tab
that contains the active view.

.. admonition:: **Did you know?**
  :class: tip

  You can make the views of the active layout fullscreen by using :guilabel:`View > Fullscreen (layout)` (or using the |F11| key).
  You can also make the active view alone fullscreen by using :guilabel:`View > Fullscreen (active view)` (or using |CTRL| + |F11| keys).
  To return back to the normal mode, use the |ESC| key.

Multiple views in ``pvpython``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In |pvpython|, one can create new views using the  ``CreateView``
function or its variants, e.g., ``CreateRenderView``  .

.. code-block:: python

  >>> from paraview.simple import *
  >>> view = CreateRenderView()
  # Alternatively, use CreateView.
  >>> view = CreateView("RenderView")

When a new view is created, it is automatically made active. You can manually
make a view active by using the  ``SetActiveView``   function. Several of the
functions available in |pvpython| will use the active view when no
view is passed as an argument to the function.

.. code-block:: python

  # Create a view
  >>> view1 = CreateRenderView()
  # Create a second view
  >>> view2 = CreateRenderView()

  # Check if view2 is the active view
  >>> view2 == GetActiveView()
  True

  # Make view1 active
  >>> SetActiveView(view1)
  >>> view1 == GetActiveView()
  True

When using  ``Python Shell``   in |paraview|, if you create a new view,
it will automatically be placed in the active tab by splitting the active view.
You can manually control the layout and placement of views from Python too, using
the layout API.

In Python, each tab corresponds to a layout.

.. \fixme{this can be expanded to cover more details about view lay outing.}

.. code-block:: python

  # To get exisiting tabs/layouts
  >>> layouts = GetLayouts()
  >>> print(layouts)
  {('ViewLayout1', '264'): <paraview.servermanager.ViewLayout object at 0x2e5b7d0>}

  # To get layout corresponding to a particular view
  >>> print(GetLayout(view))
  <paraview.servermanager.ViewLayout object at 0x2e5b7d0>

  # If view is not specified, active view is used
  >>> print(GetLayout())
  <paraview.servermanager.ViewLayout object at 0x2e5b7d0>

  # To create a new tab
  >>> new_layout = servermanager.misc.ViewLayout(registrationGroup="layouts")

  # To split the cell containing the view, either horizontally or vertically
  >>> view = GetActiveView()
  >>> layout = GetLayout(view)
  # fraction is optional, if not specified the frame is split evenly.
  >>> locationId = layout.SplitViewVertical(view=view,
                                            fraction=0.5)
  # To get the location of the layout
  >>> locationId = layout.GetViewLocation(view)

  # To change the split factor
  >>> layout.SetSplitFraction(locationId, 0.75)

  # To Maximize a particular view
  >>> layout.MaximizeCell(locationId)

  # To assign a view to a particular cell.
  >>> view2 = CreateRenderView()
  >>> layout.AssignView(locationId, view2)

View properties
===============

Just like parameters on pipeline modules, such as
readers and filters, views provide parameters that can be used for customizing
the visualization such as changing the background color for rendering views and
adding title texts for chart views. These parameters are referred to as  ``View
Properties``   and are accessible from the  ``Properties``   panel in |paraview|.

View properties in ``paraview``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Similar to properties on pipeline modules like sources and readers, view
properties are accessible from the  ``Properties``   panel. These
are grouped under the  ``View``   section. When the active view is changed, the
``Properties``   panel updates to show the view properties for the active view.
Unlike pipeline modules, however, when you change the view properties, they
affect the visualization immediately, without use of the  ``Apply``
button.

.. admonition:: **Did you know?**
  :class: tip

  It may seem odd that  ``View``   and  ``Display``   properties on the
  ``Properties``   panel don't need to be  ``Apply``  -ed to take effect, while
  properties on pipeline modules like sources, readers and filter require you to
  hit the  ``Apply``   button.

  To understand the reasoning behind that, we need to understand why the
  ``Apply``   action is needed in the first place. Generally, executing a data
  processing filter or reader is time consuming on large datasets. If the pipeline
  module keeps on executing as you are changing the parameter, the user experience
  will quickly deteriorate, since the pipeline will keep on executing with
  intermediate (and potentially invalid) property values. To avoid this, we have
  the  ``Apply``   action. This way, you can set up the pipeline properties to your
  liking and then trigger the potentially time consuming execution.

  Since the visualization process in general focuses on *reducing* data to
  generate visual representations, the rendering (broadly speaking) is less time-intensive
  than the actual data processing. Thus, changing properties that affect
  rendering are not as compute-intensive as transforming the data itself. For example,
  changing the color on a surface mesh is not as expensive as generating the mesh
  in the first place. Hence, the need to  ``Apply``   such properties becomes less
  relevant. At the same time, when changing display properties such as opacity,
  you may want to see the result as you change the property to decide on the final
  value. Hence, it is desirable to see the updates immediately.

  Of course, you can always enable  ``Auto Apply``   to have the same immediate
  update behavior for all properties on the  ``Properties``   panel.

View properties in ``pvpython``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In |pvpython|, once you have access to the view, you can directly change view
properties on the view object. There are several ways to get access to the view
object.

.. code-block:: python

  # 1. Save reference when a view is created
  >>> view = CreateView("RenderView")

  # 2. Get reference to the active view.
  >>> view = GetActiveView()

The properties available on the view will change based on the type of the view.
You can use the  ``help``   function to discover available properties.

.. code-block:: python

  >>> view = CreateRenderView()
  >>> help(view)

    Help on RenderView in module paraview.servermanager object:

  class RenderView(Proxy)
   |  View proxy for a 3D interactive render
   |  view.
   |
   |  ----------------------------------------------------------------------
   |  Data descriptors defined here:
   |
   |  CenterAxesVisibility
   |      Toggle the visibility of the axes showing the center of
   |      rotation in the scene.
   |
   |  CenterOfRotation
   |      Center of rotation for the interactor.
   |
   ...

  # Once you have a reference to the view, you can then get/set the properties.

  # Get the current value
  >>> print(view.CenterAxesVisibility)
  1

  # Change the value
  >>> view.CenterAxesVisibility = 0

.. _sec:DisplayingData:DisplayProperties:

Display properties
==================

Display properties refers to available parameters that control how data from a
pipeline module is displayed in a view, e.g., choosing to view the output mesh as a
wireframe, coloring the mesh using a data attribute, and selecting which attributes
to plot in chart view. A set of display properties is associated with a
particular pipeline module and view. Thus, if the data output from a source is
shown in two views, there will be two sets of display properties used to control
the appearance of the data in each of the two views.

Display properties in ``paraview``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Display properties are accessible from the  ``Display``   section on the
``Properties``   panel. When the active source or active view changes, this
section updates to show the display properties for the active source in the
active view, if available. If the active source produces data that cannot be
shown (or has never been shown) in the view, then the  ``Display``   properties
section may be empty.

Similar to view properties, display property changes are immediately applied,
without requiring the use of the  ``Apply``   button.

Display properties in ``pvpython``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To access display properties in |pvpython|, you can use ``SetDisplayProperties``   and  ``GetDisplayProperty``   methods.

.. code-block:: python

  # Using SetDisplayProperties/GetDisplayProperties to access the display
  # properties for the active source in the active view.

  >>> print(GetDisplayProperties("Opacity"))
  1.0

  >>> SetDisplayProperties(Opacity=0.5)

Alternatively, you
can get access to the display properties object using  ``GetDisplayProperties``
and then changing properties directly on the object.

.. code-block:: python

  # Get display properties object for the active source in the active view.
  >>> disp = GetDisplayProperties()

  # Get the available representation types. Available is an option for all properties that have a Domain.
  >>> disp.GetProperty("Representation").Available
  ['Outline', 'Points', 'Wireframe', 'Surface', 'Surface With Edges']

  # You can also save the object returned by Show.
  >>> disp = Show()

  # Now, you can directly access the properties.
  >>> print(disp.Opacity)
  0.5

  >>> disp.Opacity = 0.75

As always, you can use the  ``help``   method to discover available properties on a
display object.

.. code-block:: python

  >>> disp = Show()

  >>> help(disp)
  >>> help(a)
  Help on GeometryRepresentation in module paraview.servermanager object:

  class GeometryRepresentation(SourceProxy)
   |  ParaView`s default representation for showing any type of
   |  dataset in the render view.
   |
   |  Method resolution order:
   |      GeometryRepresentation
   |      SourceProxy
   |      Proxy
   |      __builtin__.object
   |
   |  ----------------------------------------------------------------------
   |  Data descriptors defined here:
   |
   |  ...
   |
   |  CenterStickyAxes
   |      Keep the sticky axes centered in the view window.
   |
   |  ColorArrayName
   |      Set the array name to color by. Set it to empty string
   |      to use solid color.
   |
   |  ColorAttributeType
   |  ...

.. _Render View:

Render View
===========

The   ``Render View``   is the most commonly used view in |ParaView|. It is used to render
geometries and volumes in a 3D scene. This is the view that you typically think
of when referring to 3D visualization. The view relies on techniques to map data
to graphics primitives such as triangles, polygons, and voxels, and it renders
them in a scene.

Most of the scientific datasets discussed in :numref:`sec:VTKDataModel`
are composed of meshes. These meshes can be mapped to graphics primitives using
several of the established visualization techniques. That is, you can compute the
outer surface of these meshes and then render that surface as filled polygons, you can
just render the edges, or you can render the data as a nebulous blob to get a better
understanding of the internal structure in the dataset. Plugins, like
``Digital Rock Physics``, can provide additional ways of rendering data using advanced
techniques that provide more insight into the data.

If the dataset doesn't represent a mesh, e.g., a table
(:numref:`sec:VTKDataModel:Table`), you cannot directly show that data in
this view. However, in such cases, it may be possible to construct a mesh by
mapping columns in the table to positions to construct a point cloud, for
example.

.. figure:: ../images/RenderViewInParaView.png
    :name: fig:RenderViewInParaView
    :width: 80%
    :align: center

    |paraview| using  ``Render View``   to generate 3D visualizations from a dataset.

Understanding the rendering process
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``Render View``   uses data processing techniques to map raw data to graphics
primitives, which can then be rendered in a 3D scene. These mapping techniques
can be classified as follows:

* *Surface rendering* methods provide general rendering by rendering a surface mesh for the dataset. For polygonal datasets (:numref:`sec:VTKDataModel:PolyData`), this is simply the raw data. In cases of other datasets including structured (:numref:`sec:VTKDataModel:UniformRectilinearGrid`, :numref:`sec:VTKDataModel:RectilinearGrid`, :numref:`sec:VTKDataModel:CurvilinearGrid`) and unstructured (:numref:`sec:VTKDataModel:UnstructuredGrid`) grids, this implies extracting a surface mesh for all external faces in the dataset and then rendering that mesh. The surface mesh itself can then be rendered as a filled surface or as a wireframe simply showing the edges, etc.

* *Slice* rendering is available for uniform rectilinear grid datasets (:numref:`sec:VTKDataModel:UniformRectilinearGrid`) where the visualization is generated by simply rendering an orthogonal slice through the dataset. The slice position and alignment can be selected using the display properties.

* *Volume* rendering generates rendering by tracing a ray through the dataset and accumulating intensities based on the color and opacity transfer functions set.

Each of these techniques are referred to as
*representations*. When
available, you can change the representation type from the display properties on the
``Properties``   panel or using the  ``Representation Toolbar``  .

Render View in ``paraview``
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Creating a Render View
----------------------

Unless you changed the default setting, a new  ``Render View``   will be created
when |paraview| starts up or connects to a new server. To create a
``Render View``   in |paraview|, split or close a view, and select the
``Render View``   button. You can also convert a view to a ``Render View`` (or any other
type) by right-clicking on the view's title bar and picking from the  ``Convert To``   sub-menu. It simply closes the chosen view and creates a selected view type
in its place.

You can use the  ``Pipeline Browser``   to control the visibility of datasets
produced by pipeline modules in this view. The eyeball icons reflect the
visibility state. Clicking on the eyeball icon will toggle the visibility state.
If no eyeball icon is shown, it implies that the pipeline module doesn't produce
a data type that can be directly shown in the active view, e.g., if the module
produced a table, then when  ``Render View``   is active, there will not be any
eyeball icon next to that module.

.. _sec:RenderView:Interactions:

Interactions
------------

You can interact with the Render View to move the camera in the scene for
exploring the visualization and setting up optimal viewing angles.
Each of the three mouse buttons, combined with keyboard modifier keys
(|CTRL| or |CMD| , and |SHIFT|), move the camera differently.

There are several types of camera controls available in |ParaView|:

* *Pan*: Translates the camera in the view plane.
* *Zoom*: Moves the camera closer or farther from the center of the view.
* *Roll*: Rotates the camera around the view direction.
* *Rotate*: Orbits the camera around the center of rotation.
* *Zoom To Mouse*: Zooms in or out of the projected point under the mouse position.
* *Multi Rotate*: Allows azimuth and elevation rotations by dragging from the middle of
  the view, and rolling by dragging from the edges.
* *Rotate Skybox*: Rotates the environment skybox. Useful when using Environment Lighting
  and PBR shader.

By default, |ParaView| maps mouse buttons and keyboard modifiers combinations to the
following 3D camera controls:

* **Left Mouse Button**: Rotate
* **Middle Mouse Button**: Pan
* **Right Mouse Button**: Zoom
* **With** |SHIFT| (shift): Roll, Rotate, or Pan
* **With** |CTRL| **or** |CMD|: Skybox rotation or Zoom to Mouse
* **Left Mouse Button with** :kbd:`x`, :kbd:`y`, **or** :kbd:`z` **Keys**: Rotate the
  camera around the respective axis.
* **Middle Mouse Button with** :kbd:`x`, :kbd:`y`, **or** :kbd:`z` **Keys**: translate the
  camera along the respective axis.

Usually in |ParaView|, you are interacting with a 3D scene. However, if you're working
with 2D datasets such as slices or images, |ParaView| automatically adjusts the
interaction mode to 2D, which have slightly different camera control shortcuts by default.
You can manually switch between interaction modes using the ``2D`` and ``3D`` buttons in
the view toolbar. This default interaction mode can be changed in settings dialog by
changing the ``Default Interaction Mode`` advanced setting under the ``Render View`` tab.

The mouse and keys camera controls for both 2D and 3D interaction modes can be customized
in the settings dialog, which is accessible from :guilabel:`Edit > Settings` (or
:guilabel:`ParaView > Preferences` on macOS), under the ``Camera`` tab. For more details,
see :numref:`sec:CameraSettings`.

View properties
---------------

Several of the view properties in  ``Render View``   control the annotations shown
in the view (:numref:`fig:RenderViewPropertiesPanel`).

.. figure:: ../images/RenderViewPropertiesPanel.png
    :name: fig:RenderViewPropertiesPanel
    :width: 40%
    :align: center

    The  ``Properties``   panel showing view properties for  ``Render View``  .

``Axes Grid``   refers to an annotation axis rendered around all
datasets in the view (:numref:`fig:RenderViewAxesGrid`). You use
the checkbox next to the  ``Edit Axis Grid``   button to show or hide
this annotation. To control the annotation formatting, labels, etc.,
click on the  ``Edit Axes Grid...``   button. The  ``Axes Grid``   is
described in Chapter :numref:`chapter:AxesGrid`.

.. figure:: ../images/RenderViewAxesGrid.png
    :name: fig:RenderViewAxesGrid
    :width: 50%
    :align: center

    ``Axes Grid``   is used to annotate data bounds in  ``Render View``  .

The *Center axes* refers to axes rendered in the scene positioned as the
center of rotation, i.e., the location is space around which the camera revolves
during  ``Rotate``   camera interaction.
``Center Axes Visibility``   controls the visibility of the center axes.

The *Orientation axes* is the widget shown at the lower-left corner by
default, which is used to get a sense for the orientation of the scene. The properties
grouped under the  ``Orientation Axes``   group allow you to toggle the visibility and
the interactivity of this widget. When interactivity is enabled, you can click and
drag this widget to the location of your choosing in the scene.

You can also change the  ``Background``   used for this view. You can either set it as a
``Single``   color or as a  ``Gradient``   changing between two colors, or you can select an
``Image``   (or texture) to use as the background.

There are two advanced properties you may wish to set: hidden line removal
and camera parallel projection. The  ``Hidden Line Removal``   option
can be enabled to hide lines that would be occluded by a solid object
when drawing objects in a  ``Wireframe``   representation.
If you want to render your data using parallel projection instead of
the default perspective projection you can check the
``Camera Parallel Projection``   checkbox.

Display properties
------------------

.. _sec:RenderView:DisplayProperties:

.. figure:: ../images/RenderViewDisplayPropertiesRepresentation.png
    :width: 40%
    :align: center

One of the first (and probably the most often used) display properties is
``Representation``  .  ``Representation``   allows you to pick one of the
*mapping* modes. The options available depend on the data type, as well as
the plugins loaded. While all display properties are accessible from the
advanced view for the  ``Properties``   panel, certain properties may be
shown/hidden from the default view based on the chosen representation type.

.. figure:: ../images/WaveletRepresentations.png
    :width: 70%
    :name: fig:WaveletRepresentations
    :align: center

    Different renderings generated by rendering data produced by the  ``Wavelet``  source as outline, points, slice, surface, surface with edges, and volume.

The  ``Outline``   representation can be used to render an outline for the
dataset. This is arguably the fastest way of rendering the dataset since only
the bounding box is rendered. Scalar coloring options, i.e., selecting an array
with which to color, has no effect on this representation type. You can still,
however, change the  ``Solid Color``   to use as well as the  ``Opacity``  . To change
the color, select  ``Solid Color``   in the combo-box under  ``Coloring``  , and then
click  ``Edit``   to pick the color to use. To change the opacity, simply change
the  ``Opacity``   slider. 0 implies total transparency and, hence, invisiblity, while 1
implies totally opacity.

.. admonition:: **Did you know?**
  :class: tip

  Rendering translucent data generally adds computational
  costs to the rendering process. Thus, when rendering large datasets, you may
  want to leave changing opacities to anything less than 1 to the very end,
  after having set up the visualization. In doing so, you avoid translucent geometries
  during exploration, but use them for generating images or screenshots for
  presentations and publications.

``Points``  ,  ``Surface``  ,  ``Surface With Edges``  , and  ``Wireframe``   rely on
extracting the surface mesh from the dataset and then rendering that either as a
collection of points, as solid surface, as solid surface with cell boundaries
highlighted, or as a wireframe of cell boundaries only.  ``Feature Edges``
is a subset of  ``Wireframe``   consisting of prominent edges on the surface such
as edges between cells that form a sharp angle or edges with only one adjacent cell.
For these representations, you can either set a single solid color to use,
as with  ``Outline``  , or select a data array to use for scalar coloring (also
known as pseudocoloring).

Two other representations are available for most datasets.  ``3D Glyphs``   draws
a copy of a 3D geometry (e.g., arrow, cone, or sphere, etc.), or glyph, at a subset
of points in the dataset. These glyphs can be set to a single color or
pseudocolored by a data array. The  ``Point Gaussian``   representation is similar,
but instead of drawing 3D geometry at every point, it draws a 2D image sprite
that may have transparency. The image drawn can be one of several predefined
image sprites such as  ``Gaussian Blur``  ,  ``Sphere``  ,  ``Black-edged circle``  ,
``Plain cirlce``  ,  ``Triangle``  , or  ``Square outline``  , or a custom sprite
can be defined with custom GLSL shader code.

Lastly, the ``SurfaceLIC`` representation is available for surface datasets with
vector point data arrays. LIC stands for line integral convolution, which is a visualization
technique that shows the direction of flow as a noise pattern smeared in the
direction of flow.

.. figure:: ../images/SurfaceLICRepresentation.png
    :width: 80%
    :align: center

    An example of the ``SurfaceLIC`` representation showing the direction of a
    vector data array and colored by a different scalar array showing (Density).

.. admonition:: **Did you know?**
  :class: tip

  For visualizations that feature 3D glyphs, it is typically much faster to
  use the  ``3D Glyph``   representation rather than the  ``Glyph``   filter. This is because
  the glyph representation draws the same geometry at many different locations (a graphics
  technique called geometry instancing) while the  ``Glyph``   filter makes many copies of the
  same source geometry and renders the resulting mesh in its entirety. Generating all the glyphs and
  rendering them takes potentially a lot of memory and is typically slower to render, so
  you should use the  ``3D Glyph``   representation when possible.

Next, we will cover each of the property groups available under  ``Display``
properties. Several of these are marked as advanced. Accordingly, you may need to
either toggle the panel to show advanced properties using the
|pqAdvanced| button or search for it by name using the search
box.

.. figure:: ../images/RenderViewDisplayPropertiesColoringGroup.png
    :width: 80%
    :align: center

Display properties under  ``Coloring``     allow you to set
how the dataset is
colored. To select a single solid color to use to fill the surface or color the
wireframe or points, select  ``Solid Color``   in the combo-box, and then
click  ``Edit``  . That will pop up the standard color chooser dialog from which you
can pick a color to use.

If instead you want to pseudocolor using an attribute array
available on the dataset, select that array name from the combo-box. For
multi-component arrays, you can pick a particular component or  ``Magnitude``   to
use for scalar coloring. |ParaView| will automatically set up a color transfer
function it will use to map the data array to colors. The default range for the
transfer function is set up based on the  ``Transfer Function Reset Mode``   general
setting in the  ``Settings``   dialog when the transfer function is first created.
If another dataset is later colored by a data array with the same name, the range
of the transfer function will be updated according to the  ``Automatic Rescale Range Mode``
property in the  ``Color Map Editor``  . To reset the transfer function range to the
range of the data array in the selected dataset, you can use the  ``Rescale``
button. Remember that, despite the fact that you can set the scalar array with
which to color when rendering as  ``Outline``  , the outline itself continues to use
the specified solid color.

``Scalar Coloring``   properties are only relevant when you have selected a data
array with which to pseudocolor. The  ``Map Scalars``   checkbox affects whether a color
transfer function should be used (:numref:`fig:UnderstandingMapScalars`).
If unchecked, and the data array can directly
be interpreted as colors, then those colors are used directly. If not, the color
transfer function will be used. A data array can be interpreted as colors if, and
only if, it is an unsigned char, float, or double array with two, three, or four
components. If the data array is unsigned char, the color values are defined between
0 and 255 while if the data array is float or double, the color values are expected
to be between 0 and 1.  ``Interpolate Scalars Before Mapping``   controls how color
interpolation happens across rendered polygons. If
on, scalars will be interpolated within polygons, and color mapping will occur
on a per-pixel basis. If off, color mapping occurs at polygon points, and colors
are interpolated, which is generally less accurate. Refer to the Kitware blog
:cite:`ColorInterpolationBlogPost` for a detailed explanation of this option.
``Use Nan Color For Missing Arrays`` is a property that, if enabled, will use the special
color designated for NaN values in a dataset to also be used as the color for parts of
a composite dataset that are missing the scalars array used for color mapping.

.. figure:: ../images/UnderstandingMapScalars.png
    :name: fig:UnderstandingMapScalars
    :width: 80%
    :align: center

    The  ``Map Scalars``   property can be used to avoid using a transfer function and directly interpreting the array values as colors, if possible.

.. figure:: ../images/PolarAxesCheckbox.png
    :width: 50%
    :align: center

The  ``Polar Axes``   checkbox toggles polar axes shown around the data.
Many parameters can be accessed via an  ``Edit button``   alongside it.
The parameters include angles, tick range, labels, logarithmic mode,
ellipse ratio and more.

.. figure:: ../images/PolarAxes.png
    :name: fig:PolarAxes
    :width: 70%
    :align: center

    A  ``Polar Axes``   usage example.

.. figure:: ../images/RenderViewDisplayPropertiesStylingGroup.png
    :width: 50%
    :align: center

``Styling``   properties include  ``Opacity``   (useful when rendering translucent
geometries),  ``Point Size``   (used to control size of points rendered with using
``Points``   representation), and  ``Line Width``   (used to control the thickness
of lines when rendering as  ``Wireframe``   or that of the edges when rendering as
``Surface With Edges``  .

.. figure:: ../images/RenderViewDisplayPropertiesLightingGroup.png
    :width: 50%
    :align: center

``Lighting``   properties affect the shading for rendered surfaces.
``Interpolation``   allows you to pick between  ``Flat``   and  ``Gouraud``
shading.  ``Specular``  , together with  ``Specular Color``   and  ``Specular
Power``  , affects the shininess of the surface. Set this to a non-zero value to
render shiny, metallic surfaces.

.. admonition:: **Common Errors**
  :class: error

  ``Specular``   highlights can lead to misinterpretation of scalar values when
  using scalar coloring, since the color shown on the shiny part of the surface
  will not correspond to any color on the color transfer function. Hence, it is
  generally advisable to use specular highlights on surfaces colored with a single
  solid color and not on those using scalar coloring (or
  pseudocoloring).

  .. figure:: ../images/ScalarColoringAndSpecularHighlights.png
      :width: 70%
      :align: center

.. figure:: ../images/RenderViewDisplayPropertiesEdgeStylingGroup.png
    :width: 50%
    :align: center

``Edge Styling``   allows you to set the  ``Edge Color``   with which to color the edges
when using  ``Surface With Edges``   representation.

.. figure:: ../images/RenderViewDisplayPropertiesBackfaceStylingGroup.png
    :width: 50%
    :align: center

``Backface Styling``   provides advanced controls to fine-tune the rendering by
controlling front and back faces. A front face is any mesh face facing the
camera, while a back face is the one facing away from the camera. By choosing to
``Cull Frontface``   or  ``Cull Backface``  , or by selecting a specific representation
type to use for the backface, you can customize your visualizations.

.. figure:: ../images/RenderViewDisplayPropertiesTransformingGroup.png
    :width: 80%
    :align: center

``Transforming``   properties can be used to transform the rendered data in the
scene without affecting the raw data itself. Thus, if you apply filters on the
data source, it will indeed be working with the untransformed data. To transform
the data itself, you should use the  ``Transform``   filter.

The ``Coordinate Shift Scale Method`` is used to choose how to normalize point coordinates
to improve rendering quality. Mesh points are sent to the GPU as single-precision float data
which can result in resolution issues due to limited precision. VTK includes a variety of
methods to normalize the point coordinates to a better range for single-precision floats
prior to sending them to the GPU. ``Auto Shift Scale`` is a good setting that should work
for most datasets - it recomputes a shift and scale factor according to a heuristic involving
dataset size and position relative to the origin. ``Always Auto Shift Scale`` recomputes the
shift and scale every time. ``Auto Shift Only`` only shifts the data - this is useful when
data is far away from the origin. ``Near Focal Plane Shift Scale`` and ``Focal Point Shift Scale``
works based on the current camera near clipping point and viewpoint, respectively. This makes
it the most robust setting, especially for very large datasets, but it will renormalize the
points occasionally as the camera's settings change. Renormalizing points requires reuploading
the data to the GPU, so there may be a performance cost with these last methods.

.. figure:: ../images/RenderViewDisplayPropertiesMiscellaneousGroup.png
    :width: 50%
    :align: center

Several properties are available under the  ``Miscellaneous``   group. Uncheck the  ``Pickable``
option if you want the dataset to be ignored when making selections. If the
dataset has a texture coordinates array, you can apply a texture to the dataset
surface using the  ``Texture``   combo-box. Choose  ``Load``   to load a texture or
apply a previously loaded texture listed in the combo-box. If your dataset
doesn't have texture coordinates, you can create them by applying one of
``Texture Map to Cylinder``  ,  ``Texture Map to Sphere``  , or  ``Texture Map To
Plane``   filters, or using the filters  ``Calculator``   or  ``Programmable Filter``  .

.. \fixme{Add section on Use Shader Replacements property}

The  ``Triangulate``   option is useful for rendering objects with
non-convex polygons. It comes with some additional processing cost for
converting polygons to triangles, so it should be used only when necessary.

.. figure:: ../images/NonLinearSubdivision.png
    :name: fig:NonLinearSubdivision
    :width: 50%
    :align: center

    A dataset made of quadratic tetra hedra displayed with 1, 2, and 3 levels of nonlinear subdivision.

The property ``Use Shader Replacements`` enables you to customize the shader code
VTK uses for rendering by specifying shader replacements with a JSON string.
The JSON string can be a single node or an array of nodes with the following properties:

* "type": specifies the type of shader the replacement is about.
  It can be either "vertex", "fragment" or "geometry".

* "original": specifies the original string to be replaced in the shader code.
  This string is generally a pattern defined by the mapper
  vtkOpenGLPolyDataMapper at specific locations of the shader
  GLSL source code.

* "replacement": specifies the replacement string in GLSL source code.
  Note that the Json parser supports multiple lines entries.

Here's an example of a simple shader replacement (draw all the fragments in full red
color without any shading consideration):

.. code-block:: json

  {
    "type": "fragment",
    "original": "//VTK::Light::Impl",
    "replacement": "gl_FragData[0]=vec4(1.0,0.0,0.0,1.0);"
  }

The  ``Nonlinear Subdivision Level`` property is used when rendering datasets with higher-
order elements. Use this to set the subdivision level for triangulating higher
order elements. The higher the value, the smoother the edges. This comes at the
cost of more triangles and, hence, potentially, increased rendering time.

The  ``Block Colors Distinct Values`` property sets the number
of unique colors to use when coloring multiblock datasets by block ID. Finally,
``Use Data Partitions``   controls whether data is redistributed when it is
rendered translucently. When off (default value), data is repartitioned by the
compositing algorithm prior to rendering. This is typically an expensive
operation that slows down rendering. When this option is on, the existing data
partitions are used, and the cost of data restribution is avoided. However, if
the partitions are not sortable in back-to-front order, rendering artifacts may
occur.

.. figure:: ../images/RenderViewDisplayPropertiesVolumeRenderingGroup.png
    :width: 50%
    :align: center

``Volume Rendering``   options are available if the data can be volume rendered.
You can pick a specific type of  ``Volume Rendering Mode``  , although the
default ( ``Smart``  ) should work in most cases, since it attempts to pick a
volume rendering mode suitable for your data and graphics setup. To enable
gradient-based shading, check  ``Shade``  , if available.

.. figure:: ../images/RenderViewDisplayPropertiesSlicingGroup.png
    :width: 50%
    :align: center

``Slicing``   properties are available when the  ``Slice``   representation type is
present. These allow you to pick the orthogonal slice plane orientation and
slice offset using  ``Slice Direction``   and the  ``Slice``   slider.

Render View in ``pvpython``
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Creating a Render View
----------------------

You use  ``CreateRenderView``   or  ``CreateView``   functions to create a new
instance of a render view.

.. code-block:: python

  >>> from paraview.simple import *
  >>> view = CreateRenderView()
  # Alternatively, use CreateView.
  >>> view = CreateView("RenderView")

\noindent
You use  ``Show``   and  ``Hide``   to show or hide data produced by a pipeline
module in the view.

.. code-block:: python

  >>> source = Sphere()
  >>> view = CreateRenderView()

  # Show active source in active view.
  >>> Show()

  # Or specify source and view explicitly.
  >>> Show(source, view)

  # Hide source in active view.
  >>> Hide(source)

Interactions
------------

Since |pvpython| is designed for scripting and batch processing,
it has limited support for direct interaction with the view.
To interact with a scene, invoke the  ``Interact``   function in Python.

.. code-block:: python

  Interact()

More often, you will programmatically change the camera as follows:

.. code-block:: python

  # Get camera from the active view, if possible.
  >>> camera = GetActiveCamera()

  # or, get the camera from a specific render view.
  >>> camera = view.GetActiveCamera()

  # Now, you can use methods on camera to move it around the scene.

  # Divide the camera's distance from the focal point by the given dolly value.
  # Use a value greater than one to dolly-in toward the focal point, and use a
  # value less than one to dolly-out away from the focal point.
  >>> camera.Dolly(10)

  # Set the roll angle of the camera about the direction of projection.
  >>> camera.Roll(30)

  # Rotate the camera about the view up vector centered at the focal point. Note
  # that the view up vector is whatever was set via SetViewUp, and is not
  # necessarily perpendicular to the direction of projection. The result is a
  # horizontal rotation of the camera.
  >>> camera.Azimuth(30)

  # Rotate the focal point about the view up vector, using the camera's position
  # as the center of rotation. Note that the view up vector is whatever was set
  # via SetViewUp, and is not necessarily perpendicular to the direction of
  # projection. The result is a horizontal rotation of the scene.
  >>> camera.Yaw(10)

  # Rotate the camera about the cross product of the negative of the direction
  # of projection and the view up vector, using the focal point as the center
  # of rotation. The result is a vertical rotation of the scene.
  >>> camera.Elevation(10)

  # Rotate the focal point about the cross product of the view up vector and the
  # direction of projection, using the camera's position as the center of
  # rotation. The result is a vertical rotation of the camera.
  >>> camera.Pitch(10)

Alternatively, you can explicitly set the camera position, focal point, view up,
etc,. to explicitly place the camera in the scene.

.. code-block:: python

  >>> camera.SetFocalPoint(0, 0, 0)
  >>> camera.SetPosition(0, 0, -10)
  >>> camera.SetViewUp(0, 1, 0)
  >>> camera.SetViewAngle(30)
  >>> camera.SetParallelProjection(False)

  # If ParallelProjection is set to True, then you'll need
  # to specify parallel scalar as well i.e. the height of the viewport in
  # world-coordinate distances. The default is 1. Note that the `scale'
  # parameter works as an `inverse scale' where larger numbers produce smaller
  # images. This method has no effect in perspective projection mode.
  >>> camera.SetParallelScale(1)

View properties
---------------

In |pvpython|, view properties are directly accessible on the view
object returned by  ``CreateRenderView``   or  ``GetActiveView``  .

Once you get access to the view properties objects, you can then set properties
on it similar to properties on pipeline modules such as sources, filters, and
readers.

.. code-block:: python

  >>> view = GetActiveView()

  # Set center axis visibility
  >>> view.CenterAxesVisibility = 0

  # Or you can use this variant to set the property on the active view.
  >>> SetViewProperties(CenterAxesVisibility=0)

  # Another way of doing the same
  >>> SetViewProperties(view, CenterAxesVisibility=0)

  # Similarly, you can change orientation axes related properties
  >>> view.OrientationAxesVisibility = 0
  >>> view.OrientationAxesLabelColor = (1, 1, 1)

Display properties
------------------

Similar to view properties, display properties are accessible from the display
properties object or using the  ``SetDisplayProperties``   function.

.. code-block:: python

  >>> displayProperties = GetDisplayProperties(source, view)
  # Both source and view are optional. If not specified, the active source
  # and active view will be used.

  # Now one can change properties on this object
  >>> displayProperties.Representation = "Outline"

  # Or use the SetDisplayProperties API.
  >>> SetDisplayProperties(source, view, Representation=Outline)

  # Here too, source and view are optional and when not specified,
  # active source and active view will be used.

You can always use the  ``help``   function to get information about available
properties on a display properties object.

Line Chart View
===============

.. figure:: ../images/LineChartViewInParaView.png
    :name: fig:LineChartViewInParaView
    :width: 80%
    :align: center

    |paraview| using  ``Line Chart View``   to plot data values probed along a line through the dataset using  ``Plot Over Line``   filter.

``Line Chart View``   can be used to plot data as a line plot representing
changes in dependent variables against an independent variable. Using display
properties, you can also show scatter plots in this view. This view and other
charting views in |ParaView| follow a similar design, where you pick attribute
arrays to plot using display properties, and they are plotted in the view. How
those values get plotted depends on the type of the view:  ``Line Chart View``
draws a line connecting sample points,  ``Bar Chart View``   renders bars at each
sample point, etc.

One of the most common ways of showing a line plot is to apply the  ``Plot Over
Line``   filter to any dataset. This will probe the dataset along the probe line
specified. You then plot the sampled values in the  ``Line Chart View``  .
Alternatively, if you have a tabular dataset (i.e.  ``vtkTable``  ), then you can
directly show the data in this view.

.. admonition:: **Did you know?**
  :class: tip

  You can plot any arbitrary dataset, even those not producing  ``vtkTable``   outputs,
  by using the  ``Plot Data``   filter. Remember, however, that for
  extremely large datasets, while  ``Render View``   may use parallel rendering
  strategies to improve performance and reduce memory requirements, chart views
  rarely, if ever, support such parallel strategies.

Understanding plotting
^^^^^^^^^^^^^^^^^^^^^^

``Line Chart View``   plots data arrays. For any dataset being shown in the view,
you first select which data array is to be treated as the independent variable
and plotted along the x-axis. Then, you select which arrays to plot along the
Y-axis. You can select multiple of these and setup properties for each of the
series so they are rendered with different colors and line styles. Since data
arrays in VTK datasets are associated with cells or points, and the two are not
directly comparable to one another, you can only pick arrays associated with
one type of attribute at any time.

Line Chart View in ``paraview``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Creating a Line Chart View
--------------------------

Similar to creating  ``Render View``  , you can split the viewport or convert
an existing view to  ``Line Chart View``  .  ``Line Chart View``   will also be
automatically created if you apply a filter that needs this view, e.g., the
``Plot Over Line``   filter.

.. admonition:: **Did you know?**
  :class: tip

  If you generate lengthy data for the  ``Line Chart View``  , the default variables
  that are selected may be slow to adjust. You can change |paraview|'s default
  behavior to initially load no variables at all by selecting the
  ``Load No Chart Variables``   checkbox under
  ``Settings/General/Properties Panel Options``  .

  .. figure:: ../images/ChartNoVarSetting.png
     :width: 60%
     :align: center

Interactions
------------

Interactions with the chart view result in changing the plotted axes ranges.
You can left-click and drag to pan, i.e., change the origin. To change the range
on either of the axes, you can right-click and drag vertically and/or horizontally
to change the scale on the vertical axes and/or horizontal axes, respectively.

You can also explicitly specify the axes range using view properties.

View properties
---------------

The view properties for  ``Line Chart View``   are grouped as properties that
affect the view and those that affect each of the potential four axes.

.. figure:: ../images/LineChartViewPropertiesTitleGroup.png
    :width: 50%
    :align: center

To set a title, use  ``Chart Title``  . Title text properties such as font, size,
style, and alignment with respect to the chart can be set under  ``Chart Title
Properties``  . To toggle the visibility of the legend, use  ``Show Legend``  . While
you cannot interactively place the legend in this view, you can use  ``Legend
Location``   to place it at one of the corners.

.. figure:: ../images/LineChartViewPropertiesLeftAxisGroup.png
    :width: 60%
    :align: center

There are four axes possible in this view: left, bottom, top, and right. The top
and right axes are shown only when some series is set to use those. (We will
cover this in the *Display properties* subsection.) For each of the axes,
you can set a title (e.g.,  ``Left Axis Title``  ,  ``Bottom Axis Title``  , etc.)
and adjust the title font properties. You can turn on a grid with a customizable
color by checking the  ``Show Left Axis Grid``  , for example.

Next, you can customize the axes ranges. You can always simply interact with the
mouse to set the axes ranges. To precisely set the range, check the
``Axis Use Custom Range``   for the appropriate axis, e.g.,  ``Bottom Axis Use
Custom Range``   for fixing the bottom axis range, and then specify the data values to
use for the min and the max.

The labels on the axes are, by default, automatically determined to avoid visual
clutter. By default, the axis labels are arranged on a linear scale, but by
enabling the  ``Axis Log Scale``   option you can use log scaling instead. In
addition, you can override the default labelling strategy for any of the axes
separately and, instead, specify the locations to label explicitly. This can be
done by checking  ``Axis Use Custom Labels``   for a particular axis, e.g.,
``Bottom Axis Use Custom Labels``  . When checked, a list widget will be shown
where you can manually add values at which labels will be placed.

For generating log plots, simply check the corresponding  ``Axis Use Log Scale``  ,
e.g.,  ``Left Axis Use Log Scale``   to use log scale for Y-axis
(:numref:`fig:LineChartViewUsingLogScale`). Note that log
scale should only be used for an axis with a non-zero positive range, since the log of a
number less than or equal to 0 is undefined.

.. figure:: ../images/LineChartViewUsingLogScale.png
    :name: fig:LineChartViewUsingLogScale
    :width: 80%
    :align: center

    Differences between line charts when using log scale for the Y-axis.

Display properties
------------------

.. figure:: ../images/LineChartViewDisplayPropertiesAttributeType.png
    :width: 50%
    :align: center

Display properties allow you to setup which series or data arrays are plotted in
this view. You start by picking the  ``Attribute Type``  . Select the attribute
type that has the arrays of interest. For example, if you are plotting arrays
associated with points, then you should pick  ``Point Data``  .) Arrays with
different associations cannot be plotted together. You may need to apply filters
such as  ``Cell Data to Point Data``   or  ``Point Data to Cell Data``   to convert
arrays between different associations to do that.

.. figure:: ../images/LineChartViewDisplayPropertiesXAxisParametersGroup.png
    :width: 50%
    :align: center

Properties under  ``X Axis Parameters``   allow you to select the independent
variable plotted on the X axis by choosing the  ``X Array Name``  . If none of the
arrays are appropriate, you can choose to use the element index in the array as
the X axis by checking  ``Use Index for XAxis``  .

.. figure:: ../images/LineChartViewDisplayPropertiesSeriesParametersGroup.png
    :width: 50%
    :align: center

``Series Parameters`` control series or data arrays plotted on the Y-axis. All
available data arrays are lists in the table widget that allows you to
check/uncheck a series to plot in the first column. The second column in the
table shows the associated color used to plot that series. You can double-click
the color swatch to change the color to use. By default, |ParaView| will try to
pick a palette of discrete colors. The third column lets you set the
opacity of the series plot elements. The fourth column (``Variable``) shows the
name of the variable to plot. The fifth column (``Legend Name``) shows the label to use for
that series in the legend. By default, it is set to be the same as the array
name. You can double-click to change the name to your choice, e.g., to add units.

Other series parameters include ``Line Thickness``, ``Line Style``, ``Marker
Style``, and ``Marker Size``. To change any of these, highlight a row in The
``Series Parameters`` widget, and then change the associated parameter to affect
the highlighted series. You can change properties for multiple series and can select
multiple of them by using the |CTRL| (or |CMD|) and |SHIFT| keys.

Using  ``Chart Axes``  , you can change which axes on which a series is shown. The
default is  ``Bottom-Left``  , but you can change it to be  ``Bottom-Right``  ,
``Top-Left``  , or  ``Top-Right``   to accommodate series with widely different
ranges in the same plot.

Line Chart View in ``pvpython``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The principles involved in accessing  ``Line Chart View``   from
|pvpython| are similar to those with  ``Render View``  . You work with
the view properties and display properties objects to change views and display
properties, respectively. The thing that changes is the set of available
properties.

The following script demonstrates the typical usage:

.. code-block:: python

  >>> from paraview.simple import *

  # Create a data source to probe into.
  >>> Wavelet()
  <paraview.servermanager.Wavelet object at 0x1156fd810>

  # We update the source so that when we create PlotOverLine filter
  # it has input data available to determine good defaults. Otherwise,
  # we will have to manually set up the defaults.
  >>> UpdatePipeline()

  # Now, create the PlotOverLine filter. It will be initialized using
  # defaults based on the input data.
  >>> PlotOverLine()
  <paraview.servermanager.PlotOverLine object at 0x1156fd490>

  # Show the result.
  >>> Show()
  <paraview.servermanager.XYChartRepresentation object at 0x1160a6a10>

  # This will automatically create a new Line Chart View if the
  # the active view is no a Line Chart View since PlotOverLine
  # filter indicates it as the preferred view. You can also explicitly
  # create it by using CreateView() function.

  # Display the result.
  >>> Render()

  # Access display properties object.
  >>> dp = GetDisplayProperties()
  >>> print(dp.SeriesVisibility)
  ['arc_length', '0', 'RTData', '1']

  # This is  list with key-value pairs where the first item is the name
  # of the series, then its visibility and so on.
  # To toggle visibility, change this list e.g.
  >>> dp.SeriesVisibility = ['arc_length', '1', 'RTData', '1']

  # Same is true for other series parameters including series color,
  # line thickness etc.

  # For series color, the value consists of 3 values: red, green, and blue
  # color components.
  >>> print(dp.SeriesColor)
  ['arc_length', '0', '0', '0', 'RTData', '0.89', '0.1', '0.11']

  # For series labels, value is the label to use.
  >>> print(dp.SeriesLabel)
  ['arc_length', 'arc_length', 'RTData', 'RTData']

  # e.g. to change RTData's legend label, we can do something as follows:
  >>> dp.SeriesLabel[3] = 'RTData -- new label'

  # Access view properties object.
  >>> view = GetActiveView()
  # or
  >>> view = GetViewProperties()

  # To change titles
  >>> view.ChartTitle = "My Title"
  >>> view.BottomAxisTitle = "X Axis"
  >>> view.LeftAxisTitle = "Y Axis"

Bar Chart View
==============

.. figure:: ../images/BarChartViewInParaView.png
    :name: fig:BarChartViewInParaView
    :width: 70%
    :align: center

    |paraview| using  ``Bar Chart View``   to plot the histogram for a dataset using the  ``Histogram``   filter.

``Bar Chart View``   is very similar to  ``Line Chart View``   when it comes to
creating the view, view properties, and display properties. One difference is
that, instead of rendering lines for each series, this view renders bars. In addition,
under the display properties, the  ``Series Parameters``   like  ``Line Style``   and
``Line Thickness``   are not available, since they are not applicable to bars.

Box Chart View
==============

.. figure:: ../images/BoxChartViewInParaView.png
    :name: fig:BoxChartViewInParaView
    :width: 70%
    :align: center

    |paraview| using  ``Box Chart View``   to plot the box chart for a dataset using the  ``Compute Quartiles``   filter.

Box plot is a standard method for graphically depicting groups of statistical
data based on their quartiles. A box plot is represented by a box with the
following properties: the bottom of the rectangle corresponds to the first
quartile, a horizontal line inside the rectangle indicates the median and the
top of the rectangle corresponds to the third quartile. The maximum and minimum
values are depicted using vertical lines that extend from the top and the bottom
of the rectangle.

In |ParaView|, the  ``Box Chart View``   can be used to display such box plots through
the  ``Compute Quartiles``   filter which computes the statistical data needed by
the view to draw the box plots.

Plot Matrix View
================

.. figure:: ../images/PlotMatrixViewInParaView.png
    :name: fig:PlotMatrixViewInParaView
    :width: 80%
    :align: center

    |paraview| using  ``Plot Matrix View``   to generate a scatter plot matrix to understand correlations between pairs of variables.

``Plot Matrix View``   is a chart view that renders a scatter plot matrix. It
allows you to spot patterns in the small scatter plots, change focus to those
plots of interest, and perform basic selection. The principle is that, for all
selected arrays or series to be plotted, the view generates a scatter plot for
each pair. You can activate a particular scatter plot, in which case the active
plot is re-drawn at a bigger scale to make it easier to inspect.
Additionally, the view shows a histogram for each plotted variable or series.

The view properties allow you to set colors to use for active plot, histograms,
etc., while the display properties allow you to pick which series are plotted.

Interactions
^^^^^^^^^^^^

You can click on any of the plots (except the histograms) in the matrix to make
it active. Once actived, the active plot will show that plot. You can then
interact with the active plot exactly like  ``Line Chart View``   or  ``Bar Chart
View``   for panning and zoom.

View properties
^^^^^^^^^^^^^^^

View properties on this view allow you to pick styling parameters for the
rendering ranging from title ( ``Chart Title``  ) to axis colors ( ``Active Plot
Axis Color``  ,  ``Active Plot Grid Color``  ). You can also control the visibility
of the histrogram plots, the active plot, the axes labels, the grids, and so on.

Display properties
^^^^^^^^^^^^^^^^^^

Similar to  ``Line Chart View``  , you select the  ``Attribute Type``   and then the
arrays to plot. Since, in a scatter plot matrix, the order in which the selected
series are rendered can make it easier to understand correlations, you can
change the order by clicking and dragging the rows in the  ``Series Parameters``
table.

.. \fixme{add images}

Parallel Coordinates View
=========================

.. figure:: ../images/ParallelCoordinatesViewInParaView.png
    :name: fig:ParallelCoordinatesViewInParaView
    :width: 80%
    :align: center

    |paraview| using  ``Parallel Coordinates View``   to plot correlations between columns in a table.

Like  ``Plot Matrix View``  ,  ``Parallel Coordinates View``   is also used to
visualize correlations between data arrays.

One of the main features of this view is the ability to select specific data in order to analyse
the factors influencing the data. e.g., with a table of three variables, one being the "output" variable
the other two being the potential factor influencing the first, selecting only the output will enable you
to see if none, one, or both of the factors are actually influencing the output.

.. figure:: ../images/ParallelCoordinatesViewInParaViewSelection.png
    :name: fig:ParallelCoordinatesViewInParaViewSelection
    :width: 70%
    :align: center

    High "S" data point are influenced more by low "Ks" than high "Q"

Spreadsheet View
================

.. figure:: ../images/SpreadSheetViewInParaView.png
    :name: fig:SpreadSheetViewInParaView
    :width: 80%
    :align: center

    |paraview| using  ``SpreadSheet View``   to plot raw data values for the *can.ex2* dataset.

``SpreadSheet View``   is used to inspect raw data values in a tabular form.
Unlike most other views, this view is primarily intended to be used in the
|paraview| user interface and, hence, is not available in
|pvpython|.

To use this view, simply create this view and show the dataset produced by any
pipeline module in it by using the  ``Pipeline Browser``  .  ``SpreadSheet View``
can only show one dataset at a time. Therefore, showing a new dataset will
automatically hide the previously shown dataset.

The view's toolbar provides quick access to several of this view's capabilities.
Use the  ``Showing``   widget on the view toolbar to view as well as to change the
dataset being shown. The  ``Attribute``   field allows you to pick which types of
elements to show, e.g.,  ``Cell Data``  ,  ``Point Data``  ,  ``Field Data``  , etc.
``Precision``   can be utilized to change the precision used when displaying floating
point numbers.
The |pqRectilinearGrid| button enables you to select columns to
show. Click on the button to get a popup menu in which you check/uncheck the
columns to show/hide.
If showing  ``Cell Data``  , the |pqProgrammableFilter| button, when
checked, enables you to see the point ids that form each of the cells.

:numref:`sec:UnderstandingSelection` discusses how selections can be made in
views to select elements of interest. Use the |pqSelectChart|
button to make the view show only selected elements. Now, as you make selections
in other views, this  ``SpreadSheet View``   will update to only show the values
of the selected elements (as long as the dataset selected in are indeed being shown
in the view).

.. admonition:: **Did you know?**
  :class: tip

  Some filters and readers produce ``vtkTable``, and they are automatically displayed
  in a spreadsheet view. Thus, one can very easily read the contents of a .csv file
  with |ParaView|.

Slice View
==========

.. figure:: ../images/SliceViewInParaView.png
    :name: fig:SliceViewInParaView
    :width: 70%
    :align: center

    ``Slice View``   can be used to show orthogonal slices from datasets.

``Slice View``   is special type of  ``Render View``   that can be used to view
orthogonal slices from any dataset. Any dataset shown in the view will be sliced
in axis-aligned slices based on the locations specified on the view. The
slice locations along the three orthogonal axis planes can be specified by using
the frame decoration around the view window.

Interactions
^^^^^^^^^^^^

Since this view is a type of  ``Render View``  , the camera interactions are same as
that of  ``Render View``  . Additionally, you can interact with the frame
decoration to manipulate slice locations along the three axis planes.

* Double-click the left mouse button in the region between the axis border and the view to add a new slice.

* You can click-and-drag a marker to move the slice location.

* To remove a slice, double-click with the left mouse button on the marker corresponding to that slice.

* To toggle visibility of the slice, you can right-click on the marker.

Slice View in ``pvpython``
^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: python

  # To create a slice view in use:
  >>> view = CreateView("MultiSlice")

  # Use properties on view to set/get the slice offsets.
  >>> view.XSliceValues = [-10, 0, 10]
  >>> print(view.XSliceValues)
  [-10, 0, 10]

  # Similar to XSliceValues, you have YSliceValues and ZSliceValues.
  >>> view.YSliceValues = [0]
  >>> view.ZSliceValues = []

Python View
===========

Some Python libraries, such as matplotlib, are widely used for making
publication-quality plots of data. The  ``Python View``   provides a way
to display plots made in a Python script right
within |paraview|.

The  ``Python View``   has a single property, a Python script that
generates the image to be displayed in the viewport. All the Python
bindings for |ParaView| and VTK that are available in the Python
scripting module are available from within this script, making it
possible to plot any array from just about any dataset that can be
loaded into |ParaView|. The Python script for the view is evaluated in a
unique Python environment so that global variables defined in the
script do not clobber global variables in other Python scripts (either
in other instances of the  ``Python View``   or in the Python
interpreter). This environment is reset each time the script is
evaluated, so data cannot be saved between evaluations.

The  ``Python View``   requires that the Python script where the
plotting occurs define two functions. In the first function, you
request which arrays you would like to transfer to the client for
rendering. At present, all rendering in this view takes place on the
client, even in client-server mode. These arrays can be point data,
cell data, field data, and table row data. This function runs only on
data-server processes. It provides access to the underlying data
object on the server so that you can query any aspect of the data
using the Python-wrapped parts of VTK and |ParaView|.

The second function is where you put Python plotting or rendering
commands. This function runs only on the |ParaView| client. It has
access to the complete data object gathered from the data server
nodes, but only has access to the arrays requested in the first function. This
function will typically set up objects from a plotting library,
convert data from VTK to a form that can be passed to the plotting
library, plot the data, and convert the plot to an image
(a  ``vtkImageData``   object) that can be displayed in the viewport.

Selecting data arrays to plot
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

All the rendering in the  ``Python View``   occurs in the client, so the
client must get the data from the server. Because the dataset residing
on the |ParaView| server may be large, transferring all the data to the
client may not be possible or practical. For that reason, we have
provided a mechanism to select which data arrays in a data object on
the server to transfer to the client. The overall structure of the
data object, however, (including cell connectivity, point positions,
and hierarchical block structure) is always transferred to the client.
By default, no data arrays are selected for transfer from the server.

The Python script for the view must define a function called
``setup_data(view)``  . The  ``view``   argument is the VTK object for the  ``Python
View``  . The current datasets loaded into |ParaView| may be accessed
through the view object.

.. figure:: ../images/PythonViewInParaView.png
    :name: fig:PythonViewInParaView
    :width: 70%
    :align: center

    |paraview| using  ``Python View``   with matplotlib to display a scatterplot of momentum magnitude versus density (upper right) and a histogram of density (lower right) in the bluntfin.vts dataset.

Here's an example of this function that was used to generate the image
in :numref:`fig:PythonViewInParaView`:

.. code-block:: python

  def setup_data(view):
    # Iterate over visible data objects
    for i in range(view.GetNumberOfVisibleDataObjects()):
      # You need to use GetVisibleDataObjectForSetup(i)
      # in setup_data to access the data object.
      dataObject = view.GetVisibleDataObjectForSetup(i)

      # The data object has the same data type and structure
      # as the data object that sits on the server. You can
      # query the size of the data, for instance, or do anything
      # else you can do through the Python wrapping.
      print('Memory size: {0} kilobytes'.format(dataObject.GetActualMemorySize()))

      # Clean up from previous calls here. We want to unset
      # any of the arrays requested in previous calls to this function.
      view.DisableAllAttributeArrays()

      # By default, no arrays will be passed to the client.
      # You need to explicitly request the arrays you want.
      # Here, we'll request the Density point data array
      view.SetAttributeArrayStatus(i, vtkDataObject.POINT, "Density", 1)
      view.SetAttributeArrayStatus(i, vtkDataObject.POINT, "Momentum", 1)

      # Other attribute arrays can be set similarly
      view.SetAttributeArrayStatus(i, vtkDataObject.FIELD, "fieldData", 1)

The  ``vtkPythonView``   class passed in as the  ``view``   argument to
``setup_data(view)``   defines several methods useful for specifying which
data arrays to copy:

* ``GetNumberOfVisibleDataObjects()``   -
  This returns the number of visible data objects in the view. If an object
  is not visible, it should not show up in the rendering, so all the
  methods provided by the view deal only with visible objects.

* ``GetVisibleDataObjectForSetup(visibleObjectIndex)``   -
  This returns the ``visibleObjectIndex'th``   visible data object in
  the view. (The data object will have an open eye next to it in the
  ``Pipeline Browser`` .)

* ``GetNumberOfAttributeArrays(visibleObjectIndex, attributeType)``   -
  This returns the number of attribute arrays for
  the  ``visibleObjectIndex'th``   visible object and the
  given ``attributeType``
  (e.g.,  ``vtkDataObject.POINT``  ,  ``vtkDataObject.CELL``  , etc.).

* ``GetAttributeArrayName(visibleObjectIndex, attributeType, arrayIndex)``   -
  This returns the name of the array of the given attribute type at the
  given array index for the ``visibleObjectIndex'th``   object.

* ``SetAttributeArrayStatus(visibleObjectIndex, vtkDataObject.POINT, "Density", 1)``  -
  This sets the array status of an attribute array. The first argument is
  the visible object index, the second object is the attribute
  association of the array, the third argument is the name of the
  array, and the last argument specifies if the array is to be copied
  (1) or not (0).

* ``GetAttributeArrayStatus(visibleObjectIndex, vtkDataObject.POINT, "Density")``   -
  This retrieves the array status for the object with the given visible
  index with a given attribute association (second argument) and a name
  (last argument).

* ``EnableAllAttributeArrays()``   -
  This sets all arrays to be copied.

* ``DisableAllAttributeArrays()``   -
  This sets all arrays to not be copied.

The methods  ``GetNumberOfVisibleDataObjects()``  ,
``GetVisibleDataObjectForSetup(...)``  ,  ``GetNumberOfAttributeArrays(...)``  ,
and  ``GetAttributeArrayName(...)``   are all convenient methods for
obtaining information about visible data objects in the view that
could otherwise be accessed with existing view and representation
methods. The last four methods are valid only from within
the  ``setup_data(view)``   function.

Plotting data in Python
^^^^^^^^^^^^^^^^^^^^^^^

After the  ``setup_data(view)``   function has been called, |ParaView|
will transfer the data object and selected arrays to the client. When
that is done, it will call the  ``render(view, width, height)``
function you have defined in your script.

The  ``view``   argument to the  ``render(view, width, height)``
function is the  ``vtkPythonView``   object on the
client. The  ``width``   and  ``height``   arguments are the width and
height of the viewport, respectively. The  ``render(view, width,
height)``   function uses the data available through the view, along with
the width and height, to generate a  ``vtkImageData``   object that will
be displayed in the viewport. This  ``vtkImageData``   object must be
returned from the  ``render(view, width, height)``   function. If no
``vtkImageData``   is returned, the viewport will be black. If the size of the
image does not match the size of the viewport, the image will be
stretched to fit the viewport.

Putting it all together, here is a simple example that generates a
solid red image to display in the viewport.

.. code-block:: python

  def render(view, width, height):
    from paraview.vtk import vtkImageData
    image = vtkImageData()
    image.SetDimensions(width, height, 1)
    from paraview.numeric import VTK_UNSIGNED_CHAR
    image.AllocateScalars(VTK_UNSIGNED_CHAR, 4)
    pixel_array = image.GetPointData().GetArray(0)
    pixel_array.FillComponent(0, 255.0)
    pixel_array.FillComponent(1, 0.0)
    pixel_array.FillComponent(2, 0.0)
    pixel_array.FillComponent(3, 0.0)

    return image

This example does not produce an interesting visualization, but serves
as a minimal example of how the  ``render(view, width, height)``
function should be implemented. Typically, we expect that the Python
plotting library you use has some utilities to expose the generated
plot image pixel data. You need to copy that pixel data to
the  ``vtkImageData``   object returned by the  ``render(view, width, height)``
function. Exactly how you do this is up to you, but |ParaView|
comes with some utilities to make this task easier for matplotlib.

Set up a matplotlib Figure
--------------------------

The  ``Python View``   comes with a Python module,
called  ``python_view``  , that has some utility functions you can
use. To import it, use:

.. code-block:: python

  from paraview import python_view

This module has a function, called  ``matplotlib_figure(view, width,
height)``  , that returns a  ``matplotlib.figure.Figure``   given  ``width``
and  ``height``   arguments. This figure can be used with matplotlib
plotting commands to plot data as in the following:

.. code-block:: python

  def render(view, width, height):
    figure = python_view.matplotlib_figure(width, height)

    ax = figure.add_subplot(1,1,1)
    ax.minorticks_on()
    ax.set_title('Plot title')
    ax.set_xlabel('X label')
    ax.set_ylabel('Y label')

    # Process only the first visible object in the pipeline browser
    dataObject = view.GetVisibleDataObjectForRendering(0)

    x = dataObject.GetPointData().GetArray('X')

    # Convert VTK data array to numpy array for plotting
    from paraview.numpy_support import vtk_to_numpy
    np_x = vtk_to_numpy(x)

    ax.hist(np_x, bins=10)

    return python_view.figure_to_image(figure)

This definition of the  ``render(view, width, height)``   function
creates a histogram of a point data array named  ``X``   from the first
visible object in the ``Pipeline Browser`` . Note the conversion
function,  ``python_view.figure_to_image(figure)``  , in the last line.
This converts the matplotlib  ``Figure``   object created
with  ``python_view.matplotlib_figure(width, height)``   into a
``vtkImageData``   object suitable for display in the viewport.

Comparative Views
=================

``Comparative Views``  , including  ``Render View (Comparative)``  ,  ``Line Chart
View (Comparative)``  , and  ``Bar Chart View (Comparative)``  , are used
for generating comparative visualization from parameter studies. These views
are covered in :numref:`chapter:ComparativeVisualization` of the Reference Manual.

Virtual reality
===============

|ParaView| supports immersive data visualization in virtual reality (VR) with
head-mounted displays (HMDs). VR can be used to view the scene in the active
:ref:`Render View` and interact with it. This environment provides enhanced perception
of depth and more intuitive manipulation of 3D objects by creating the sensation
of the user being physically present inside of the scene.

XRInterface plugin
^^^^^^^^^^^^^^^^^^^^

VR support in |ParaView| is provided through the ``XRInterface`` plugin (previously
called ``OpenVR`` plugin). To load this plugin, open the ``Plugin Manager`` via
:guilabel:`Tools > Manage Plugins...`. Click on ``XRInterface``, then on the button
``Load Selected``. This will open the :ref:`XRInterface panel`.

How to install/build
--------------------

By default, the ``XRInterface`` plugin is already enabled in |ParaView|
`Windows binaries <https://www.paraview.org/download/>`_. Simply launch |ParaView|
with a VR runtime such as `SteamVR`_ on your machine to easily experience VR with
|ParaView|.

Otherwise, the plugin needs to be enabled before building |ParaView|, see `README.md
<https://gitlab.kitware.com/paraview/paraview/-/blob/master/Plugins/XRInterface/README.md>`_
in the plugin sources for more information.

.. _XRInterface panel:

XRInterface panel
-------------------

By default, the ``XRInterface`` panel appears on the right upon loading the plugin.
To open it manually, search for the corresponding checkbox in the main menu via
:guilabel:`View > XRInterface`.

  .. figure:: ../images/XRInterfacePanel.png
      :name: fig:XRPanel
      :width: 60%
      :align: center

      XRInterface panel.

Once the ``XRInterface`` plugin is loaded and an HMD connected, click on the
button ``Send to XR`` to start rendering in VR. Other options are available in
the plugin panel:

* ``Use MultiSamples`` --- This checkbox indicates whether multisampled framebuffers
  are used. Using multisamples can reduce flickering but currently does not work
  with volume rendering.

* ``Base Station Visibility`` --- This checkbox indicates whether the base stations
  models are displayed in VR (for devices using base stations).

* ``Desired XR Runtime`` --- This drop down list indicates whether to use OpenVR or
  OpenXR when both are available.

* ``Send to XR`` - This button launches the VR mode using the selected runtime.

* ``Attach to Current View`` --- This button allows VR-only elements to appear in
  the current Render View, such as cropping planes or avatars. This option is mainly
  useful in Collaboration mode for desktop users when an HMD is not available.

* ``Show XR View`` - This button opens a window showing a stabilized view of what the VR
  headset is showing, which is useful to produce screenshots or videos.

* ``Export Locations as a View`` --- This button exports saved locations as ``.vtp``
  files in a folder called ``pv-view``. This option is meant to be used for `Mineview`_.

* ``Export Locations as Skyboxes`` --- This button exports saved locations as skyboxes
  in a folder called ``pv-skybox``. This generates six `.jpg` images (`right`, `left`, `up`,
  `down`, `back` and `front`) producing a skybox that can then be used outside of
  VR as well.

Interactions
^^^^^^^^^^^^

On top of head tracking to reproduce the user physical movements for navigation,
the controllers can be used to interact with the data through actions such as scaling,
picking, etc.

The controls mapping for different controllers is detailed in :numref:`sec:ControlsMapping`.

+-----------------------------+------------------------+
| Action                      | Controls               |
+=============================+========================+
| Movement                    | (Left/Right) Joystick  |
+-----------------------------+------------------------+
| Open XR Menu                | Right Menu Button      |
+-----------------------------+------------------------+
| Confirm (XR Menu)           | Right Trigger          |
+-----------------------------+------------------------+
| Trigger Action              | Right Trigger          |
+-----------------------------+------------------------+
| Move to Next Saved Location | Left Trigger           |
+-----------------------------+------------------------+
| Grip Action                 | Left Grip + Right Grip |
+-----------------------------+------------------------+

.. _sec:VRTriggerActions:

Trigger actions
---------------

Trigger actions are assigned to the right trigger by default and include grabbing,
picking, probing, interactive clipping, teleportation, and adding points to sources
(such as a polyline source). The current action can be chosen via the XR menu
(see :numref:`sec:XRMenu`).

* **Adding points to a source** --- Press the right trigger to place a point at
  the tip of the right controller. Only valid when the active source allows placing
  points, such as a polyline source.

  .. figure:: ../images/VRPtSource.png
      :name: fig:VRPtSource
      :width: 80%
      :align: center

      Adding a point to a polyline source in VR.

* **Grabbing** --- Press the right trigger when the right controller is in the
  bounding box of an object to grab it and move it.

  .. figure:: ../images/VRGrab.png
      :name: fig:VRGrab
      :width: 80%
      :align: center

      Grab action in VR.

* **Picking** --- Press the right trigger while pointing at an object to pick it
  and move it from a distance.

  .. figure:: ../images/VRPick.png
      :name: fig:VRPick
      :width: 80%
      :align: center

      Picking action in VR.

* **Interactive Cropping** --- Press the right trigger to crop the scene in real
  time with a plane placed at the tip of the right controller.

  .. figure:: ../images/VRCrop.png
      :name: fig:VRCrop
      :width: 80%
      :align: center

      Real time cropping in VR.

* **Probing** --- Press the right trigger while pointing at a dataset cell to select
  it and display information on its position and data values.

  .. figure:: ../images/VRProbe.png
      :name: fig:VRProbe
      :width: 80%
      :align: center

      Cell probing action in VR.

* **Teleportation** --- Press the right trigger while pointing at a dataset with
  the ray to instantly move at the pointed location.

Grip actions
------------

Grip actions are used to transform the scene through translation, scaling and rotation.

* **Translation** --- Press both grip buttons, then move the controllers together
  to translate the scene.

  .. figure:: ../images/VRTranslate.png
      :name: fig:VRTranslate
      :width: 80%
      :align: center

      Translation action in VR. Green and red arrows correspond to movements of the
      controllers and dataset, respectively.

* **Scaling/zoom** --- Press both grip buttons, then move the controllers farther
  or closer to each other to zoom in or out of the scene.

  .. figure:: ../images/VRScale.png
      :name: fig:VRScale
      :width: 80%
      :align: center

      Scaling action in VR. Green and red arrows correspond to movements of the
      controllers and dataset, respectively.

* **Rotation** --- Press both grip buttons, then move one controller around the other
  to rotate the scene around a vertical axis.

  .. figure:: ../images/VRRotate.png
      :name: fig:VRRotate
      :width: 80%
      :align: center

      Rotation action in VR. Green and red arrows correspond to movements of the
      controllers and dataset, respectively.

.. _sec:XRMenu:

XR menu
^^^^^^^

In the XR View, pressing the menu button opens a dedicated menu floating in the
3D scene in front of the user.

  .. figure:: ../images/XRMenu.png
      :name: fig:XRMenu
      :width: 90%
      :align: center

      XR integrated menu.

This menu is composed of the following elements:

#. **Pipeline Browser** --- This is the same ``Pipeline Browser`` present in |ParaView|.
   The visibility for each item in the pipeline can be modified by pointing the
   navigation ray on the eye icon and pressing the right trigger.

#. **Panels** --- VR options are distributed into 4 panels, that can be displayed by
   clicking on the corresponding tab:

   * ``Interaction`` --- This panel contains options related to the interactions with
     the scene using the controllers (see :numref:`sec:VRInteractionPanel`).

   * ``Movement`` --- This panel contains options related to the camera movement and
     poses (see :numref:`sec:VRMovementPanel`).

   * ``Environment`` --- This panel contains global options related to the scene
     (see :numref:`sec:VREnvironmentPanel`).

   * ``Widgets`` --- This panel contains options related to VR-specific widgets
     (see :numref:`sec:VRWidgetsPanel`).

#. **Exit XR** --- This button closes the current XR View.

#. **Animation Buttons** --- These buttons are used to navigate timesteps for
   temporal datasets.

.. _sec:VRInteractionPanel:

Interaction panel
-----------------

  .. figure:: ../images/XRMenuInteraction.png
      :name: fig:XRMenuInteraction
      :width: 90%
      :align: center

      Interaction panel of the XR integrated menu.

* ``Right Trigger`` --- This drop down list indicates which action is mapped to
  the right trigger outside of the menu, such as picking, probing, etc. See
  :numref:`sec:VRTriggerActions` for the list of available actions.

* ``Reset Actors Positions`` --- This button resets the position of all objects within
  the scene.

* ``Interactive Ray`` --- This checkbox indicates whether the ray changes color
  when pointing at an object to signal a collision.

.. _sec:VRMovementPanel:

Movement Panel
--------------

  .. figure:: ../images/XRMenuMovement.png
      :name: fig:XRMenuMovement
      :width: 90%
      :align: center

      Movement panel of the XR integrated menu.

* ``Movement Style`` --- This drop down list indicates which movement style
  is mapped to the controller joysticks.

    * **Flying** mode uses only one
      joystick and movement follows the orientation of the controller itself.

    * **Grounded** mode uses the left joystick to move horizontally in all directions,
      while the right joystick controls elevation.

* ``Movement Speed`` --- This horizontal slider modifies the movement speed when using
  the joysticks. A higher multiplier corresponds to a higher speed.

* ``Reset Camera`` --- This button scales and places the objects at the center
  of the physical room.

* **Camera pose buttons**:

  * ``Clear`` --- This button clears all previously saved camera poses.

  * ``Save pose`` --- This button saves the current pose in the list of saved
    camera poses. Up to 6 poses can be saved this way. For each saved pose, a
    dedicated button is added to the right of this button.

* ``Bring Collaborators Here`` --- This button moves all collaborators to your
  current location. Only applicable in Collaboration mode.

.. _sec:VREnvironmentPanel:

Environment panel
-----------------

  .. figure:: ../images/XRMenuEnvironment.png
      :name: fig:XRMenuEnvironment
      :width: 90%
      :align: center

      Environment panel of the XR integrated menu.

* ``View Up Direction`` --- These buttons set which axis points upwards from
  the top of the HMD. This is useful when datasets or skyboxes are oriented
  differently from the default.

* ``Scene Scale`` --- These buttons change the scaling factor of the scene.
  A higher value results in all objects appearing larger.

* ``Show Floor`` --- This button allows hiding or showing the floor as a white plane.

.. _sec:VRWidgetsPanel:

Widgets panel
-------------

  .. figure:: ../images/XRMenuWidgets.png
      :name: fig:XRMenuWidgets
      :width: 90%
      :align: center

      Widgets panel of the XR integrated menu.

* ``Distance Widget`` --- This button adds a measuring tool to the scene.
  Press the right trigger once to place the starting point where the right
  controller is located, then press a second time with the controller at the
  desired location to place the second point. Four values are displayed next
  to the tool: distance and X, Y, Z difference between both points.
  The tips of the line can be grabbed and moved individually after placing them.

.. figure:: ../images/VRDistanceWidget.png
    :name: fig:VRDistanceWidget
    :width: 80%
    :align: center

    Distance measurement widget in VR.

* ``Navigation Panel`` --- This button allows to display a tooltip above the
  left controller with information on its spatial position in world coordinates.

.. figure:: ../images/VRNavigationPanel.png
    :name: fig:VRNavigationPanel
    :width: 80%
    :align: center

    Navigation panel widget in VR.

* **Cropping buttons** --- The following buttons provide tools to crop data in real time.
  Cropping planes can be moved by placing the right controller on them and grabbing
  them with the right trigger. More than one plane can be added to the scene.

  * ``Add Crop Plane`` --- This button adds a cropping plane to the scene.

  * ``Add Thick Crop`` --- This button adds a thick cropping plane to the scene.

  * ``Hide Crop Planes`` --- This button hides all cropping planes in the scene.

  * ``Remove All Crop Planes`` --- This button removes all cropping planes from
    the scene.

  * ``Crop Thickness`` --- This horizontal slider sets the thickness of created
    thick cropping planes (this parameter does not affect current ones). By default,
    the value is set to **auto**, which adjusts the plane thickness according to the
    current scene scale.

  * ``Snap Crop Planes`` --- This button allows to choose whether the cropping
    planes should snap to the coordinates axes.

.. _sec:Remoting:

Remoting
^^^^^^^^
.. admonition:: **Notice**
  :class: tip

  Remoting support is currently experimental.

Remoting allows streaming the active render view of ParaView to a remote device.

Prerequisites
-------------

The remoting feature is only available on Windows for the Hololens 2 and requires an additional
package named `Microsoft.Holographic.Remoting.OpenXr`_. With this, ParaView can connect to
another application in the remote device if both applications use the same version
of this package.

Note that the ParaView release uses the same version as the official player application developed
by Microsoft, available in the `Microsoft Store`_, which is version **2.9.2**.

If you do have not an application already deployed in the remote device, we recommend downloading the
`Holographic Remoting Player` application in the Microsoft Store.

How to launch
-------------

First, start the application on the remote device.

After launching this application, it will wait for another application to connect to it via an IP address.

.. figure:: ../images/XRRemotingWaitingScreen.png
    :name: fig:XRRemotingWaitingScreen
    :width: 90%
    :align: center

    Remote application awaiting connection in the Hololens 2.

You can now start ParaView and do any process on your data that you want. When you are ready to test it in
the Hololens 2, enable the XR Interface plugin. You will need to set different options:

* ``Desired XR Runtime`` --- set it to `OpenXR` because the `Microsoft.Holographic.Remoting.OpenXr` depends on it.
* ``Use OpenXR Remoting`` --- enable or disable the remoting support.
* ``Remote address`` --- set the IP address to connect ParaView and the application in the Hololens 2.

.. figure:: ../images/XRRemotingPanel.png
    :name: fig:XRRemotingPanel
    :width: 40%
    :align: center

    XRInterface panel with OpenXR Remoting options.

After setting these options, you can click on ``Send To XR``. Once the connection is established, you will be able
to see and interact with your dataset.

.. figure:: ../images/XRRemotingApplication.png
    :name: fig:XRRemotingApplication
    :width: 50%
    :align: center

    can.ex2 in the Hololens 2.

For now, only grabbing feature is available as interaction.

.. _sec:ControlsMapping:

Controls mapping
^^^^^^^^^^^^^^^^

This section details the button mappings used in |ParaView| for different types
of controllers. The controls names are those used throughout the VR section.

HP Motion
---------

+-------------------+-------------------+
| XR View Controls  | Controller Button |
+===================+===================+
| Joystick          | Joystick          |
+-------------------+-------------------+
| Trigger           | Trigger           |
+-------------------+-------------------+
| Grip              | Grip Button       |
+-------------------+-------------------+
| Menu Button       | Menu Button       |
+-------------------+-------------------+

HTC Vive
--------

+-------------------+-------------------+
| XR View Controls  | Controller Button |
+===================+===================+
| Joystick          | Trackpad          |
+-------------------+-------------------+
| Trigger           | Trigger           |
+-------------------+-------------------+
| Grip              | Grip Button       |
+-------------------+-------------------+
| Menu Button       | Menu Button       |
+-------------------+-------------------+

Oculus Touch
------------

+-------------------+-------------------+
| XR View Controls  | Controller Button |
+===================+===================+
| Joystick          | Joystick          |
+-------------------+-------------------+
| Trigger           | Trigger           |
+-------------------+-------------------+
| Grip              | Grip Button       |
+-------------------+-------------------+
| Menu Button       | Menu Button       |
+-------------------+-------------------+

Valve Index
-----------

+-------------------+-------------------+
| XR View Controls  | Controller Button |
+===================+===================+
| Joystick          | Joystick          |
+-------------------+-------------------+
| Trigger           | Trigger           |
+-------------------+-------------------+
| Grip              | A Button          |
+-------------------+-------------------+
| Menu Button       | B Button          |
+-------------------+-------------------+

Microsoft Hand
--------------

+-------------------+-------------------+
| XR View Controls  | Controller Gesture|
+===================+===================+
| Trigger           | Hand squeeze      |
+-------------------+-------------------+
| Grip              | Hand grip         |
+-------------------+-------------------+

.. \begin{TODO}
  \begin{itemize}
    \item Several advanced views remain including Histogram View, Bag Chart, etc.
  \end{itemize}
  \end{TODO}

.. _SteamVR: https://www.steamvr.com/

.. _Microsoft.Holographic.Remoting.OpenXr: https://www.nuget.org/packages/Microsoft.Holographic.Remoting.OpenXr

.. _Microsoft Store: https://apps.microsoft.com/store/detail/holographic-remoting-player/9NBLGGH4SV40

.. _Mineview: https://gitlab.kitware.com/ken-martin/mineview/

.. |TabWidgetPlus| image:: ../images/icons/TabWidgetPlus.png
   :height: 20px

.. |pqRectilinearGrid| image:: ../images/icons/pqRectilinearGrid16.png
   :height: 20px

.. |TitleBarCloseButton| image:: ../images/icons/TitleBarCloseButton.png
   :height: 20px

.. |TitleBarMaxButton| image:: ../images/icons/TitleBarMaxButton.png
   :height: 20px

.. |pqAdvanced| image:: ../images/icons/pqAdvanced.svg
   :width: 20px

.. |pqProgrammableFilter| image:: ../images/icons/pqProgrammableFilter.svg
   :width: 20px

.. |pqSelectChart| image:: ../images/icons/pqSelectChart.svg
   :width: 20px

CAVEs
=====

|ParaView| supports immersive data visualization in CAVEs (CAVE is a recursive
acronym which stands for CAVE automatic virtual environment) thanks to a combination
of server side rendering configuration with PVX files and a dedicated interaction plugin
named CAVEInteraction.

PVX server side rendering
^^^^^^^^^^^^^^^^^^^^^^^^^
CAVE rendering support in |ParaView| is provided through the configuration
of the server using .pvx files. The general idea is to show a window server side
on a specific location with specific parameters.

Here is a trivial .pvx file:

.. code-block:: xml

	<pvx>
	  <Machine Name="localhost"
	           Environment="DISPLAY=:0"
	           Geometry="300x300+300+0"/>
	</pvx>

Here we define that the server should show a 300x300 window on 300,0 location
on the `:0` screen.

To use it simply run |pvserver| like this:

.. code-block::

	pvserver --pvx /path/to/trivial.pvx

Then connect to the server and trigger a rendering. A window will appear on the screen of the server.

If you render anything you will remark that the camera seems positioned in the center of the scene.
This is expected and you should use the CAVEInteraction plugin as described below.
Another way to simply set the `EyeTransformMatrix` is to run a simple python script:

.. code-block:: python

	from paraview.simple import *
	from vtkmodules.vtkCommonTransforms import vtkTransform

	eyepos = [0, 0, 5]

	tform = vtkTransform()
	tform.Translate(eyepos)
	mat = tform.GetMatrix()

	rv = GetActiveView()
	rv.SetPropertyWithName("EyeTransformMatrix", mat.GetData())

More complex configurations are possible, here is an example:

.. code-block:: xml

	<?xml version="1.0" ?>
	<pvx>
	  <!--
	      Three screen configuration: left, right, floor
	      Screens are 2.26 x 1.27 in physical coordinates
	  -->
	  <Machine Name="Left"
	    Geometry="640x360+100+1200"
	    ShowBorders="0"
	    LowerLeft="-1.13 -0.635 1.04"
	    LowerRight="-1.13 -0.635 -1.22"
	    UpperRight="-1.13  0.635 -1.22"
	  />
	  <Machine Name="Right"
	    Geometry="640x360+740+1200"
	    ShowBorders="0"
	    LowerLeft="-1.13 -0.635  -1.22"
	    LowerRight="1.13 -0.635 -1.22"
	    UpperRight="1.13  0.635 -1.22"
	  />
	  <Machine Name="Floor"
	    Geometry="640x360+740+1560"
	    ShowBorders="0"
	    LowerLeft="-1.13 -0.635  0.05"
	    LowerRight="1.13 -0.635  0/05"
	    UpperRight="1.13 -0.635 -1.22"
	  />
	</pvx>

Here we define a left, right and floor window with their physical coordinates in meters.
The physical coordinates of the three corners of each display are required for correct off-axis projection, as described in the 2011 paper "Generalized Perspective Projection" by Robert Kooima.

Finally, here is an example with all supported properties:

.. code-block:: xml

	<?xml version="1.0" ?>
	<pvx>
	  <EyeSeparation Value="0.065"/>
	  <Machine Name="Screen"
	    Geometry="640x360+100+1200"
	    ShowBorders="0"
	    FullScreen="1"
	    Coverable="1"
	    LowerLeft="-1.13 -0.635 1.04"
	    LowerRight="-1.13 -0.635 -1.22"
	    UpperRight="-1.13  0.635 -1.22"
	  />

CAVEInteraction plugin
^^^^^^^^^^^^^^^^^^^^^^

CAVE interaction support in |ParaView| is provided through the ``CAVEInteraction`` plugin
(which was at one time called ``VRPlugin``). To load this plugin, open the
``Plugin Manager`` via :guilabel:`Tools > Manage Plugins...`. Click on
``CAVEInteraction``, then on the button ``Load Selected``. This will open the
:ref:`CAVE Interaction Manager panel`.

How to install/build
--------------------

By default, the ``CAVEInteraction`` plugin is already enabled in |ParaView|
`binaries <https://www.paraview.org/download/>`_.

Otherwise, the plugin needs to be enabled before building |ParaView|, see the
`documentation <https://gitlab.kitware.com/paraview/paraview/-/blob/master/Plugins/CAVEInteraction/README.md>`_
in the plugin sources for more information.

.. _CAVE Interaction Manager panel:

CAVE Interaction Manager panel
------------------------------

By default, the ``CAVE Interaction Manager`` panel appears on the lower left upon loading the plugin.
To open it manually, search for the corresponding checkbox in the main menu via
:guilabel:`View > CAVE Interaction Manager`.

  .. figure:: ../images/CAVEDockPanelNoCollab.png
      :name: fig:CAVEDockPanelNoCollab
      :width: 80%
      :align: center

      CAVE Interaction Manager panel.

At the highest level, using the plugin is just a matter of configuring
VR events and interactions (and likely saving it all to state for easy and
quick re-constitution later), and then clicking the "Start" button to
start the VR events streaming into your interactor styles.

But as you might guess from looking at the panel above, there are a couple
of concepts to understand about CAVE Interactions first: VR Connections and
Interactions.

CAVE Interaction Concepts
^^^^^^^^^^^^^^^^^^^^^^^^^

Interacting with your CAVE through ParaView involves the following:

1. Configure events using the "VR Connections" section
2. Add one or more interactor styles using the "Interactions" section
3. Click the ``Start`` button to begin interacting
4. Click the ``Stop`` button to stop interacting

Interactor styles are quite flexible in allowing you to manipulate ParaView
proxies and their associated properties, but one main goal of interactor
styles is to allow you to navigate around your dataset.  You can find more
information on navigation, events, and interactor styles in the sections
below.

Eye Positions in the CAVE
-------------------------

A CAVE is very different from a traditional screen as the eye positions are
usually known thanks to a tracking system.  This means that it becomes possible
to achieve proper off axis projection rendering, which is supported by VTK.
However, it means that the ParaView window and the CAVE window are not synchronized
fully as their camera is configured differently, and that the ``EyeTransformMatrix``
must be set up to track the viewers head in order to get a correct rendering.
This is described in the 2011 paper "Generalized Perspective Projection" by Robert Kooima.

This is achieved thanks to the configuration of the CAVE Interactor, see below.

Navigation in the CAVE
----------------------

A CAVE can help you explore your data by allowing you to move around within
your physical space, looking at the data from different positions and
angles to gain a better understanding.  When the scale of the data exceeds
the size of your physical space, the ability to navigate becomes important.
One of the main goals of the CAVEInteraction plugin is to support this kind
of navigation.

For this purpose, the base class of all CAVE interactors provides methods to
get and set the navigation matrix, and these should be used to navigate in
the CAVE.  This is the only way to move and rotate around the data and should be
handled in the CAVE interactor configuration, see below.

From a programming point of view, the approach consists of:

1. access the current nagivation matrix using the provided ``GetNavigationMatrix`` method
2. multiply it on the left with the next desired navigation transformation
3. update the current navigation matrix with ``SetNavigationMatrix``.

The ParaView source code repository contains an
`example <https://gitlab.kitware.com/paraview/paraview/-/blob/master/Examples/VR/CustomizablePythonInteractorStyle.py>`_
of this approach in action.

Coordinate Systems
------------------

There are two main coordinate systems supported in CAVES, termed "Fixed"
and "Navigable".  Any pipeline objects can be placed in either coordinate
system by toggling advanced properties and/or searching in the properties
panel for "coordinate system".

  .. figure:: ../images/RepresentationCoordinateSystem.png
      :name: fig:PVSelectCoordinateSystem
      :width: 80%
      :align: center

      Choosing a coordinate system for representations.

Any pipeline objects placed in the ``Fixed`` coordinate system will not
move as a result of navigation, while objects placed in the ``Navigable``
coordinate system will be transformed by the navigation matrix.
Default is ``Navigable``.

For example, let's say you wish to place two "screen bumpers" in your
scene to mark where your physical displays are located.  This could help
you avoid accidentally walking into the screens while immersed in your data
inside your CAVE.

To accomplish this, you could create two "Box" sources, and use the screen
coordinates from your ``.pvx`` file to compute the ``Center`` and ``X/Y/Z Length``
properties of these boxes so that they share the same length as the front
and side walls, but have small, fixed width and depth (so they don't
obscure too much of the data you want to see).

Once these are sized and positioned to your satisfaction, you would set
their coordinate system to ``Fixed``.  Later, when loading your data, you
don't have to do anything special, as the default coordinate system is
``Navigable``, which is likely what you want.

Now, when ``SetNavigationMatrix`` is called in interactor style
proxies, the screen bumpers will remain fixed in place, adjacent to your
front and side walls, while you, for example, fly through the rest of
your data.

VR Connections
--------------

Two more important concepts in the CAVEInteraction plugin are so-called
connections and interactions.  At a high level, connections represent
the events that might be generated by your devices, while interactions
(also sometimes referred to as "interactors" or "interactor style proxies")
represent the actions you take in response to those events.  Let's start
by taking a closer look at connections.

You can add any number of VR Connections by clicking the :guilabel:`Add` button
below the list of connections in the ``VR Connections`` section of the panel.
Alternatively, if you select an item in that list, you can either :guilabel:`Edit`
or :guilabel:`Remove` that item.

To add a connection you must first choose whether the source is a VRPN or VRUI
event source (if you built ParaView yourself and don't see both of those
options, check your build configuration and make sure they're enabled).  Then
you can assign a unique name and specify the network address of the event
source.  Next, you must define one or more events you expect to receive from
the connection.  To define an event, first select the event type from the
left-most combo box, then type in the event ID number (you get these from
your tracking system), and lastly provide a name to associate with the event.
Once you have filled in all three values, click the "plus" button to create
the event definition.  See the image below for some examples.

  .. figure:: ../images/CAVEEditVRConnection.png
      :name: fig:CAVEEditVRConnection
      :width: 80%
      :align: center

      Defining CAVE Interaction events.

To remove any event from the configuration, simply select the associated row
and click the "minus" button.  Event definitions cannot be edited, instead you
must remove the event you wish to edit, and then add it again.

The screenshot above shows a single VRPN connection with 9 events defined
corresponding to all the inputs available on a standard HTC Vive controller.
The trigger is defined not only as a valuator (or analog) (which indicates how much the
trigger is squeezed), but also as a button (which only fires once the trigger
has been squeezed to the maximum extent, where there is a small haptic response
to help indicate a "click").  Similarly, the trackpad has been associated with
two valuator events (one for the amount of displacement in the y direction, and
one for the x displacement), as well as a button click for when you press it
a little harder.  The controller's orientation is defined as a "Tracker" event,
and events are defined for all the other buttons available on the device.

Figuring out the right configuration for the VR connection can be complex,
let's take a closer look into VRPN setup.  First we need to configure VRPN so that the
vrpn_server can connect to the tracking device.  Second we need inspect VRPN output
to figure out the type and id of the VRPN events we want to recover.  Third we need to convert that
into a proper CAVEInteraction connection configuration.

1. VRPN configuration

ParaView ships a `vrpn_server` executable and a ``vrpn.cfg`` configuration file.
Modify ``vrpn.cfg`` according to your tracking devices.  Usually, it is just needed to
uncomment one specific line and modify accordingly to the documentation above, eg,
to add a specific keyboard on linux and name it ``Input0``:

.. code-block::

  vrpn_DevInput           Input0          "Hoksi Technology DURGOD Taurus K320" keyboard 255

Then start the `vrpn_server` (super user may be needed on Linux) using port 22222:

.. code-block::

  ./bin/vrpn_server -v 22222

To make sure the `vrpn_server` is working as expected, the easiest way is to use the debug tool
`vrpn_print_devices`:

.. code-block::

  ./bin/vrpn_print_devices Input0@localhost:22222

This should output information about the events when the device is interacted with, especially event type and id.

2. Identify event types and ids

Using `vrpn_print_devices` as shown above displays information about devices events types and ids.
It usually looks like this:

.. code-block::

  Button Input0@localhost:22222, number 106 was just released
  Analog Input1@localhost:22222:  -1.00, -1.00
  Tracker Input2@localhost:22222, sensor 0: pos (1.2, 1.3, 1.4); quat (0.12, -0.18, 0.73, 0.64)

The first word is the event type that are described above.
The URI is the one configured in the `vrpn_server` configuration.
The number is the id of the event; for buttons, there is one id by button; for valuator (analog)
there is no id but each value can be accessed in order by id; for Tracker, there is one id by sensor.

3. Creating a CAVEInteraction connection configuration

As shown above, the configuration can be created interactively but the result can be saved in a ``.pvvr`` which
looks like this:

.. code-block::

  <CAVEInteractionState>
    <VRConnectionManager>
      <VRPNConnection name="mouse" address="Input1@localhost:22222">
        <Button id="0" name="left"/>
        <Button id="1" name="right"/>
        <Button id="2" name="middle"/>
        <Valuator id="0" name="mousex"/>
        <Valuator id="1" name="mousey"/>
      </VRPNConnection>
      <VRPNConnection name="keyboard" address="Input0@localhost:22222">
        <Button id="103" name="up"/>
        <Button id="105" name="left"/>
        <Button id="106" name="right"/>
        <Button id="108" name="down"/>
      </VRPNConnection>
    </VRConnectionManager>
  </CAVEInteractionState>

The ``address`` is just the URI of the device, then each events is listed with
``<EventType id="val" name="foo"/>``.
The event type and id value are the ones recovered using `vrpn_print_devices` as described above
and the name is just a name that will be used when defining actual interactions as described below.

Defining Interactions
---------------------

Once you have defined events via the "VR Connections" you can use them to
configure interactions.  Interactions are typically defined in C++ code as
subclasses of the ``vtkSMVRInteractorStyleProxy`` class.  Most interactor
styles are defined to operate on a single property of a selected proxy, and
the specific proxy and property are left to the user to choose at runtime.
Besides that, an interactor style has a few responsibilities:

#. Declare all event types it needs to operate, giving each event type a useful name (known as a "Role").
#. Declare the number of elements it can handle updating.  For example a style could update a 3-element color or position property, or it could update a 16-element matrix property.
#. Implement one or more of the handler methods defined by the base class.

To declare needed event types, an interactor style should make calls like
the following in its constructor:

::

    AddNamedTrackerRole("Head");
    AddNamedButtonRole("Reset");
    AddNamedValuatorRole("Fly");

To declare the number of property elements it can handle updating, an interactor
style should override this method to return the number of elements:

::

    virtual int GetControlledPropertySize();

where the default is ``-1``, which indicates to the UI that no filtering
should be done to display to the user only properties of the correct length.

The methods an interactor style should likely override are the following:

::

    virtual void HandleButton(const vtkVREvent& event);
    virtual void HandleValuator(const vtkVREvent& event);
    virtual void HandleTracker(const vtkVREvent& event);

Inside these methods is where the real work of responding to events happens.

Using Interactions
------------------

The CAVEInteraction plugin defines a set of interactor styles that can be
used out of the box, each of which follows the guidelines above.  These
built-in styles are available to select from the left-most combo box in
the ``Interactions`` section of the panel:

  .. figure:: ../images/CAVEInteractions.png
      :name: fig:CAVEInteractions
      :width: 80%
      :align: center

      Creating an interaction.

Once you have selected an interactor style from the list, you can then
select the proxy and property upon which it should act, using the remaining
two combo boxes to the right.  If the interactor style you chose overrides
the ``GetControlledPropertySize()`` method, choosing a proxy from the
center combo will constrain the properties in the right-most combo so
that only the proxy's properties of that length are shown.  Otherwise
all of the proxy's properties are shown in the right-most combo.  Once
you have set all three the way you want, click the "Add" button.  This
will bring up a dialog allowing you to define the mapping from your
pool of defined events to the "Roles" defined by the interactor style:

  .. figure:: ../images/CAVEAddInteraction.png
      :name: fig:CAVEAddInteraction
      :width: 60%
      :align: center

      Configuring the role bindings.

The image above shows what the dialog looks like when the interactor
style has only defined one named tracker role, "Tracker".  As you can
see, the combo box was automatically filled with one of the events of
type "tracker" defined earlier in the ``VR Connections`` section of the
panel.  Clicking "Ok" on the dialog accepts the chosen mapping of event
to named role.

The results can be saved into the ``.pvvr`` file and can look like this:

.. code-block::

  <VRInteractorStyles>
    <Style class="vtkSMVRYourInteractionStyleProxy" proxyName="RenderView1" proxy="6552" property="ModelTransforMatrix">
      <Valuator role="Mouse Position X" name="mouse.mousex"/>
      <Valuator role="Mouse Position Y" name="mouse.mousey"/>
      <Button role="up" name="keyboard.up"/>
      <Button role="left" name="keyboard.left"/>
      <Button role="right" name="keyboard.right"/>
      <Button role="down" name="keyboard.down"/>
    </Style>
  </VRInteractorStyles>

This is just a mapping between event names from the VR connection and "roles" expected by the interaction style
used, which of course should match for that style.  The proxy and property are the one that are being controlled by the interaction style.

Custom Python Interactors
-------------------------

The "Python" interactor style is a recent addition to the built-in
collection which gives you complete freedom and power to define your
own interactions in Python.

To use this type of interactor style, simply select "Python" in the
left-most combo box in the ``Interactions`` section of the panel.
When you do this, you can just ignore the other two drop-downs, as
your Python code will have the ability to update any number of proxies
and properties.  Once you click the "Add" button and your "Python"
interactor style appears in the list, select it, and its "File Name"
property editor will appear in the UI, allowing you to select the
Python file to use:

  .. figure:: ../images/PythonInteractorSelectFile.png
      :name: fig:SelectPythonFile
      :width: 80%
      :align: center

      Select Python interactor file.

Any time you change the file, and also any time you click the
"Refresh" button in the "File Name" property editor, the selected
file will be re-read, and the "Add VR Interaction" dialog will
reappear, allowing you to update the event/role bindings.

Defining Python Interactors
---------------------------

To define a custom Python interactor, you have a few responsibilities:

#. In your Python file, define a method called ``create_interactor_style()`` that creates and returns an instance of your class
#. In your interactor style Python class, define an ``Initialize(self, vtkSelf)`` method where you declare the event types of interest
#. In your interactor style Python class, define your tracker, button, and valuator handler methods

You can also define a constructor for your class, and any instance
methods or module-level methods you wish.  Your handler methods are
then called with the latest event data so you can do whatever your
imagination desires, all of ParaView proxies are at your fingertips
to use as you see fit.

The paraview source repository has an `example <https://gitlab.kitware.com/paraview/paraview/-/blob/master/Examples/VR/CustomizablePythonInteractorStyle.py>`_ custom Python
interactor style you can use as a model.

To achieve head tracking in your custom Python interactor, you only
need to update the ``EyeTransformMatrix`` available on the active render
view proxy (accessible via ``GetActiveView()``).  To perform any kind
of transformation on the entire scene, hereafter referred to as
"navigation", simply call the ``SetNavigationMatrix`` method which
is defined on the ``vtkSMVRInteractorStyleProxy`` class.  In C++ interactor
styles you can access this method on yourself (via the ``this`` pointer),
while in Python interactor styles, you can call it on the ``vtkSelf``
argument pass to all methods (see the example linked above).  In Python
interactor styles, you are also free to target properties on any pipeline
source/filter proxies in your custom interactor style, as well as properties
on paraview representation or view proxies.

Collaboration
^^^^^^^^^^^^^

If you downloaded a binary version of ParaView from the website, then it
is already set to collaborate with other immersive ParaView users around
the world.  Similar to functionality in the ``XRInterface`` plugin, the
``CAVEInteraction`` plugin supports collaboration via a publicly available
collaboration server, using a simple protocol.

Note that when using the collaboration feature, users of both plugins
can collaborate with each other seamlessly, though the ``XRInterface``
plugin currently supports more features than the ``CAVEInteraction``
plugin.

Collaboration Basics
--------------------

In this context collaboration means joining a session with other ParaView
users, and getting real-time information about their head/hand positions,
as well as possibly information about where they have navigated in the
navigable world.  Some things to keep in mind when collaborating with
other users:

* Each user must load the same data in order to see the same thing
* Pipeline state is not shared with collaborators

When collaborating with others, you will see an animated avatar
representing each connected user, and each avatar will be a unique
color (chosen at randrom from a small set of neutral colors) and
have a billboard with their name hovering above their head.

  .. figure:: ../images/HelloCollaborator.png
      :name: fig:CollaboratorInParaView
      :width: 90%
      :align: center

      A collaborator waving hello.

When collaboration is enabled, the CAVEInteraction plugin panel will
include a section dedicated to configuring your connection to the
collaboration server.

  .. figure:: ../images/CollaborationPanel.png
      :name: fig:ConfiguringCollaboration
      :width: 80%
      :align: center

      The collaboration configuration panel.

The first thing to note about the collaboration panel is the checkbox
that enables/disables collaboration.  In the ``CAVEInteraction`` plugin,
collaboration is handled by the existing event loop, and as such, you
begin and end collaborating using the normal ``Start`` and ``Stop``
buttons described above (assuming the ``Collaboration`` checkbox is
checked).  This is different from the ``XRInterface`` plugin, where you
must take separate action to connect to the collaboration server when
you are already interacting with your data in XR.

In addition to enabling/disabling collaboration, the panel also allows
you specify the hostname (or IP address) and port of the collaboration
server, the name of a session to join, and your own name (visible to
collaborators on a billboard over your avatars head).  Once this
information is entered and you click ``Start``, you will be collaborating
with all users who connect to the same server/port and specify the same
session.

Another property you can configure in the panel is the default avatar up
vector.  In ParaView the default camera is oriented with the positive Y
axis pointing up, the positive X axis pointing to your right, and the
positive Z axis pointing out of the screen at you.  If your data is
oriented in such a way that this orientation makes sense, you can leave
the default avatar up vector alone.  However, if your data is oriented
differently, the default avatar up vector allows you to configure the
up direction for new avatars joining your collaboration session.

The collaboration section of the ``CAVEInteraction`` plugin panel also
contains an area for output messages indicating users who have joined
or left the collaboration session.

If you don't see the collaboration panel and you built ParaView yourself,
check your build configuration to make sure it is enabled.

Avatar Configuration
--------------------

The last bit of configuration required for collaboration is to tell
ParaView how to communicate your personal orientation to collaborators.
Recall that you configured some number of trackers when you were using
"VR Connections" section of the panel.  In order to collaborate with
others, you must configure which of those trackers should be associated
with your head and hands.

  .. figure:: ../images/ConfigureAvatarEvents.png
      :name: fig:ConfiguringAvatarEvents
      :width: 60%
      :align: center

      The avatar configuration dialog.

The figure above shows the avatar configuration dialog in scenario
where we have configured a single connection named ``vrconn`` with
three separate trackers named ``puck``, ``controller1``, and
``controller2``.  The event named ``vrconn.puck`` is the one being
used for head tracking, and as such, it has been associated with the
avatar head.  The events named ``vrconn.controller1`` and
``vrconn.controller2`` have been associated with the left and right
hand, respectively, since those are being used as wands with
buttons and valuators for triggering various interactions.

It is not required to have avatar hands configured.  In this case,
your avatar will be displayed to collaborators with unconfigured
hands missing.  Configuring a head, however, is required.

You may notice the "Share Navigation" checkbox in the avatar configuration
dialog.  If this box is left unchecked, collaborators will only see
the tracked positions of your head and hands within the confines of
your physical space.  If you check the "Share Navigation" checkbox,
then collaborators will see not only your tracked head and hand
positions, but also see any navigation you perform via your interactors
as they use the ``SetNavigationMatrix`` method described above.

Collaboration Server
--------------------

Kitware hosts a collaboration server instance for demonstration and
testing purposes, it's the one configured by default when you load
the ``CAVEInteraction plugin`` (located at ``vrserver.kitware.com``).
However, the collaboration server is an open source project that is
hosted `here <https://gitlab.kitware.com/paraview/collaboration-server>`_.

You can build the server yourself, following the instructions in the
projects ``README.md``, and then deploy it within your own network.
Additionally, the server is included in Linux binary downloads of the
ParaView application, available from Kitwares download
`website <https://www.paraview.org/download/>`_.

Saving and Restoring State
^^^^^^^^^^^^^^^^^^^^^^^^^^

The CAVEInteraction plugin supports saving its own state (file extension
``.pvvr``), as well as saving all its state in a ParaView state file
(extension ``.pvsm``).

Whether using the two buttons at the bottom of the CAVEInteraction panel
to save CAVEInteraction-specific state, or using ParaViews File menu to
save CAVEInteraction-specific state along with the rest of the ParaView
state, all aspects of the plugin state are saved.  This includes all
information about connections, interactions (including the Python file,
in the case of a Python interactor style proxy), and collaboration.
