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

.. only:: html

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

        :ref:`Go to the end <sphx_glr_download_tutorial_06_vtk_d_wasm.py>`
        to download the full example code. or to run this example in your browser via Binder

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

.. _sphx_glr_tutorial_06_vtk_d_wasm.py:


VTK + WASM
~~~~~~~~~~

Use WASM local rendering. This requires VTK version greater than 9.3:

.. code-block:: bash

    pip install --extra-index-url https://wheels.vtk.org vtk>=9.3

.. GENERATED FROM PYTHON SOURCE LINES 12-33

.. code-block:: Python


    # Required for vtk factory
    from trame.app import get_server
    from trame.decorators import TrameApp, change
    from trame.ui.vuetify3 import SinglePageLayout
    from trame.widgets import vuetify3 as vuetify
    from trame.widgets.vtk import VtkRemoteView
    from trame_vtklocal.widgets import vtklocal
    from vtkmodules.vtkCommonColor import vtkNamedColors
    from vtkmodules.vtkFiltersCore import vtkElevationFilter, vtkGlyph3D
    from vtkmodules.vtkFiltersSources import vtkConeSource, vtkCubeSource, vtkSphereSource
    from vtkmodules.vtkImagingCore import vtkRTAnalyticSource
    from vtkmodules.vtkImagingGeneral import vtkImageGradient
    from vtkmodules.vtkRenderingCore import (
        vtkActor,
        vtkPolyDataMapper,
        vtkRenderer,
        vtkRenderWindow,
        vtkRenderWindowInteractor,
    )


.. GENERATED FROM PYTHON SOURCE LINES 34-121

.. code-block:: Python



    def setup_vtk():  # noqa: PLR0915
        colors = vtkNamedColors()

        # The Wavelet Source is nice for generating a test vtkImageData set
        rt = vtkRTAnalyticSource()
        rt.SetWholeExtent(-2, 2, -2, 2, 0, 0)

        # Take the gradient of the only scalar 'RTData' to get a vector attribute
        grad = vtkImageGradient()
        grad.SetDimensionality(3)
        grad.SetInputConnection(rt.GetOutputPort())

        # Elevation just to generate another scalar attribute that varies nicely over the data range
        elev = vtkElevationFilter()
        # Elevation values will range from 0 to 1 between the Low and High Points
        elev.SetLowPoint(-2, -2, 0)
        elev.SetHighPoint(2, 2, 0)
        elev.SetInputConnection(grad.GetOutputPort())

        # Create simple PolyData for glyph table
        cs = vtkCubeSource()
        cs.SetXLength(0.5)
        cs.SetYLength(1)
        cs.SetZLength(2)
        ss = vtkSphereSource()
        ss.SetRadius(0.25)
        cs2 = vtkConeSource()
        cs2.SetRadius(0.25)
        cs2.SetHeight(0.5)

        # Set up the glyph filter
        glyph = vtkGlyph3D()
        glyph.SetInputConnection(elev.GetOutputPort())

        # Here is where we build the glyph table
        # that will be indexed into according to the IndexMode
        glyph.SetSourceConnection(0, cs.GetOutputPort())
        glyph.SetSourceConnection(1, ss.GetOutputPort())
        glyph.SetSourceConnection(2, cs2.GetOutputPort())

        glyph.ScalingOn()
        glyph.SetScaleModeToScaleByScalar()
        glyph.SetVectorModeToUseVector()
        glyph.OrientOn()
        glyph.SetScaleFactor(1)  # Overall scaling factor
        glyph.SetRange(0, 1)  # Default is (0,1)

        # Tell it to index into the glyph table according to scalars
        glyph.SetIndexModeToScalar()

        # Tell glyph which attribute arrays to use for what
        glyph.SetInputArrayToProcess(0, 0, 0, 0, "Elevation")  # scalars
        glyph.SetInputArrayToProcess(1, 0, 0, 0, "RTDataGradient")  # vectors

        coloring_by = "Elevation"
        mapper = vtkPolyDataMapper()
        mapper.SetInputConnection(glyph.GetOutputPort())
        mapper.SetScalarModeToUsePointFieldData()
        mapper.SetColorModeToMapScalars()
        mapper.ScalarVisibilityOn()

        # GetRange() call doesn't work because attributes weren't copied to glyphs
        # as they should have been...
        # mapper.SetScalarRange(glyph.GetOutputDataObject(0).GetPointData().GetArray(coloring_by).GetRange())

        mapper.SelectColorArray(coloring_by)
        actor = vtkActor()
        actor.SetMapper(mapper)

        ren = vtkRenderer()
        ren.AddActor(actor)
        ren.SetBackground(colors.GetColor3d("DarkGray"))

        renWin = vtkRenderWindow()  # noqa: N806
        renWin.AddRenderer(ren)

        renderWindowInteractor = vtkRenderWindowInteractor()  # noqa: N806
        renderWindowInteractor.SetRenderWindow(renWin)
        renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()

        ren.ResetCamera()

        return renWin, ren, cs2, ss



.. GENERATED FROM PYTHON SOURCE LINES 122-190

.. code-block:: Python



    @TrameApp()
    class App:
        def __init__(self, server=None) -> None:
            self.server = get_server(server, client_type="vue3")
            self.render_window, self.renderer, self.cone, self.sphere = setup_vtk()
            self.view_local = None
            self.view_remote = None
            self.ui = self._build_ui()

        @property
        def ctrl(self):
            return self.server.controller

        @change("resolution")
        def on_resolution_change(self, resolution, **kwargs) -> None:
            self.cone.SetResolution(int(resolution))
            self.sphere.SetStartTheta(int(resolution) * 6)
            self.view_remote.update()
            self.view_local.update()

        def reset_camera(self) -> None:
            self.renderer.ResetCamera()
            self.view_local.update()
            self.view_remote.update()

        def _build_ui(self):
            with SinglePageLayout(self.server) as layout:
                layout.icon.click = self.reset_camera
                with layout.toolbar:
                    vuetify.VSpacer()
                    vuetify.VSlider(
                        v_model=("resolution", 6),
                        min=3,
                        max=60,
                        step=1,
                        dense=True,
                        hide_details=True,
                    )
                    vuetify.VBtn("Update", click=self.ctrl.view_update)

                with (
                    layout.content,
                    vuetify.VContainer(
                        fluid=True,
                        classes="pa-0 fill-height",
                    ),
                ):
                    with vuetify.VContainer(
                        fluid=True, classes="pa-0 fill-height", style="width: 50%;"
                    ):
                        self.view_local = vtklocal.LocalView(
                            self.render_window,
                            eager_sync=True,
                        )
                        self.ctrl.view_update = self.view_local.update
                    with vuetify.VContainer(
                        fluid=True, classes="pa-0 fill-height", style="width: 50%;"
                    ):
                        self.view_remote = VtkRemoteView(self.render_window, interactive_ratio=1)

                # hide footer
                layout.footer.hide()

                return layout



.. GENERATED FROM PYTHON SOURCE LINES 191-194

.. code-block:: Python

    app = App("wasm")
    await app.ui.ready


.. GENERATED FROM PYTHON SOURCE LINES 195-197

Make sure to give room for the download of WASM bundle
Only needed at first execution

.. GENERATED FROM PYTHON SOURCE LINES 197-201

.. code-block:: Python

    import asyncio

    await asyncio.sleep(1)


.. GENERATED FROM PYTHON SOURCE LINES 202-203

.. code-block:: Python

    app.ui


.. _sphx_glr_download_tutorial_06_vtk_d_wasm.py:

.. only:: html

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

    .. container:: binder-badge

      .. image:: images/binder_badge_logo.svg
        :target: https://mybinder.org/v2/gh/pyvista/pyvista-tutorial/gh-pages?urlpath=lab/tree/notebooks/tutorial/06_vtk/d_wasm.ipynb
        :alt: Launch binder
        :width: 150 px

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

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

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

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

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: d_wasm.zip <d_wasm.zip>`


.. only:: html

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

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