Open LunarLanding opened 3 years ago
As a workaround could you use a vtkGlyph3d mapper? https://github.com/holoviz/panel/pull/2027
@xavArtley vtkSphereMapper uses one triangle per sphere (in shader code here https://github.com/Kitware/vtk-js/blob/master/Sources/Rendering/OpenGL/SphereMapper/index.js ) and renders spheres correctly as long as the sphere is fully visible on screen. vtkGlyph3d with a coarse resolution of 8 for both phi and theta will use 64 faces per sphere.
The fps goes from 3fps to 40 fps, details follow below, but using vtkGlyph3D for this does not work.
PS: support for glyph3D mapper was very helpful, and it fills many use cases; I'm trying to expand the usage of pane/vtkjs to some new problems, which lead to this issue.
Measured avg fps on a surface pro 4 (integrated graphics) while rotating and zooming back and forth.
I can predict a lower bound for the performance of vtkSphereMapper by using resolution = 1 for the sphere glyph, which uses 6 faces per glyph. Using the live example gives worse results (with the plane at xy, down from 40fps at (0,0,-1) to 6fps along the (1,1,0) direction), which I attribute to the size of its particles varying orders of magnitude above the minimum radius, which is not the use case of molecular renderings.
vtkGlyph3d with resolution 8 will yield 3fps. Dropping resolution to 5 gives 7fps which is barely ok but now spheres will look like pentagons up close. Dropping resolution to 1 gives 40fps.
Resolution 8:
Resolution 5:
Test code:
import pyvista as pv
import vtk
import panel as pn
pn.extension('vtk')
def make_glyph(N):
Nt = N
Np = N
print(f"~ # of faces in glyph:{Nt*Np=}")
sphereSource2 = vtk.vtkSphereSource()
sphereSource2.SetThetaResolution(Nt)
sphereSource2.SetPhiResolution(Np)
return sphereSource2
def make_grid(N):
sphereSource = vtk.vtkSphereSource()
Nr = int(N**.5)
Nt = Nr
Np = Nr
sphereSource.SetThetaResolution(Nt)
sphereSource.SetPhiResolution(Np)
source = sphereSource
print(f"~ # of glyphs:{Nt*Np=}")
return source
def make_glyph3dMapper(source,glyph):
mapper = vtk.vtkGlyph3DMapper();
mapper.SetInputConnection(source.GetOutputPort())
mapper.SetSourceConnection(glyph.GetOutputPort())
mapper.SetScaleFactor(.01)
mapper.Update()
return mapper
def make_pane(mapper):
actor = vtk.vtkActor();
actor.SetMapper(mapper);
ren = vtk.vtkRenderer()
ren.AddActor(actor)
ren.ResetCamera()
win = vtk.vtkRenderWindow()
win.AddRenderer(ren)
return pn.pane.VTK(win, width=500, height=500)
# resolution = 8 # 3fps
# resolution = 5 # 7fps
resolution = 1 # 40fps
glyph = make_glyph(resolution)
glyph_mapper = vtk.vtkPolyDataMapper();
glyph_mapper.SetInputConnection(glyph.GetOutputPort())
glyph_mapper.Update()
# N = 100
N = int(100e3)
grid = make_grid(N)
pn.Column(*[
make_pane(glyph_mapper),
make_pane(make_glyph3dMapper(grid,glyph)),
])
If understand correctly you would like to use the vtkSphereMapper of vtk.js because it render sphere more efficiently.
The problem is there is no equivalent class on VTK side (vtkSphereMapper does not exist). vtkSphereMapper is just a class around vtkMapper with a radius parameter and a scaleArray, but I don't see wich VTK class could be serialized correctly
On the other side vtkMoleculeMapper does not exist on vtk.js, there is a vtkMolecule class but I don't see how to use it.
May be I can try to serialize a Vtk moleculemapper into a vtkjs spheremapper and stickmapper
I wasn't aware vtkSphereMapper was exclusive to vtk-js. Mapping vtkMoleculeMapper to SphereMapper and StickMapper on vtk-js would solve my use-case. But I understand how that would be harder to implement/maintain. Perhaps I can ask vtk-js to have a MoleculeMapper..
On Sat, 24 Apr 2021, 09:02 Xavier Artusi, @.***> wrote:
May be I can try to serialize a Vtk moleculemapper into a vtkjs spheremapper and stickmapper
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/holoviz/panel/issues/2232#issuecomment-826054208, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABB4J6TNPTHNZPR6DLHM6MDTKJ3JTANCNFSM43OQRMPQ .
ALL software version info
holoviews : 1.14.2 panel: 0.11.1 vtk : 9.0.1 pyvista : 0.29.0 numpy : 1.20.2 python: 3.9.2 jupyter : 3.0.12 OS python runs on: Ubuntu 18.04.5 browser : Firefox 88.0 OS browser runs on : Windows 10
Description of expected behavior and the observed behavior
Make vtkMoleculeMapper, with one atom; add it to a pyvista plot; render it via panel on a jupyter lab notebook Expected image of a sphere, instead get a blank canvas and a javascript error.
Complete, minimal, self-contained example code that reproduces the issue
(blank output)
Stack traceback and/or browser JavaScript console output
Screenshots or screencasts of the bug in action
See code section.
Additional details
It seems panel's serializer for vtk does not support vtkMolecule or vtkMoleculeMapper. If this is too specific a niche usage, the crucial part of this mapper, performance wise, is using vtkSphereMapper, which renders many spheres using a few triangles for each; having support for it would already cover my use-case. I can make a new issue for it if necessary.
vtkMoleculeMapper is implemented in vtk.js by default.
vtk from conda-forge has vtkMolecule and vtkMoleculeMapper classes, however the opengl implementation is not included by default. Therefore in MVE I show the intended output via a screenshot obtained with pyvista.
My use-case calls for rendering efficiently up to 100k spheres; vtkMoleculeMapper uses vtkSphereMapper to render each sphere with a few triangles, which reaches the necessary performance for interactivity. I tested this by editing the input range on their live example here https://kitware.github.io/vtk-js/examples/SphereMapper.html#Live-example