def __init__(self, ren, title='DIPY', size=(300, 300), png_magnify=1, reset_camera=True, order_transparent=False, interactor_style='custom'): """ Manages the visualization pipeline Parameters ---------- ren : Renderer() or vtkRenderer() The scene that holds all the actors. title : string A string for the window title bar. size : (int, int) ``(width, height)`` of the window. Default is (300, 300). png_magnify : int Number of times to magnify the screenshot. This can be used to save high resolution screenshots when pressing 's' inside the window. reset_camera : bool Default is True. You can change this option to False if you want to keep the camera as set before calling this function. order_transparent : bool True is useful when you want to order transparent actors according to their relative position to the camera. The default option which is False will order the actors according to the order of their addition to the Renderer(). interactor_style : str or vtkInteractorStyle If str then if 'trackball' then vtkInteractorStyleTrackballCamera() is used, if 'image' then vtkInteractorStyleImage() is used (no rotation) or if 'custom' then CustomInteractorStyle is used. Otherwise you can input your own interactor style. Attributes ---------- ren : vtkRenderer() iren : vtkRenderWindowInteractor() style : vtkInteractorStyle() window : vtkRenderWindow() Methods ------- initialize() render() start() add_window_callback() Notes ----- Default interaction keys for * 3d navigation are with left, middle and right mouse dragging * resetting the camera press 'r' * saving a screenshot press 's' * for quiting press 'q' Examples -------- >>> from dipy.viz import actor, window >>> renderer = window.Renderer() >>> renderer.add(actor.axes()) >>> showm = window.ShowManager(renderer) >>> # showm.initialize() >>> # showm.render() >>> # showm.start() """ self.ren = ren self.title = title self.size = size self.png_magnify = png_magnify self.reset_camera = reset_camera self.order_transparent = order_transparent self.interactor_style = interactor_style if self.reset_camera: self.ren.ResetCamera() self.window = vtk.vtkRenderWindow() self.window.AddRenderer(ren) if self.title == 'DIPY': self.window.SetWindowName(title + ' ' + dipy_version) else: self.window.SetWindowName(title) self.window.SetSize(size[0], size[1]) if self.order_transparent: # Use a render window with alpha bits # as default is 0 (false)) self.window.SetAlphaBitPlanes(True) # Force to not pick a framebuffer with a multisample buffer # (default is 8) self.window.SetMultiSamples(0) # Choose to use depth peeling (if supported) # (default is 0 (false)): self.ren.UseDepthPeelingOn() # Set depth peeling parameters # Set the maximum number of rendering passes (default is 4) ren.SetMaximumNumberOfPeels(4) # Set the occlusion ratio (initial value is 0.0, exact image): ren.SetOcclusionRatio(0.0) if self.interactor_style == 'image': self.style = vtk.vtkInteractorStyleImage() elif self.interactor_style == 'trackball': self.style = vtk.vtkInteractorStyleTrackballCamera() elif self.interactor_style == 'custom': self.style = CustomInteractorStyle() else: self.style = interactor_style self.iren = vtk.vtkRenderWindowInteractor() self.style.SetCurrentRenderer(self.ren) # Hack: below, we explicitly call the Python version of SetInteractor. self.style.SetInteractor(self.iren) self.iren.SetInteractorStyle(self.style) self.iren.SetRenderWindow(self.window)
def initialize_scene(self): self.ren = window.Renderer() self.iren = CustomInteractorStyle() self.show_m = window.ShowManager(self.ren, size=self.screen_size, interactor_style=self.iren) # Add clustering panel to the scene. self.clustering_panel = self._make_clustering_panel() self.clustering_panel.set_visibility(False) self.ren.add(self.clustering_panel) # Add "Reset/Home" button def reset_button_callback(iren, obj, button): # iren: CustomInteractorStyle # obj: vtkActor picked # button: Button2D print("Merging remaining bundles...") streamlines = nib.streamlines.ArraySequence() for k, bundle in self.bundles.items(): streamlines.extend(bundle.streamlines) self.remove_bundle(k) if len(streamlines) == 0: print("No streamlines left to merge.") iren.force_render() iren.event.abort() # Stop propagating the event. return # Add new root bundle to the scene. self.add_bundle(self.root_bundle, Bundle(streamlines)) self._add_bundle_right_click_callback( self.bundles[self.root_bundle], self.root_bundle) self.select(None) print("{} streamlines merged.".format(len(streamlines))) button.color = (1, 1, 1) # Restore color. iren.force_render() iren.event.abort() # Stop propagating the event. reset_button = gui_2d.Button2D( icon_fnames={'reset': read_viz_icons(fname='home3_neg.png')}) reset_button.color = (1, 1, 1) reset_button.add_callback("LeftButtonPressEvent", animate_button_callback) reset_button.add_callback("LeftButtonReleaseEvent", reset_button_callback) reset_button.set_center( (self.screen_size[0] - 20, self.screen_size[1] - 60)) self.ren.add(reset_button) # Add toggle "Centroid/Streamlines" button def centroids_toggle_button_callback(iren, obj, button): if button.current_icon_name == "streamlines": button.next_icon() for bundle in self.bundles.values(): bundle.show_centroids() bundle.hide_streamlines() elif button.current_icon_name == "centroids": button.next_icon() for bundle in self.bundles.values(): bundle.hide_centroids() bundle.show_streamlines() iren.force_render() iren.event.abort() # Stop propagating the event. centroids_toggle_button = gui_2d.Button2D( icon_fnames={ 'streamlines': read_viz_icons(fname='database_neg.png'), 'centroids': read_viz_icons(fname='centroid_neg.png') }) centroids_toggle_button.color = (1, 1, 1) # centroids_toggle_button.add_callback("LeftButtonPressEvent", animate_button_callback) centroids_toggle_button.add_callback("LeftButtonReleaseEvent", centroids_toggle_button_callback) centroids_toggle_button.set_center((20, self.screen_size[1] - 20)) self.ren.add(centroids_toggle_button) # Add objects to the scene. self.ren.add(self.bundles[self.root_bundle]) self._add_bundle_right_click_callback(self.bundles[self.root_bundle], self.root_bundle) # Add shortcut keys. def select_biggest_cluster_onchar_callback(iren, evt_name): if self.verbose: print("Pressed {} (shift={}), (ctrl={}), (alt={})".format( iren.event.key, iren.event.shift_key, iren.event.ctrl_key, iren.event.alt_key)) if iren.event.key.lower() == "escape": self.select(None) elif "tab" in iren.event.key.lower(): if iren.event.shift_key: self.select_previous() else: self.select_next() elif iren.event.key == "c": for bundle in self.bundles.values(): bundle.show_centroids() bundle.hide_streamlines() iren.force_render() elif iren.event.key == "C": for bundle in self.bundles.values(): bundle.hide_centroids() bundle.show_streamlines() iren.force_render() iren.event.abort() # Stop propagating the event. self.iren.AddObserver("CharEvent", select_biggest_cluster_onchar_callback) # Add anatomy, if there is one. if self.anat is not None: anat_data = self.anat.get_data() if anat_data.ndim == 4: # Take b0 (assuming it is diffusion data) anat_data = anat_data[..., 0] self.anat_axial_slicer = actor.slicer(anat_data, affine=self.anat.affine) self.anat_coronal_slicer = actor.slicer(anat_data, affine=self.anat.affine) self.anat_sagittal_slicer = actor.slicer(anat_data, affine=self.anat.affine) self.ren.add(self.anat_axial_slicer, self.anat_coronal_slicer, self.anat_sagittal_slicer) self.anatomy_panel = self._make_anatomy_panel( self.anat_axial_slicer, self.anat_coronal_slicer, self.anat_sagittal_slicer) self.ren.add(self.anatomy_panel)