Updating VTKVolume based on widgets in tab

Hi all,

I am trying to create a RadioBoxGroup button that has values X, Y, Z and 3D and links to the focalPoint in camera in the VTKVolume object (see the last example in https://panel.holoviz.org/reference/panes/VTKVolume.html).

Say I call the RadioBoxGroup “View”, then I’d want something along the lines of:

@pn.depends(“camera’, watch=True)
def view_func(target, event):
if event == “X”:
focal_point = [90, 0, 0]
elif event == “Y”:
focal_point = [0, 90, 0]
elif event == “Z”:
focal_point = [0, 0, 90]
target.camera = “{” + f"focalPoint: {focal_point}” + “}”

Any help would be much appreciated.

you can do something like that:

import panel as pn
pn.extension('vtk')

import numpy as np

data_matrix = np.zeros([75, 75, 75], dtype=np.uint8)
data_matrix[0:35, 0:35, 0:35] = 50
data_matrix[25:55, 25:55, 25:55] = 100
data_matrix[45:74, 45:74, 45:74] = 150

vtkvol = pn.pane.VTKVolume(data_matrix, sizing_mode='stretch_width', height=400,
                           spacing=(3,2,1), interpolation='nearest',
                           edge_gradient=0, sampling=0, controller_expanded=False)

toggle = pn.widgets.ToggleGroup(options=[None, "X", "Y", "Z"], behavior="radio")
initial_focal_point = None
@pn.depends(value=toggle)
def change_camera(value):
    global initial_focal_point
    if vtkvol.camera is not None:
        if initial_focal_point is None:
            initial_focal_point = vtkvol.camera["focalPoint"]
        if value=="X":
            fp = [90, 0, 0]
        elif value=="Y":
            fp = [0, 90, 0]
        elif value=="Z":
            fp = [0, 0, 90]

        if value is not None:
            vtkvol.camera = {"focalPoint": fp}
        else:
            vtkvol.camera = {"focalPoint": initial_focal_point}

pn.Row(vtkvol, toggle, change_camera)

However I suppose your are looking for maybe something more like that:

import panel as pn
pn.extension('vtk')

import numpy as np

data_matrix = np.zeros([75, 75, 75], dtype=np.uint8)
data_matrix[0:35, 0:35, 0:35] = 50
data_matrix[25:55, 25:55, 25:55] = 100
data_matrix[45:74, 45:74, 45:74] = 150

def major_axis(view_up, idxa, idxb):
    axis = np.asarray([0, 0, 0])
    idx = idxa if np.abs(view_up[idxa]) > np.abs(view_up[idxb]) else idxb
    value = 1 if view_up[idx] > 0 else -1
    axis[idx] = value
    return axis



vtkvol = pn.pane.VTKVolume(data_matrix, sizing_mode='stretch_width', height=400,
                           spacing=(3,2,1), interpolation='nearest',
                           edge_gradient=0, sampling=0, controller_expanded=False,
                           orientation_widget=True, interactive_orientation_widget=False)

toggle = pn.widgets.ToggleGroup(options=[None, "X", "Y", "Z"])
initial_camera = None
@pn.depends(value=toggle)
def change_camera(value):
    toggle.value = []
    global initial_camera
    if vtkvol.camera is not None and value:
        if initial_camera is None:
            initial_camera = dict(vtkvol.camera)
            initial_camera.pop('mtime')
        
        if value[0] is not None:
            focal_point = np.asarray(vtkvol.camera['focalPoint'])
            position = np.asarray(vtkvol.camera['position'])
            view_up = np.asarray(vtkvol.camera['viewUp'])

            distance = np.sqrt(((position - focal_point)**2).sum())

            if value[0]=="X":
                direction = np.asarray([1, 0, 0])
            elif value[0]=="Y":
                direction = np.asarray([0, 1, 0])
            elif value[0]=="Z":
                direction = np.asarray([0, 0, 1])

            new_camera = {"position": (focal_point+direction*distance).tolist()}
            if direction[0]:
                view_up = major_axis(view_up, 1, 2).tolist()
            if direction[1]:
                view_up = major_axis(view_up, 0, 2).tolist()
            if direction[2]:
                view_up = major_axis(view_up, 0, 1).tolist()
            new_camera.update({"focalPoint": focal_point, "viewUp": view_up})
            vtkvol.camera = new_camera
        else:
            vtkvol.camera=dict(initial_camera)

pn.Row(vtkvol, toggle, change_camera)