Skip to content

Issues with WebGPU Backend and RenderPointsAsSpheresOn #42

@abhinavsns

Description

@abhinavsns

I am trying to render points as spheres using VTKLocal but it doensn't work. I saw a couple of posts saying WebGL will not support those features so I tried webGPU but still no luck. Can anyone confirm this works or how to check if WebGPU is being used?

Modified cone.py minimal example

from trame.app import get_server
from trame.ui.html import DivLayout
from trame.widgets import html, client
from trame_vtklocal.widgets import vtklocal
from trame.decorators import TrameApp, change, trigger

from vtkmodules.vtkFiltersSources import vtkConeSource
from vtkmodules.vtkRenderingCore import (
    vtkActor,
    vtkPolyDataMapper,
    vtkRenderer,
    vtkRenderWindow,
    vtkRenderWindowInteractor,
)

# Required for vtk factory
import vtkmodules.vtkRenderingOpenGL2  # noqa
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch  # noqa

CLIENT_TYPE = "vue3"

# -----------------------------------------------------------------------------
# VTK pipeline
# -----------------------------------------------------------------------------


def create_vtk_pipeline():
    renderer = vtkRenderer()
    renderWindow = vtkRenderWindow()
    renderWindow.AddRenderer(renderer)

    renderWindowInteractor = vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)
    renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()

    cone = vtkConeSource()

    mapper = vtkPolyDataMapper()
    mapper.SetInputConnection(cone.GetOutputPort())

    actor = vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().SetRepresentationToPoints()
    actor.GetProperty().SetPointSize(15)
    actor.GetProperty().RenderPointsAsSpheresOn()
    actor.GetProperty().SetOpacity(1.0)

    renderer.AddActor(actor)
    renderer.SetBackground(0.1, 0.2, 0.4)
    renderer.ResetCamera()

    return renderWindow, cone, actor


# -----------------------------------------------------------------------------
# GUI
# -----------------------------------------------------------------------------


@TrameApp()
class DemoApp:
    def __init__(self, server=None):
        self.server = get_server(server, client_type=CLIENT_TYPE)

        self.render_window, self.cone, self.actor = create_vtk_pipeline()
        self.server.state.update(dict(mem_blob=0, mem_vtk=0))
        self.html_view = None
        self.ui = self._ui()
        # print(self.ui)

    @trigger("export")
    def export(self, format):
        return self.html_view.export(format)

    def reset_camera(self):
        self.html_view.reset_camera()

    @change("resolution")
    def on_resolution_change(self, resolution, **kwargs):
        self.cone.SetResolution(int(resolution))
        self.html_view.update_throttle()

    @change("opacity")
    def on_opacity_change(self, opacity, **kwargs):
        self.actor.property.opacity = float(opacity)
        self.html_view.update_throttle()

    def _ui(self):
        with DivLayout(self.server) as layout:
            client.Style("body { margin: 0; }")
            with html.Div(
                style="position: absolute; left: 0; top: 0; width: 100vw; height: 100vh;"
            ):
                self.html_view = vtklocal.LocalView(
                    self.render_window,
                    throttle_rate=20,
                    cache_size=("cache", 0),
                    memory_vtk="mem_vtk = $event",
                    memory_arrays="mem_blob = $event",
                    config="{rendering: 'webgpu'}",
                )
            html.Div(
                "Scene: {{ (mem_vtk / 1024).toFixed(1) }}KB - "
                "Arrays: {{ (mem_blob / 1024).toFixed(1) }}KB - "
                "cache: {{ (cache/1024).toFixed(1) }}KB ",
                style=(
                    "position: absolute; top: 1rem; left: 1rem;"
                    "z-index: 10; background: white;"
                    "padding: 1rem; border-radius: 1rem;"
                ),
            )
            html.Input(
                type="range",
                v_model=("resolution", 6),
                min=3,
                max=60,
                step=1,
                style="position: absolute; top: 1rem; right: 1rem; z-index: 10;",
            )
            html.Input(
                type="range",
                v_model=("opacity", 1),
                min=0.01,
                max=1,
                step=0.01,
                style="position: absolute; top: 5rem; right: 1rem; z-index: 10;",
            )
            html.Input(
                type="range",
                v_model=("cache", 0),
                min=0,
                max=100000,
                step=1000,
                style="position: absolute; top: 1rem; right: 10rem; z-index: 10;",
            )
            html.Button(
                "Export json",
                click="utils.download('scene-wasm.json', trigger('export', ['json']), 'application/octet-stream')",
                style="position: absolute; top: 3rem; right: 1rem; z-index: 10;",
            )
            html.Button(
                "Export zip",
                click="utils.download('scene-wasm.zip', trigger('export', ['zip']), 'application/octet-stream')",
                style="position: absolute; top: 3rem; right: 7rem; z-index: 10;",
            )
            html.Button(
                "Reset Camera",
                click=self.reset_camera,
                style="position: absolute; top: 3rem; right: 14rem; z-index: 10;",
            )

        return layout


# -----------------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------------

if __name__ == "__main__":
    app = DemoApp()
    app.server.start()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions