I'm trying to synchronize the camera view of multiple Image3D
panels displayed within a Manipulate
interface.
A random 3D image will do for demonstration purposes.
theimg = Image3D[RandomReal[1, {20, 30, 40}], ImageSize -> Medium]
Here is the code I have which attempts to synchronize the camera views of two Image3D panels. The code is based upon the StackExchange answers Extract current viewing parameters from a 3D view and Synchronizing manual rotations for multiple Graphics3D outputs.
Options[imgcompare] = {SphericalRegion -> True};
imgcompare[img1_, img2_, opts : OptionsPattern[{imgcompare, Image3D}]] :=
DynamicModule[{vv = {0.0, 0.0, 1.0}, vp = {1.3, -2.4, 2.0}},
Grid[
{{Image3D[img1, opts, Sequence @@ Options[imgcompare],
ViewPoint -> Dynamic[vp], ViewVertical -> Dynamic[vv]],
Image3D[img2, opts, Sequence @@ Options[imgcompare],
ViewPoint -> Dynamic[vp], ViewVertical -> Dynamic[vv]]}}]]
The code works fine outside of a Manipulate
statement as demonstrated by the code below. You can manually rotate one of the 3D images and the other one rotates in synch.
imgcompare[theimg, Binarize[Erosion[theimg, 1]]]
However, synchronization doesn't work if you try to call the function within a Manipulate
statement.
Manipulate[imgcompare[theimg, Binarize[Erosion[theimg, n]]],
{{n, 1, "Erosion"}, 1, 4, 1, SetterBar}]
Initially, the Manipulate
window gives an error. In the message window, the errors given are:
Viewpoint \$CellContext`vp$13957 is not a triple of numbers or a recognized symbolic form.
and
The ViewVertical vector is too short to establish the up direction.
If you inspect the value of the variable vp$13957
(the number part of the variable name changes for each execution of the code), you can see it is undefined (the output just repeats the symbol name). I'm baffled as to how this variable could be undefined as I explicitly initialize vp
and vv
in the DynamicModule
.
Despite the error, if I ignore the error and try to manually rotate one of the images, it seems to work at first and the panels are synchronized.
However, if I click the SetterBar
to change the value, the error returns.
If I again ignore the error and manually rotate one of the panels, the error goes away again, but synchronization is broken. The two panels rotate independently.
Why does the camera view synchronization fail when the imgcompare
function is called within a Manipulate
expression?
Dynamic@DynamicModule[{vp = {2.0, 2.0, 1.}}, Image3D[RandomReal[1, {2, 2, 2}], ViewPoint -> Dynamic[vp]]]
. $\endgroup$Dynamic@DynamicModule[{vp = {2.0, 2.0, 1.}}, Plot3D[Sin[x y], {x, 0, 1}, {y, 0, 1}, ViewPoint -> Dynamic[vp]]]
I don't know what to say... $\endgroup$