Hi everyone!
I am trying to figure out a way to pick (by clicking on) a specific InstancedMesh. I've worked out an example based on a simplification of existing examples, which uses visual_at to get the InstanceMesh clicked. However, this seems to return the object of InstancedMesh but I can not figure out a way to get which instance of that InstanceMesh it is. Is there a way to accomplish that?
# -*- coding: utf-8 -*-
# vispy: gallery 30
# -----------------------------------------------------------------------------
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
# -----------------------------------------------------------------------------
"""
Instanced Mesh Visual
=====================
Show usage of the InstancedMesh visual and its filters.
"""
from vispy.scene import transforms
from itertools import cycle
import argparse
import numpy as np
from scipy.spatial.transform import Rotation
from vispy import app, scene, use, color
from vispy.io import imread, load_data_file, read_mesh
from vispy.scene.visuals import InstancedMesh, Mesh
from vispy.visuals.filters import InstancedShadingFilter, WireframeFilter, TextureFilter, ShadingFilter, FacePickingFilter
# 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)
vertices_d, faces_d, normals_d, texcoords_d = 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 = 8
n_instances_d = 8
# instance_colors = np.random.rand(n_instances, 3).astype(np.float32)
instance_colors = np.array(
[color.Color("#%06x" % np.random.randint(0, 0xFFFFFF)).rgba for _ in range(n_instances)]
)
instance_positions = ((np.random.rand(n_instances, 3) - 0.5) ).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,
)
#Creating a second InstancedMesh
mesh_d = InstancedMesh(
vertices_d,
faces_d,
instance_colors=instance_colors,
face_colors=face_colors,
instance_positions=instance_positions,
instance_transforms=instance_transforms,
parent=view.scene,
)
mesh_d.transform = transforms.MatrixTransform()
mesh_d.transform.rotate(90, (1, 0, 0))
wireframe_filter = WireframeFilter(width=1)
mesh.attach(wireframe_filter)
mesh_d.interactive = True
mesh.interactive = True
shading_cycle = cycle(['flat', None, 'smooth'])
color_cycle = cycle([None, instance_colors])
face_color_cycle = cycle([None, face_colors])
@canvas.events.mouse_press.connect
def mouse_press(event):
visual = canvas.visual_at(event.pos)
print(visual)
if __name__ == "__main__":
app.run()
Hi everyone! I am trying to figure out a way to pick (by clicking on) a specific InstancedMesh. I've worked out an example based on a simplification of existing examples, which uses visual_at to get the InstanceMesh clicked. However, this seems to return the object of InstancedMesh but I can not figure out a way to get which instance of that InstanceMesh it is. Is there a way to accomplish that?
Thanks,