Skip to content

Commit

Permalink
chore(volume): Add volume rendering example
Browse files Browse the repository at this point in the history
  • Loading branch information
jourdain committed Jul 14, 2023
1 parent 1ca98ff commit 672b1ad
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 1 deletion.
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ ignore =
per-file-ignores =
# These directories will always contain "from ... import *"
trame/*:F401,F403
examples/*:F401,F403

# Black sometimes conflicts with flake8 here
# Ignore white space after binary operator and assigning lambda expressions
Expand Down
76 changes: 76 additions & 0 deletions examples/validation/PyVistaVolumeRendering.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Validate volume rendering with VTK.js."""
import os
import sys
import pyvista as pv
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

if os.environ.get("PYTEST_CURRENT_TEST") or "--test" in sys.argv:
server = enable_testing(get_server(), "local_rendering_ready")
else:
server = get_server()
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()


def update_local_rendering():
ctrl.view_update()
ctrl.view_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")
vuetify.VBtn("Update", click=update_local_rendering)

with layout.content:
with vuetify.VContainer(
fluid=True,
classes="pa-0 fill-height",
):
with vuetify.VCol(classes="fill-height"):
view = VtkLocalView(
plotter.ren_win,
ref="local",
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,
ref="remote",
)

# hide footer
layout.footer.hide()

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

if __name__ == "__main__":
server.start()
121 changes: 121 additions & 0 deletions examples/validation/VtkRayCast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/usr/bin/env python

# Web imports
from trame.app import get_server
from trame.ui.vuetify import SinglePageLayout
from trame.widgets import vtk, vuetify

# -----------------------------------------------------------------------------
# Example: SimpleRayCast
# taken from: https://kitware.github.io/vtk-examples/site/Python/
# -----------------------------------------------------------------------------

# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle # noqa
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonDataModel import vtkPiecewiseFunction
from vtkmodules.vtkIOLegacy import vtkStructuredPointsReader
from vtkmodules.vtkRenderingCore import (
vtkColorTransferFunction,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer,
vtkVolume,
vtkVolumeProperty,
)
from vtkmodules.vtkRenderingVolume import vtkFixedPointVolumeRayCastMapper

# noinspection PyUnresolvedReferences
from vtkmodules.vtkRenderingVolumeOpenGL2 import (
vtkOpenGLRayCastImageDisplayHelper, # noqa
)

# FIXME
DATA_FILE = "/Users/sebastien.jourdain/Documents/code/web/trame-suite/trame-tutorial/data/ironProt.vtk"

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

colors = vtkNamedColors()

# This is a simple volume rendering example that
# uses a vtkFixedPointVolumeRayCastMapper

# Create the standard renderer, render window
# and interactor.
ren1 = vtkRenderer()

renWin = vtkRenderWindow()
renWin.AddRenderer(ren1)

iren = vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.GetInteractorStyle().SetCurrentStyleToTrackballCamera() # +++

# Create the reader for the data.
reader = vtkStructuredPointsReader()
reader.SetFileName(DATA_FILE)

# Create transfer mapping scalar value to opacity.
opacityTransferFunction = vtkPiecewiseFunction()
opacityTransferFunction.AddPoint(20, 0.0)
opacityTransferFunction.AddPoint(255, 0.2)

# Create transfer mapping scalar value to color.
colorTransferFunction = 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)

# The property describes how the data will look.
volumeProperty = vtkVolumeProperty()
volumeProperty.SetColor(colorTransferFunction)
volumeProperty.SetScalarOpacity(opacityTransferFunction)
volumeProperty.ShadeOn()
volumeProperty.SetInterpolationTypeToLinear()

# The mapper / ray cast function know how to render the data.
volumeMapper = vtkFixedPointVolumeRayCastMapper()
volumeMapper.SetInputConnection(reader.GetOutputPort())

# The volume holds the mapper and the property and
# can be used to position/orient the volume.
volume = vtkVolume()
volume.SetMapper(volumeMapper)
volume.SetProperty(volumeProperty)

ren1.AddVolume(volume)
ren1.SetBackground(colors.GetColor3d("Wheat"))
ren1.GetActiveCamera().Azimuth(45)
ren1.GetActiveCamera().Elevation(30)
ren1.ResetCameraClippingRange()
ren1.ResetCamera()

# -----------------------------------------------------------------------------
# Web Application setup
# -----------------------------------------------------------------------------

server = get_server()
ctrl = server.controller

with SinglePageLayout(server) as layout:
layout.title.set_text("Hello trame")

with layout.content:
with vuetify.VContainer(
fluid=True,
classes="pa-0 fill-height",
):
# view = vtk.VtkRemoteView(renWin)
view = vtk.VtkLocalView(renWin)


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

if __name__ == "__main__":
server.start()
5 changes: 4 additions & 1 deletion trame_vtk/modules/vtk/serializers/initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,10 @@ def initialize_serializers():
"vtkOpenGLPolyDataMapper",
"vtkPolyDataMapper",
],
"vtkVolumeMapper": "vtkFixedPointVolumeRayCastMapper",
"vtkVolumeMapper": [
"vtkFixedPointVolumeRayCastMapper",
"vtkSmartVolumeMapper",
],
"vtkImageData": "vtkStructuredPoints",
}

Expand Down

0 comments on commit 672b1ad

Please sign in to comment.