Makie | volumeslices!: combining synchronized rotation, etc. with sliders and toggles

Hello,

I adapted the following code to synchronize rotations, translations, and zoom between two 3D LScene volumeslices! at in the MNWE code below:

https://discourse.julialang.org/t/makie-linking-cameras-in-multiple-3d-plots/83309/7

I then added sliders and toggles and encountered an issue.

The original startup display:

After rotation:

After changing the displayed slices by moving a slider bar:

The issue: the 3D display on the right [or left] reverts to its original orientation after changing the displayed slices using the slider bar.

If I then click on one of the 3D displays it switches to the orientation of the other image.

Q: How can I prevent the reversion in orientation in the 3D displays when moving a slider bar?

The MNWE code:

# test_synchronize_LScene_3D.jl

using GLMakie
using Random

# Ref. https://discourse.julialang.org/t/makie-linking-cameras-in-multiple-3d-plots/83309/7
function link_cameras_lscene(f; step=.01)
  scenes = filter(x -> x isa LScene, f.content)
  cameras = map(x -> cameracontrols(x.scene), scenes)
  n_cameras = length(cameras)

  for i ∈ 1:n_cameras
    on(cameras[i].eyeposition) do eye
      for j ∈ 1:n_cameras
        i == j && continue
        if sum(abs, eye - cameras[j].eyeposition[]) > step
          update_cam!(scenes[j].scene, cameras[i])
        end
      end
    end
  end

  return f
end

function test_lscene()
    f = Figure()

    n_rows = 10
    n_cols = 10
    n_slcs = 10

    axs_1 = LScene(
        f[1, 1:2], 
        scenekw = (;
                aspect = :data,
                backgroundcolor = :white,
                camera = cam3d!,
                center = true,
                clear = true,
                raw = false
        )
    )

    x = LinRange(1, n_rows, n_rows)
    y = LinRange(1, n_cols, n_cols)
    z = LinRange(1, n_slcs, n_slcs)

    alpha = 0.7

    plt_1 = volumeslices!(
        axs_1,
        x, y, z,
        randn(5 * n_rows, 5 * n_cols, 5 * n_slcs),
        alpha = alpha,
        bbox_visible = true,
        colormap = :thermal,
        lowclip = :transparent,
        space = :data,
        transparency = true
    )

    axs_2 = LScene(
        f[1, 3:4],
        scenekw = (;
                aspect = :data,
                backgroundcolor = :white,
                camera = cam3d!,
                center = true,
                clear = true,
                raw = false
        )
    )

    plt_2 = volumeslices!(
        axs_2,
        x, y, z,
        randn(5 * n_rows, 5 * n_cols, 5 * n_slcs),
        alpha = alpha,
        bbox_visible = true,
        colormap = :viridis,
        lowclip = :transparent,
        space = :data,
        transparency = true
    )

    # Sliders
    dspl_sldr_grid = SliderGrid(
        f[2, 2:3],
        (label = "Sagittal - yz plane", range = 1:length(x)),
        (label = "Coronal - xz plane", range = 1:length(y)),
        (label = "Axial - xy plane", range = 1:length(z)),
    )

    dspl_sldr_layout = dspl_sldr_grid.layout
    dspl_sldr_n_cols = ncols(dspl_sldr_layout)

    # Connect sliders to `volumeslices`! update methods
    dspl_sl_yz, dspl_sl_xz, dspl_sl_xy = dspl_sldr_grid.sliders

    # Sagittal slider
    on(dspl_sl_yz.value) do v; 
        plt_1[:update_yz][](v)
        plt_2[:update_yz][](v)
    end

    # Coronal slider
    on(dspl_sl_xz.value) do v; 
        plt_1[:update_xz][](v) 
        plt_2[:update_xz][](v)
    end

    # Axial slider
    on(dspl_sl_xy.value) do v;
        plt_1[:update_xy][](v)
        plt_2[:update_xy][](v)
    end

    set_close_to!(dspl_sl_yz, .5length(x))
    set_close_to!(dspl_sl_xz, .5length(y))
    set_close_to!(dspl_sl_xy, .5length(z))

    # Toggles
    # Add toggles to show/hide heatmaps
    hmap_1 = [plt_1[Symbol(:heatmap_, s)][] for s ∈ (:yz, :xz, :xy)]

    toggles_dspl = [Toggle(dspl_sldr_layout[i, dspl_sldr_n_cols + 1], active = true) for i ∈ 1:length(hmap_1)]

    map(zip(hmap_1, toggles_dspl)) do (h, t)
        on(t.active) do active
            h.visible = active
        end
    end

    hmap_2 = [plt_2[Symbol(:heatmap_, s)][] for s ∈ (:yz, :xz, :xy)]

    map(zip(hmap_2, toggles_dspl)) do (h, t)
        on(t.active) do active
            h.visible = active
        end
    end

    resize_to_layout!(f)

    link_cameras_lscene(f)

    wait(display(f))
end

function main()
  test_lscene() 
end

begin
    main()
end

GLMakie version: 0.13.11
Makie version: v0.24.11
Julia version: 1.12.6
Windows 11