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

.. only:: html

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

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

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

.. _sphx_glr_gallery_scene_instanced_mesh_visual.py:


Instanced Mesh Visual
=====================

Show usage of the InstancedMesh visual and its filters.

.. GENERATED FROM PYTHON SOURCE LINES 13-109



.. image-sg:: /gallery/scene/images/sphx_glr_instanced_mesh_visual_001.png
   :alt: instanced mesh visual
   :srcset: /gallery/scene/images/sphx_glr_instanced_mesh_visual_001.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 Out:

 .. code-block:: none

    Downloading data from https://raw.githubusercontent.com/vispy/demo-data/main/spot/spot.obj.gz (106 kB)

    [........................                ] 60.53854 | downloading   
    [........................................] 100.00000 / downloading   
    File saved as /tmp/tmp.NVC9tXepCc/.vispy/data/spot/spot.obj.gz.
    Downloading data from https://raw.githubusercontent.com/vispy/demo-data/main/spot/spot.png (77 kB)

    [.................................       ] 83.27425 | downloading   
    [........................................] 100.00000 / downloading   
    File saved as /tmp/tmp.NVC9tXepCc/.vispy/data/spot/spot.png.






|

.. code-block:: default


    from itertools import cycle

    import numpy as np
    from scipy.spatial.transform import Rotation
    from vispy import app, scene, use
    from vispy.io import imread, load_data_file, read_mesh
    from vispy.scene.visuals import InstancedMesh
    from vispy.visuals.filters import InstancedShadingFilter, WireframeFilter, TextureFilter

    # needed for instanced rendering to work
    use(gl='gl+')


    mesh_path = load_data_file('spot/spot.obj.gz')
    texture_path = load_data_file('spot/spot.png')
    vertices, faces, normals, texcoords = read_mesh(mesh_path)
    texture = np.flipud(imread(texture_path))

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

    view.camera = 'arcball'
    view.camera.depth_value = 10 * (vertices.max() - vertices.min())

    n_instances = 100

    instance_colors = np.random.rand(n_instances, 3).astype(np.float32)
    instance_positions = ((np.random.rand(n_instances, 3) - 0.5) * 10).astype(np.float32)
    face_colors = np.random.rand(len(faces), 3)
    instance_transforms = Rotation.random(n_instances).as_matrix().astype(np.float32)

    # Create a colored `MeshVisual`.
    mesh = InstancedMesh(
        vertices,
        faces,
        instance_colors=instance_colors,
        face_colors=face_colors,
        instance_positions=instance_positions,
        instance_transforms=instance_transforms,
        parent=view.scene,
    )


    wireframe_filter = WireframeFilter(width=1)
    shading_filter = InstancedShadingFilter('smooth', shininess=1)
    texture_filter = TextureFilter(texture, texcoords)
    mesh.attach(wireframe_filter)
    mesh.attach(shading_filter)
    mesh.attach(texture_filter)


    def attach_headlight(view):
        light_dir = (0, 1, 0, 0)
        shading_filter.light_dir = light_dir[:3]
        initial_light_dir = view.camera.transform.imap(light_dir)

        @view.scene.transform.changed.connect
        def on_transform_change(event):
            transform = view.camera.transform
            shading_filter.light_dir = transform.map(initial_light_dir)[:3]


    attach_headlight(view)


    shading_cycle = cycle(['flat', None, 'smooth'])
    color_cycle = cycle([None, instance_colors])
    face_color_cycle = cycle([None, face_colors])


    @canvas.events.key_press.connect
    def on_key_press(event):
        if event.key == "t":
            texture_filter.enabled = not texture_filter.enabled
            canvas.update()
        if event.key == 's':
            shading_filter.shading = next(shading_cycle)
            canvas.update()
        if event.key == 'c':
            mesh.instance_colors = next(color_cycle)
            canvas.update()
        if event.key == 'f':
            mesh.set_data(
                vertices=vertices,
                faces=faces,
                face_colors=next(face_color_cycle),
            )
            canvas.update()
        if event.key == 'w':
            wireframe_filter.enabled = not wireframe_filter.enabled
            canvas.update()


    if __name__ == "__main__":
        app.run()


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

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


.. _sphx_glr_download_gallery_scene_instanced_mesh_visual.py:


.. only :: html

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



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

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



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

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


.. only:: html

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

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