Instanced Mesh Visual#

Show usage of the InstancedMesh visual and its filters.

instanced mesh visual
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()

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

Gallery generated by Sphinx-Gallery