enthought / mayavi

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

mayavi smart downsampling for volumetric rendering #225

Open 22csnyder opened 9 years ago

22csnyder commented 9 years ago

Good afternoon,

I am accustomed to calling: ix,iy,iz=np.indicies(src) mlab.pipeline.volume(mlab.pipeline.scalar_field(ix,iy,iz,src))

My new problem is that src is too large. Specifically the np.indicies call runs out of memory, but I suspect the second line would have problems as well.

The obvious solution is to try downsample when the user is zoomed out and show full resolution when the user is zoomed closer in. I'm sure someone has tried to write this before. It might even be literally built into mayavi but I don't know it.

What are my best options for doing this?

Thanks, Chris

dmsurti commented 9 years ago

@22csnyder Assuming you load the src on demand without running out of memory, you can use LODActor.

Setting mlab.USE_LOD_ACTOR=True gives you LOD Actors if you use mlab.

Else, you need to use tvtk.LODActor. For finer control, you will need to use tvtk.LODProp3D.

[1] http://www.vtk.org/doc/nightly/html/classvtkLODActor.html

22csnyder commented 9 years ago

Thanks for the reply. At the moment it is still quite sluggish and I'm not sure if I've done it right. I can get it to render (neigh unresponsively) with the following code that neglects creating a set of indices.

mlab.pipeline.volume(mlab.pipeline.scalar_field(src))

If I add in front of it the line you suggest:

mlab.USE_LOD_ACTOR=True mlab.pipeline.volume(mlab.pipeline.scalar_field(src))

I don't really see any performance difference.

22csnyder commented 9 years ago

I'm going to move this to the mayavi users help email chain group (I've forgotten the name). I've had quite some trouble getting tvtk to play nicely with mayavi for volume rendering. It seems to be in a minority of the examples.

dmsurti commented 9 years ago

@22csnyder As for the performance sluggishness, it is much dependent upon your graphics card. And VTK uses OpenGL's ancient fixed pipeline.

Most modern graphics cards are designed to perform optimally when graphical primitives are stored in graphics memory using vertex buffer objects and when the rendering is performed using specialized shader programs. This is not what is being done as of VTK 6.2.

22csnyder commented 9 years ago

dmsurti,

Thank you very much for your reply, as I've found it difficult to find help on this issue. Do you think that there is a rescue here?

In my mind, even though 99% of what you just said went over my head, it still seems reasonable/feasible that someone would have created an object that acts in the following way:

while sluggish: every_n_strides+=1 new_volume_data_to_display = sample_at( large_data_perhaps_on_disk_worst_case ,\ spacing=every_n_strides) display( volume_data_to_display)

The are two reasons that I'm avoiding resampling the image at several resolutions and coding this myself. 1) I think it would look more professional if the display could more smoothly scroll from a local high-res image to a global low-res one. 2) I don't want to spend the requisite time debugging index checking. I would have several arrays all with different spacings and different origins; bleh.

Thanks again very much, Chris S

dmsurti commented 9 years ago

@22csnyder You will have to write your vtkRenderWindowInteractor implementation where you intercept the events (zoom in, zoom out). In those event handlers, you load the data on-demand and render it. Basically just do what you did in your while block above in a custom window interactor.

http://www.vtk.org/doc/nightly/html/classvtkRenderWindowInteractor.html#details

Hope this helps.

22csnyder commented 9 years ago

I will do my best! Do you have an example of how vtkRenderWindowInteractor hooks into the mayavi Engine or Scene? I think I could do it from the examples if I was programming in vtk alone... but I'm not sure where to go from there.

You've been so helpful. Chris

dmsurti commented 9 years ago

For custom interaction you can see this example here: http://www.vtk.org/gitweb?p=VTK.git;a=blob;f=Examples/GUI/Python/CustomInteraction.py

On same lines, to modify the interaction in Mayavi to handle your own events, you need to add such observers to the interaction which is accessible from TVTK scene [1].

So if you are using say MLab [2], that will be self.scene_model.scene.interactor which gives you the interactor.

[1]https://github.com/enthought/mayavi/blob/master/tvtk/pyface/tvtk_scene.py#L159 [2]https://github.com/enthought/mayavi/blob/master/tvtk/pyface/scene_model.py#L64