Clip Planes¶

You can use clip planes to transect the voxel-based volume rendering. This notebook is similar to the advanced clip planes notebook.

In [1]:
from ipyniivue import NiiVue
import ipywidgets as widgets
from IPython.display import display

nv = NiiVue()

nv.load_volumes([{"path": "../images/mni152.nii.gz"}])
nv.opts.mesh_xray = 0.02
nv.set_slice_type("RENDER")

## Widget properties

cutaway_check = widgets.Checkbox(value=False, description="Cutaway")


def on_cutaway_change(change):
    """Set cutaway"""
    if change["new"]:
        nv.set_cutaway(True)
    else:
        nv.set_cutaway(False)


cutaway_check.observe(on_cutaway_change, names="value")


planes_options = ["0", "1", "2", "3", "4", "5", "6"]


planes_dropdown = widgets.Dropdown(
    options=planes_options,
    value="2",
    description="Planes:",
)


def on_planes_change(change):
    """Set clipping planes based on dropdown selection."""
    new_value = int(change["new"])  # Convert string to int, like JS parseInt
    planes = [[2.0, 180, 20]]  # default
    match new_value:
        case 1:
            planes = [[0.1, 180, 20]]
        case 2:
            planes = [
                [0.1, 180, 20],
                [0.1, 0, -20],
            ]
        case 3:
            planes = [
                [0.0, 90, 0],   # right center
                [0.0, 0, -20],  # posterior oblique
                [0.1, 0, -90],  # inferior
            ]
        case 4:
            planes = [
                [0.3, 270, 0],  # left
                [0.3, 90, 0],   # right
                [0.0, 180, 0],  # anterior
                [0.1, 0, 0],    # posterior
            ]
        case 5:
            planes = [
                [0.4, 270, 0],  # left
                [0.4, 90, 0],   # right
                [0.4, 180, 0],  # anterior
                [0.2, 0, 0],    # posterior
                [0.1, 0, -90],  # inferior
            ]
        case 6:
            planes = [
                [0.4, 270, 0],  # left
                [-0.1, 90, 0],  # right
                [0.4, 180, 0],  # anterior
                [0.2, 0, 0],    # posterior
                [0.1, 0, -90],  # inferior
                [0.3, 0, 90],   # superior
            ]
        case _:
            # optional explicit default, if you want clarity
            planes = [[2.0, 180, 20]]

    nv.set_clip_planes(planes)



planes_dropdown.observe(on_planes_change, names="value")


shade_options = {"none", "outside", "inside"}


shade_dropdown = widgets.Dropdown(
    options=shade_options,
    value="outside",  # Default shader
    description="Shade:",
)


def on_shade_change(change):
    """Set planes."""
    new_value = change["new"]
    clr = list(nv.opts.clip_plane_color)
    match new_value:
        case "none":
            clr[3] = 0     
        case "outside":
            clr[3] = 0.5
        case "inside":
            clr[3] = -0.5
    nv.set_clip_plane_color(clr)


shade_dropdown.observe(on_shade_change, names="value")

nv.set_clip_planes([[0.1, 180, 20], [0.1, 0, -20]])

## Display

controls = widgets.HBox([planes_dropdown, shade_dropdown, cutaway_check])


## Show widgets and view

display(controls)
display(nv)
In [ ]:
 
In [ ]: