enthought / mayavi

3D visualization of scientific data in Python
http://docs.enthought.com/mayavi/mayavi/
Other
1.32k stars 285 forks source link

on_mouse_pick give me random wrong position #906

Open dz3264 opened 4 years ago

dz3264 commented 4 years ago

I am trying to use Mayavi with trait to build an application. However the on_mouse_pick function always give me wrong position and it cannot obtain the object I clicked on at all.

I draw many 3d points with mlab.points3d method. For example, I click on the point A with position (30, 50, 1), but when I use on_mouse_pick to click on that point, the pick value is random position like (124, 289, 19). There is no any relation between my click point with the picker position. (Just like shown in figures below, I click on red star, but on_mouse_pick gives the position at the white ball)

屏幕快照 2020-04-08 20 57 44 屏幕快照 2020-04-08 20 57 37

Only if I zoom extremely close and click, the position may be close.

屏幕快照 2020-04-08 20 57 59

And I also found that, when the more I zoom out, the picker position farther to the click position. I think they're maybe some relations between zoom and on_mouse_pick but I cannot figure it out.

Also the famous red ball example cannot work at all. http://docs.enthought.com/mayavi/mayavi/auto/example_select_red_balls.html

Also I tried on_mouse_pick(self.picker_callback, type='cell') and type='world', they are not work at all. BTW I am with python 3.7, Mayavi 4.7.1, traits 6.0.0, VTK 8.1.2.

Here is part of my code related with on_mouse_pick

class Visualization(HasTraits):
    time = Range(100, 149,1)
    scene      = Instance(MlabSceneModel, ())

    def __init__(self):
        # Do not forget to call the parent's __init__

        HasTraits.__init__(self)
        self.data = get_my_data(100)

        self.plot_th = self.scene.mlab.points3d(self.data[0], self.data[1], self.data[2], self self.data th_data[3], colormap="hot", scale_factor=1.5, reset_zoom=False)

    @on_trait_change('scene.activated')
    def set_click(self):
        self.figure = mlab.gcf(engine=self.scene.engine)
        picker = self.figure.on_mouse_pick(self.picker_callback)
        picker.tolerance = 1

    def picker_callback(self,picker):
        print('pick --> ',picker)

     view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
                             height=800, width=800, show_label=False),
                        HGroup(
                            '_', 'time',
                        ),
    )

visualization = Visualization()
visualization.configure_traits()

How should I fix this one? I appreciate anyone's help.

laagveen commented 4 years ago

I happen to been trying to this myself with a surface plot and first I got similar results but I got it working in the end. So maybe my observations can help you.

I am plotting a surface z (2d float array) which is indexed as (x, y)

self.surf2 = surf(self.z, extent=(0, 1, 0, 1, 0, 1), colormap='jet')

First of I am using a lower tolerance

self.scene.picker.tolerance = 0.0025

What i noticed was the following.

Firstly the picker_obj can contain multiple actors but i only found one point_id. It seems the point_id is valid for the first actor in the array. So I first check if the _vtk_obj object of my surface plot is the same as the _vtk_obj of first actor in the picker array.

Secondly i played around with the order of x and y in the unravel function. I think that the underlying vtk data is tranposed but i am not sure. This seems to work.

The following call back returns the correct index into my surface data z.

    def picker_callback(self, picker_obj):
        picked = picker_obj.actors
        if len(picked) == 0:
            return

        if self.surf2.actor.actor._vtk_obj == picked[0]._vtk_obj:
            # m.mlab_source.points is the points array underlying the vtk
            # dataset. GetPointId return the index in this array.
            y_, x_ = np.lib.index_tricks.unravel_index(picker_obj.point_id, (self.z.shape[1], self.z.shape[0]))
            return x_, y_ # correct index into z array
weilindong666 commented 1 year ago

I meet the same problem. do you solve it now?