Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volume rendering is broken #44

Closed
banesullivan opened this issue Jul 2, 2023 · 10 comments
Closed

Volume rendering is broken #44

banesullivan opened this issue Jul 2, 2023 · 10 comments

Comments

@banesullivan
Copy link
Contributor

I can't get volume rendering to work with any client-side views right now

"""Validate volume rendering with VTK.js."""

import pyvista as pv
import numpy as np
from trame.app import get_server
from trame.ui.vuetify import SinglePageLayout
from trame.widgets import vuetify, html
from trame.widgets.vtk import VtkLocalView, VtkRemoteView

# Just for using this script in testing
from trame_client.utils.testing import enable_testing

server = enable_testing(get_server(), "local_rendering_ready")
state, ctrl = server.state, server.controller

state.trame__title = "Volume Validation"
state.local_rendering_ready = 0

# -----------------------------------------------------------------------------

image = pv.Wavelet()

plotter = pv.Plotter(off_screen=True)
actor = plotter.add_volume(image)
plotter.reset_camera()


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

with SinglePageLayout(server) as layout:
    layout.icon.click = ctrl.view_reset_camera
    layout.title.set_text(state.trame__title)

    with layout.toolbar:
        vuetify.VSpacer()
        html.Div("{{ local_rendering_ready }}", classes="readyCount")

    with layout.content:
        with vuetify.VContainer(
            fluid=True,
            classes="pa-0 fill-height",
        ):
            with vuetify.VCol(classes="fill-height"):
                view = VtkLocalView(
                    plotter.ren_win,
                    on_ready="local_rendering_ready++",
                )
                ctrl.view_update = view.update
                ctrl.view_reset_camera = view.reset_camera
            with vuetify.VCol(classes="fill-height"):
                VtkRemoteView(plotter.ren_win)

    # hide footer
    layout.footer.hide()

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

if __name__ == "__main__":
    server.start()
@banesullivan
Copy link
Contributor Author

Seeing this in JS console:

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'set')
    at Object.r [as registerInstance] (trame-vtk.js:3450:72118)
    at trame-vtk.js:3450:64758
    at Array.forEach (<anonymous>)
    at Object.ut [as update] (trame-vtk.js:3450:64568)
    at ts (trame-vtk.js:3450:63650)
    at trame-vtk.js:3450:64781
    at Array.forEach (<anonymous>)
    at ut (trame-vtk.js:3450:64568)
    at Object.oM [as update] (trame-vtk.js:3450:65403)
    at ts (trame-vtk.js:3450:63650)

@banesullivan
Copy link
Contributor Author

This was a browser caching issue. All seems to be working now

@jourdain jourdain reopened this Jul 14, 2023
@jourdain
Copy link
Collaborator

No builder for vtkSmartVolumeMapper

@jourdain
Copy link
Collaborator

Fixed the error by adding an alias but the rendering is still empty...

@jourdain
Copy link
Collaborator

Any reason for 2 fields with a weird one set at setScalars?

{
					"parent": "000000013df054a0",
					"id": "000000013df054a0-dataset",
					"type": "vtkImageData",
					"properties": {
						"spacing": [1.0, 1.0, 1.0],
						"origin": [0.0, 0.0, 0.0],
						"extent": [-10, 10, -10, 10, -10, 10],
						"direction": [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0],
						"fields": [{
							"hash": "d42f855c14d32707570a50f67ab96952_9261f",
							"vtkClass": "vtkDataArray",
							"name": "RTData",
							"dataType": "Float32Array",
							"numberOfComponents": 1,
							"size": 9261,
							"ranges": [{
								"min": 37.35310363769531,
								"max": 276.8288269042969,
								"component": null
							}],
							"location": "pointData",
							"registration": "addArray"
						}, {
							"hash": "8f1bb27011e27e1f5d3ea5798bd2b93a_9261f",
							"vtkClass": "vtkDataArray",
							"name": "Data",
							"dataType": "Float32Array",
							"numberOfComponents": 1,
							"size": 9261,
							"ranges": [{
								"min": 0.0,
								"max": 255.0,
								"component": null
							}],
							"location": "pointData",
							"registration": "setScalars"
						}]
					}
				}

@jourdain
Copy link
Collaborator

Seems to be a blend of PyVista and trame-vtk expectation.

As I remember, the vtkSmartVolumeMapper prevent us to grab proper info from the concrete mapper. At some point you did something to override the vtkSmartVolumeMapper by a concrete one within PyVista...

@jourdain
Copy link
Collaborator

The VTK volume rendering example is working.

@banesullivan
Copy link
Contributor Author

Which example? Is it using vtkFixedPointVolumeRayCastMapper because that is the only volume mapper class I can get to work with the current serializer. vtkOpenGLGPUVolumeRayCastMapper, vtkGPUVolumeRayCastMapper, and vtkSmartVolumeMapper are all failing

@banesullivan
Copy link
Contributor Author

Here is a pure VTK wxample:

import vtk

from trame.app import get_server
from trame.ui.vuetify import SinglePageLayout
from trame.widgets import vuetify
from trame.widgets.vtk import VtkLocalView, VtkRemoteView

server = get_server()
state, ctrl = server.state, server.controller

state.trame__title = "VTK Volume Rendering"

# -----------------------------------------------------------------------------
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.GetInteractorStyle().SetCurrentStyleToTrackballCamera()

source = vtk.vtkRTAnalyticSource()
source.Update()
# mapper = vtk.vtkFixedPointVolumeRayCastMapper()  # works!
# mapper = vtk.vtkSmartVolumeMapper()  # fails!
# mapper = vtk.vtkOpenGLGPUVolumeRayCastMapper()  # fails
mapper = vtk.vtkGPUVolumeRayCastMapper()  # fails
mapper.SetInputConnection(source.GetOutputPort())
actor = vtk.vtkVolume()
actor.SetMapper(mapper)
actor.GetProperty().SetScalarOpacityUnitDistance(10)
ren.AddActor(actor)

colorTransferFunction = vtk.vtkColorTransferFunction()
colorTransferFunction.AddRGBPoint(0.0, 0.0, 0.0, 0.0)
colorTransferFunction.AddRGBPoint(64.0, 1.0, 0.0, 0.0)
colorTransferFunction.AddRGBPoint(128.0, 0.0, 0.0, 1.0)
colorTransferFunction.AddRGBPoint(192.0, 0.0, 1.0, 0.0)
colorTransferFunction.AddRGBPoint(255.0, 0.0, 0.2, 0.0)

opacityTransferFunction = vtk.vtkPiecewiseFunction()
opacityTransferFunction.AddPoint(20, 0.0)
opacityTransferFunction.AddPoint(255, 0.2)

volumeProperty = vtk.vtkVolumeProperty()
volumeProperty.SetColor(colorTransferFunction)
volumeProperty.SetScalarOpacity(opacityTransferFunction)
volumeProperty.ShadeOn()
volumeProperty.SetInterpolationTypeToLinear()

actor.SetProperty(volumeProperty)

cube = vtk.vtkCubeAxesActor()
cube.SetCamera(ren.GetActiveCamera())
cube.SetBounds(source.GetOutput().GetBounds())
ren.AddActor(cube)

iren.Initialize()
ren.ResetCamera()
ren.SetBackground(0.7, 0.7, 0.7)
renWin.Render()


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

with SinglePageLayout(server) as layout:
    layout.icon.click = ctrl.view_reset_camera
    layout.title.set_text(state.trame__title)

    with layout.toolbar:
        vuetify.VSpacer()

    with layout.content:
        with vuetify.VContainer(
            fluid=True,
            classes="pa-0 fill-height",
        ):
            with vuetify.VContainer(fluid=True, classes="pa-0 fill-height", style="width: 50%;"):
                local = VtkLocalView(renWin)
            with vuetify.VContainer(fluid=True, classes="pa-0 fill-height", style="width: 50%;"):
                remote = VtkRemoteView(renWin)

    # hide footer
    layout.footer.hide()

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

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

@jourdain
Copy link
Collaborator

Yes just tested vtkFixedPointVolumeRayCastMapper

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants