silx
silx copied to clipboard
Enable the synchronization of multiple plot3d.SceneWidget's viewpoint
There is no way from the public API to synchronize the viewpoint of multiple SceneWidgets and that is missing.
The following code provides a SyncCameras class that does the job by doing the synchronization at the viewport's camera level.
Alternative approaches are:
- Add a signal to
SceneWidgetfor camera updates and a method to set the camera. - Add an object in the public API to control the camera.
import sys
import numpy
from silx.gui import qt
from silx.gui.plot3d.SceneWindow import SceneWindow, items
qapp = qt.QApplication.instance() or qt.QApplication([])
# Create two SceneWindow widgets
def create_plot3d():
window = SceneWindow()
sceneWidget = window.getSceneWidget()
x, y, z = numpy.meshgrid(numpy.linspace(-10, 10, 64),
numpy.linspace(-10, 10, 64),
numpy.linspace(-10, 10, 64))
data = numpy.sin(x * y * z) / (x * y * z)
volume = sceneWidget.addVolume(data)
volume.addIsosurface(0.2, '#FF000080')
return window
window1 = create_plot3d()
window2 = create_plot3d()
window3 = create_plot3d()
# Synchronize the 2 cameras
class SyncCameras:
"""Synchronize direction and position of the camera between multiple SceneWidgets
:param List[~silx.gui.plot3d.SceneWidget.SceneWidget] sceneWidgets:
"""
def __init__(self, *sceneWidgets):
self.__cameras = [sw.viewport.camera for sw in sceneWidgets]
self.__updating = False
for camera in self.__cameras:
camera.addListener(self._camera_changed)
def _camera_changed(self, source):
"""Camera changes listener"""
if self.__updating:
return
self.__updating = True
position = source.extrinsic.position
direction = source.extrinsic.direction
up = source.extrinsic.up
for camera in self.__cameras:
if camera is source:
continue
if not (numpy.array_equal(direction, camera.extrinsic.direction) and
numpy.array_equal(up, camera.extrinsic.up)):
camera.extrinsic.setOrientation(direction, up)
if not numpy.array_equal(position, camera.extrinsic.position):
camera.extrinsic.position = position
self.__updating = False
sync_cam = SyncCameras(
window1.getSceneWidget(),
window2.getSceneWidget(),
window3.getSceneWidget())
# Run example
window1.show()
window2.show()
window3.show()
sys.excepthook = qt.exceptionHandler
qapp.exec_()