Hi!
I am trying to have a clip plane in a vtkVolume. The weird thing is that clipping the volume in RemoteView works completely as expected using my slider. I can scroll through and works perfectly. It is only when I try using LocalView that it stops working.
Here is the most minimal example I can produce for it:
from trame.app import get_server
from trame.decorators import TrameApp, change
from trame.widgets import vuetify, vtk as vtk_widgets
from trame.ui.vuetify import SinglePageLayout
import vtk
from vtkmodules.vtkFiltersSources import vtkConeSource
from vtkmodules.vtkRenderingCore import (
vtkRenderer,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkPolyDataMapper,
vtkActor,
)
from vtkmodules.vtkCommonDataModel import vtkPlane
from vtkmodules.vtkFiltersCore import vtkClipPolyData
# VTK factory initialization
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleSwitch # noqa
import vtkmodules.vtkRenderingOpenGL2 # noqa
server = get_server(client_type="vue2")
state, ctrl = server.state, server.controller
# -----------------------------------------------------------------------------
origin = 0
reader = vtk.vtkDICOMImageReader()
reader.SetDirectoryName("./dicomfolder")
reader.Update()
# Mapper
volume_mapper = vtk.vtkFixedPointVolumeRayCastMapper()
volume_mapper.SetInputConnection(reader.GetOutputPort())
# Volume properties
volume_property = vtk.vtkVolumeProperty()
color : vtk.vtkColorTransferFunction = vtk.vtkColorTransferFunction()
color.AddRGBPoint(0, 0.0, 0.0, 0.0)
color.AddRGBPoint(255, 1.0, 1.0, 1.0)
volume_property.SetColor(color)
# Causes darker regions to become partially transparent
opacity_func : vtk.vtkPiecewiseFunction = vtk.vtkPiecewiseFunction()
opacity_func.AddPoint(0, 0.0)
opacity_func.AddPoint(255, 1.0)
volume_property.SetScalarOpacity(opacity_func)
# Volume Actor
volume = vtk.vtkVolume()
volume.SetMapper(volume_mapper)
volume.SetProperty(volume_property)
# Create a vtkPlane. Adjust the origin and normal as needed.
clip_plane = vtk.vtkPlane()
clip_plane.SetOrigin(219, 0, 0)
clip_plane.SetNormal(1, 0, 0)
# Add the clip plane to the volume mapper.
volume_mapper.AddClippingPlane(clip_plane)
renderer = vtkRenderer()
renderer.AddVolume(volume) # Add the DICOM volume to the scene
renderWindow = vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindow.OffScreenRenderingOn()
renderWindowInteractor = vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
renderer.ResetCamera()
renderWindow.Render()
@state.change("origin")
def on_origin_change(origin, **kwargs):
print("New plane origin: ", origin)
clip_plane.SetOrigin(origin, 0, 0)
ctrl.view_update()
def reset_origin():
origin = 0
with SinglePageLayout(server) as layout:
layout.title.set_text("Trame demo")
with layout.toolbar as toolbar:
toolbar.dense = True
vuetify.VSpacer()
vuetify.VSlider(
v_model=("origin", 0),
min=0,
max=500,
step=1,
hide_details=True,
style="max-width: 300px;",
)
with vuetify.VBtn(icon=True, click=reset_origin):
vuetify.VIcon("mdi-lock-reset")
with vuetify.VBtn(icon=True, click=ctrl.view_reset_camera):
vuetify.VIcon("mdi-crop-free")
with layout.content:
with vuetify.VContainer(fluid=True, classes="pa-0 fill-height"):
view = vtk_widgets.VtkLocalView(renderWindow)
ctrl.view_update = view.update
ctrl.view_reset_camera = view.reset_camera
def main(**kwargs):
server.start()
if __name__ == "__main__":
main()
Why is this happening? Is there a way to have local rendering?