vcolors[:] = np.array(color) utils.update_actor(sphere) color_toggler.on_change = toggle_color ############################################################################### # Show Manager # ============ # # Now that all the elements have been initialised, we add them to the show # manager. current_size = (800, 800) show_manager = window.ShowManager(size=current_size, title="FURY Sphere Example") show_manager.scene.add(sphere) show_manager.scene.add(color_toggler) ############################################################################### # Set camera for better visualization show_manager.scene.reset_camera() show_manager.scene.set_camera(position=(0, 0, 150)) show_manager.scene.reset_clipping_range() show_manager.scene.azimuth(30) interactive = False if interactive: show_manager.start()
def test_ui_line_double_slider_2d(interactive=False): line_double_slider_2d_horizontal_test = ui.LineDoubleSlider2D( center=(300, 300), shape="disk", outer_radius=15, min_value=-10, max_value=10, initial_values=(-10, 10)) npt.assert_equal( line_double_slider_2d_horizontal_test.handles[0].size, (30, 30)) npt.assert_equal( line_double_slider_2d_horizontal_test.left_disk_value, -10) npt.assert_equal( line_double_slider_2d_horizontal_test.right_disk_value, 10) line_double_slider_2d_vertical_test = ui.LineDoubleSlider2D( center=(300, 300), shape="disk", outer_radius=15, min_value=-10, max_value=10, initial_values=(-10, 10)) npt.assert_equal( line_double_slider_2d_vertical_test.handles[0].size, (30, 30)) npt.assert_equal( line_double_slider_2d_vertical_test.bottom_disk_value, -10) npt.assert_equal( line_double_slider_2d_vertical_test.top_disk_value, 10) if interactive: show_manager = window.ShowManager(size=(600, 600), title="FURY Line Double Slider") show_manager.scene.add(line_double_slider_2d_horizontal_test) show_manager.scene.add(line_double_slider_2d_vertical_test) show_manager.start() line_double_slider_2d_horizontal_test = ui.LineDoubleSlider2D( center=(300, 300), shape="square", handle_side=5, orientation="horizontal", initial_values=(50, 40)) npt.assert_equal( line_double_slider_2d_horizontal_test.handles[0].size, (5, 5)) npt.assert_equal( line_double_slider_2d_horizontal_test.left_disk_value, 39) npt.assert_equal( line_double_slider_2d_horizontal_test.right_disk_value, 40) npt.assert_equal( line_double_slider_2d_horizontal_test.left_disk_ratio, 0.39) npt.assert_equal( line_double_slider_2d_horizontal_test.right_disk_ratio, 0.4) line_double_slider_2d_vertical_test = ui.LineDoubleSlider2D( center=(300, 300), shape="square", handle_side=5, orientation="vertical", initial_values=(50, 40)) npt.assert_equal( line_double_slider_2d_vertical_test.handles[0].size, (5, 5)) npt.assert_equal( line_double_slider_2d_vertical_test.bottom_disk_value, 39) npt.assert_equal( line_double_slider_2d_vertical_test.top_disk_value, 40) npt.assert_equal( line_double_slider_2d_vertical_test.bottom_disk_ratio, 0.39) npt.assert_equal( line_double_slider_2d_vertical_test.top_disk_ratio, 0.4) with npt.assert_raises(ValueError): ui.LineDoubleSlider2D(orientation="Not_hor_not_vert") if interactive: show_manager = window.ShowManager(size=(600, 600), title="FURY Line Double Slider") show_manager.scene.add(line_double_slider_2d_horizontal_test) show_manager.scene.add(line_double_slider_2d_vertical_test) show_manager.start()
def test_ui_radio_button_default(interactive=False): filename = "test_ui_radio_button" recording_filename = pjoin(DATA_DIR, filename + ".log.gz") expected_events_counts_filename = pjoin(DATA_DIR, filename + ".json") radio_button_test = ui.RadioButton( labels=["option 1", "option 2\nOption 2", "option 3", "option 4"], position=(10, 10), checked_labels=[]) old_positions = [] for option in radio_button_test.options.values(): old_positions.append(option.position) old_positions = np.asarray(old_positions) radio_button_test.position = (100, 100) new_positions = [] for option in radio_button_test.options.values(): new_positions.append(option.position) new_positions = np.asarray(new_positions) npt.assert_allclose(new_positions - old_positions, 90 * np.ones((4, 2))) selected_option = [] def _on_change(radio_button): selected_option.append(radio_button.checked_labels) # Set up a callback when selection changes radio_button_test.on_change = _on_change event_counter = EventCounter() event_counter.monitor(radio_button_test) # Create a show manager and record/play events. show_manager = window.ShowManager(size=(600, 600), title="FURY Checkbox") show_manager.scene.add(radio_button_test) # Recorded events: # 1. Click on button of option 1. # 2. Click on button of option 2. # 3. Click on button of option 2. # 4. Click on text of option 2. # 5. Click on button of option 1. # 6. Click on text of option 3. # 7. Click on button of option 4. # 8. Click on text of option 4. show_manager.play_events_from_file(recording_filename) expected = EventCounter.load(expected_events_counts_filename) event_counter.check_counts(expected) # Check if the right options were selected. expected = [['option 1'], ['option 2\nOption 2'], ['option 2\nOption 2'], ['option 2\nOption 2'], ['option 1'], ['option 3'], ['option 4'], ['option 4']] npt.assert_equal(len(selected_option), len(expected)) assert_arrays_equal(selected_option, expected) del show_manager if interactive: radio_button_test = ui.RadioButton( labels=["option 1", "option 2\nOption 2", "option 3", "option 4"], position=(100, 100), checked_labels=[]) showm = window.ShowManager(size=(600, 600)) showm.scene.add(radio_button_test) showm.start()
button_right = ui.Button2D(icon_fnames=[ ('square', read_viz_icons(fname='circle-right.png')) ], position=(295, 295), size=(30, 30)) textbox2 = ui.TextBox2D(50, 20, position=(330, 270), text="Element 2" + " " * 8) button_down = ui.Button2D(icon_fnames=[ ('square', read_viz_icons(fname='circle-down.png')) ], position=(295, 265), size=(30, 30)) content = ui.Panel2D(size=(170, 100), color=(1, 1, 1), align="left") content.center = (330, 330) textbox = ui.TextBox2D(50, 10, text="Hello World!!") content.add_element(textbox, (20, 50)) elements = [textbox1, button_right, button_down, content, textbox2, textbox] current_size = (800, 800) show_manager = window.ShowManager(size=current_size, title="Accordion UI Example") for element in elements: show_manager.scene.add(element) show_manager.start()
############################################################################### # Connect the actors with the Scene. scene.add(stream_actor) scene.add(image_actor_z) scene.add(image_actor_x) scene.add(image_actor_y) ############################################################################### # Now we would like to change the position of each ``image_actor`` using a # slider. The sliders are widgets which require access to different areas of # the visualization pipeline and therefore we don't recommend using them with # ``show``. The more appropriate way is to use them with the ``ShowManager`` # object which allows accessing the pipeline in different areas. Here is how: show_m = window.ShowManager(scene, size=(1200, 900)) show_m.initialize() ############################################################################### # After we have initialized the ``ShowManager`` we can go ahead and create # sliders to move the slices and change their opacity. line_slider_z = ui.LineSlider2D(min_value=0, max_value=shape[2] - 1, initial_value=shape[2] / 2, text_template="{value:.0f}", length=140) line_slider_x = ui.LineSlider2D(min_value=0, max_value=shape[0] - 1, initial_value=shape[0] / 2,
rgb[idx, 0] = 1.0 - (onco[idx] - onco_min) / onco_range # rgb[idx,1] = (onco[idx] - onco_min)/onco_range rgb[idx, 1] = rgb[idx, 0] rgb[idx, 2] = 0 elif cycle_model[idx] == 100: rgb[idx, 0] = 1 rgb[idx, 1] = 0 rgb[idx, 2] = 0 elif cycle_model[idx] > 100: rgb[idx, 0] = 0.54 # 139./255 rgb[idx, 1] = 0.27 # 69./255 rgb[idx, 2] = 0.075 # 19./255 #----------------------------- scene = window.Scene() # https://fury.gl/latest/reference/fury.actor.html?highlight=sphere#fury.actor.sphere colors = (1, 0, 0) #sphere_actor = actor.sphere(centers=xyz, colors=colors, radii=1.0) #sphere_actor = actor.sphere(centers=xyz, colors=colors, radii=cell_radii) sphere_actor = actor.sphere(centers=xyz, colors=rgb, radii=cell_radii) scene.add(sphere_actor) showm = window.ShowManager(scene, size=(800, 800), reset_camera=True, order_transparent=False) showm.initialize() showm.start() ## window.record(showm.scene, size=(900, 768), out_path="viz_timer.png")
def test_button_and_slider_widgets(): recording = False filename = "test_button_and_slider_widgets.log.gz" recording_filename = pjoin(DATA_DIR, filename) renderer = window.Renderer() # create some minimalistic streamlines lines = [ np.array([[-1, 0, 0.], [1, 0, 0.]]), np.array([[-1, 1, 0.], [1, 1, 0.]]) ] colors = np.array([[1., 0., 0.], [0.3, 0.7, 0.]]) stream_actor = actor.streamtube(lines, colors) states = { 'camera_button_count': 0, 'plus_button_count': 0, 'minus_button_count': 0, 'slider_moved_count': 0, } renderer.add(stream_actor) # the show manager allows to break the rendering process # in steps so that the widgets can be added properly show_manager = window.ShowManager(renderer, size=(800, 800)) if recording: show_manager.initialize() show_manager.render() def button_callback(obj, event): # print('Camera pressed') states['camera_button_count'] += 1 def button_plus_callback(obj, event): # print('+ pressed') states['plus_button_count'] += 1 def button_minus_callback(obj, event): # print('- pressed') states['minus_button_count'] += 1 fetch_viz_icons() button_png = read_viz_icons(fname='camera.png') button = widget.button(show_manager.iren, show_manager.ren, button_callback, button_png, (.98, 1.), (80, 50)) button_png_plus = read_viz_icons(fname='plus.png') button_plus = widget.button(show_manager.iren, show_manager.ren, button_plus_callback, button_png_plus, (.98, .9), (120, 50)) button_png_minus = read_viz_icons(fname='minus.png') button_minus = widget.button(show_manager.iren, show_manager.ren, button_minus_callback, button_png_minus, (.98, .9), (50, 50)) def print_status(obj, event): rep = obj.GetRepresentation() stream_actor.SetPosition((rep.GetValue(), 0, 0)) states['slider_moved_count'] += 1 slider = widget.slider(show_manager.iren, show_manager.ren, callback=print_status, min_value=-1, max_value=1, value=0., label="X", right_normalized_pos=(.98, 0.6), size=(120, 0), label_format="%0.2lf") # This callback is used to update the buttons/sliders' position # so they can stay on the right side of the window when the window # is being resized. global size size = renderer.GetSize() if recording: show_manager.record_events_to_file(recording_filename) print(states) else: show_manager.play_events_from_file(recording_filename) npt.assert_equal(states["camera_button_count"], 7) npt.assert_equal(states["plus_button_count"], 3) npt.assert_equal(states["minus_button_count"], 4) npt.assert_equal(states["slider_moved_count"], 116) if not recording: button.Off() slider.Off() # Uncomment below to test the slider and button with analyze # button.place(renderer) # slider.place(renderer) report = window.analyze_renderer(renderer) # import pylab as plt # plt.imshow(report.labels, origin='lower') # plt.show() npt.assert_equal(report.actors, 1) report = window.analyze_renderer(renderer) npt.assert_equal(report.actors, 1)
def test_wrong_interactor_style(): panel = ui.Panel2D(size=(300, 150)) dummy_scene = window.Scene() dummy_show_manager = window.ShowManager(dummy_scene, interactor_style='trackball') npt.assert_raises(TypeError, panel.add_to_scene, dummy_scene)
def test_ui_file_menu_2d(interactive=False): filename = "test_ui_file_menu_2d" recording_filename = pjoin(DATA_DIR, filename + ".log.gz") expected_events_counts_filename = pjoin(DATA_DIR, filename + ".pkl") # Create temporary directory and files os.mkdir(os.path.join(os.getcwd(), "testdir")) os.chdir("testdir") os.mkdir(os.path.join(os.getcwd(), "tempdir")) for i in range(10): open(os.path.join(os.getcwd(), "tempdir", "test" + str(i) + ".txt"), 'wt').close() open("testfile.txt", 'wt').close() filemenu = ui.FileMenu2D(size=(500, 500), extensions=["txt"], directory_path=os.getcwd()) # We will collect the sequence of files that have been selected. selected_files = [] def _on_change(): selected_files.append(list(filemenu.listbox.selected)) # Set up a callback when selection changes. filemenu.listbox.on_change = _on_change # Assign the counter callback to every possible event. event_counter = EventCounter() event_counter.monitor(filemenu) # Create a show manager and record/play events. show_manager = window.ShowManager(size=(600, 600), title="FURY FileMenu") show_manager.scene.add(filemenu) # Recorded events: # 1. Click on 'testfile.txt' # 2. Click on 'tempdir/' # 3. Click on 'test0.txt'. # 4. Shift + Click on 'test6.txt'. # 5. Click on '../'. # 2. Click on 'testfile.txt'. show_manager.play_events_from_file(recording_filename) expected = EventCounter.load(expected_events_counts_filename) event_counter.check_counts(expected) # Check if the right files were selected. expected = [["testfile.txt"], ["tempdir"], ["test0.txt"], [ "test0.txt", "test1.txt", "test2.txt", "test3.txt", "test4.txt", "test5.txt", "test6.txt" ], ["../"], ["testfile.txt"]] npt.assert_equal(len(selected_files), len(expected)) assert_arrays_equal(selected_files, expected) # Remove temporary directory and files os.remove("testfile.txt") for i in range(10): os.remove( os.path.join(os.getcwd(), "tempdir", "test" + str(i) + ".txt")) os.rmdir(os.path.join(os.getcwd(), "tempdir")) os.chdir("..") os.rmdir("testdir") if interactive: filemenu = ui.FileMenu2D(size=(500, 500), directory_path=os.getcwd()) show_manager = window.ShowManager(size=(600, 600), title="FURY FileMenu") show_manager.scene.add(filemenu) show_manager.start()
def test_ui_button_panel(recording=False): filename = "test_ui_button_panel" recording_filename = pjoin(DATA_DIR, filename + ".log.gz") expected_events_counts_filename = pjoin(DATA_DIR, filename + ".pkl") # Rectangle rectangle_test = ui.Rectangle2D(size=(10, 10)) another_rectangle_test = ui.Rectangle2D(size=(1, 1)) # Button fetch_viz_icons() icon_files = [] icon_files.append(('stop', read_viz_icons(fname='stop2.png'))) icon_files.append(('play', read_viz_icons(fname='play3.png'))) button_test = ui.Button2D(icon_fnames=icon_files) button_test.center = (20, 20) def make_invisible(i_ren, _obj, button): # i_ren: CustomInteractorStyle # obj: vtkActor picked # button: Button2D button.set_visibility(False) i_ren.force_render() i_ren.event.abort() def modify_button_callback(i_ren, _obj, button): # i_ren: CustomInteractorStyle # obj: vtkActor picked # button: Button2D button.next_icon() i_ren.force_render() button_test.on_right_mouse_button_pressed = make_invisible button_test.on_left_mouse_button_pressed = modify_button_callback button_test.scale((2, 2)) button_color = button_test.color button_test.color = button_color # TextBlock text_block_test = ui.TextBlock2D() text_block_test.message = 'TextBlock' text_block_test.color = (0, 0, 0) # Panel panel = ui.Panel2D(size=(300, 150), position=(290, 15), color=(1, 1, 1), align="right") panel.add_element(rectangle_test, (290, 135)) panel.add_element(button_test, (0.1, 0.1)) panel.add_element(text_block_test, (0.7, 0.7)) npt.assert_raises(ValueError, panel.add_element, another_rectangle_test, (10., 0.5)) npt.assert_raises(ValueError, panel.add_element, another_rectangle_test, (-0.5, 0.5)) # Assign the counter callback to every possible event. event_counter = EventCounter() event_counter.monitor(button_test) event_counter.monitor(panel.background) current_size = (600, 600) show_manager = window.ShowManager(size=current_size, title="FURY Button") show_manager.scene.add(panel) if recording: show_manager.record_events_to_file(recording_filename) print(list(event_counter.events_counts.items())) event_counter.save(expected_events_counts_filename) else: show_manager.play_events_from_file(recording_filename) expected = EventCounter.load(expected_events_counts_filename) event_counter.check_counts(expected)
def test_text_block_2d_justification(): window_size = (700, 700) show_manager = window.ShowManager(size=window_size) # To help visualize the text positions. grid_size = (500, 500) bottom, middle, top = 50, 300, 550 left, center, right = 50, 300, 550 line_color = (1, 0, 0) grid_top = (center, top), (grid_size[0], 1) grid_bottom = (center, bottom), (grid_size[0], 1) grid_left = (left, middle), (1, grid_size[1]) grid_right = (right, middle), (1, grid_size[1]) grid_middle = (center, middle), (grid_size[0], 1) grid_center = (center, middle), (1, grid_size[1]) grid_specs = [ grid_top, grid_bottom, grid_left, grid_right, grid_middle, grid_center ] for spec in grid_specs: line = ui.Rectangle2D(size=spec[1], color=line_color) line.center = spec[0] show_manager.scene.add(line) font_size = 60 bg_color = (1, 1, 1) texts = [] texts += [ ui.TextBlock2D("HH", position=(left, top), font_size=font_size, color=(1, 0, 0), bg_color=bg_color, justification="left", vertical_justification="top") ] texts += [ ui.TextBlock2D("HH", position=(center, top), font_size=font_size, color=(0, 1, 0), bg_color=bg_color, justification="center", vertical_justification="top") ] texts += [ ui.TextBlock2D("HH", position=(right, top), font_size=font_size, color=(0, 0, 1), bg_color=bg_color, justification="right", vertical_justification="top") ] texts += [ ui.TextBlock2D("HH", position=(left, middle), font_size=font_size, color=(1, 1, 0), bg_color=bg_color, justification="left", vertical_justification="middle") ] texts += [ ui.TextBlock2D("HH", position=(center, middle), font_size=font_size, color=(0, 1, 1), bg_color=bg_color, justification="center", vertical_justification="middle") ] texts += [ ui.TextBlock2D("HH", position=(right, middle), font_size=font_size, color=(1, 0, 1), bg_color=bg_color, justification="right", vertical_justification="middle") ] texts += [ ui.TextBlock2D("HH", position=(left, bottom), font_size=font_size, color=(0.5, 0, 1), bg_color=bg_color, justification="left", vertical_justification="bottom") ] texts += [ ui.TextBlock2D("HH", position=(center, bottom), font_size=font_size, color=(1, 0.5, 0), bg_color=bg_color, justification="center", vertical_justification="bottom") ] texts += [ ui.TextBlock2D("HH", position=(right, bottom), font_size=font_size, color=(0, 1, 0.5), bg_color=bg_color, justification="right", vertical_justification="bottom") ] show_manager.scene.add(*texts) # Uncomment this to start the visualisation # show_manager.start() window.snapshot(show_manager.scene, size=window_size, offscreen=True)
slider = ui.LineSlider2D(length=150) listbox = ui.ListBox2D(size=(150, 150), values=['First', 'Second', 'Third']) ############################################################################### # Now, we create grids with different shapes rect_grid = GridLayout(position_offset=(0, 0, 0)) square_grid = GridLayout(cell_shape='square', position_offset=(0, 300, 0)) diagonal_grid = GridLayout(cell_shape="diagonal", position_offset=(0, 600, 0)) ############################################################################### # Applying the grid to the ui elements rect_grid.apply([panel_1, panel_2]) square_grid.apply([listbox_1, listbox_2]) diagonal_grid.apply([slider, listbox]) current_size = (1500, 1500) show_manager = window.ShowManager(size=current_size, title="FURY UI Layout") show_manager.scene.add(panel_1, panel_2, listbox_1, listbox_2, slider, listbox) # To interact with the UI, set interactive = True interactive = False if interactive: show_manager.start() window.record(show_manager.scene, out_path="ui_layout.png", size=(400, 400))
def test_picking_manager(): xyz = 10 * np.random.rand(100, 3) colors = np.random.rand(100, 4) radii = np.random.rand(100) + 0.5 scene = window.Scene() sphere_actor = actor.sphere(centers=xyz, colors=colors, radii=radii) scene.add(sphere_actor) showm = window.ShowManager(scene, size=(900, 768), reset_camera=False, order_transparent=True) showm.initialize() tb = ui.TextBlock2D(bold=True) # use itertools to avoid global variables counter = itertools.count() pickm = pick.PickingManager() record_indices = { 'vertex_indices': [], 'face_indices': [], 'xyz': [], 'actor': [] } def timer_callback(_obj, _event): cnt = next(counter) tb.message = "Let's count up to 15 and exit :" + str(cnt) showm.scene.azimuth(0.05 * cnt) # sphere_actor.GetProperty().SetOpacity(cnt/100.) if cnt % 10 == 0: # pick at position info = pickm.pick((900 / 2, 768 / 2), scene) record_indices['vertex_indices'].append(info['vertex']) record_indices['face_indices'].append(info['face']) record_indices['xyz'].append(info['xyz']) record_indices['actor'].append(info['actor']) showm.render() if cnt == 15: showm.exit() scene.add(tb) # Run every 200 milliseconds showm.add_timer_callback(True, 200, timer_callback) showm.start() assert_greater(np.sum(np.array(record_indices['vertex_indices'])), 1) assert_greater(np.sum(np.array(record_indices['face_indices'])), 1) for ac in record_indices['actor']: if ac is not None: npt.assert_equal(ac is sphere_actor, True) assert_greater( np.sum(np.abs(np.diff(np.array(record_indices['xyz']), axis=0))), 0)
def test_selector_manager(): centers, colors, radii = _get_three_cubes() scene = window.Scene() cube_actor = actor.cube(centers, directions=(1, 0, 2), colors=colors, scales=radii) pts = 100 * (np.random.rand(100, 3) - 0.5) + np.array([20, 0, 0.]) pts_actor = actor.dots(pts, dot_size=10) rgb = 255 * np.ones((400, 400, 3), dtype=np.uint8) tex_actor = actor.texture(rgb) scene.add(cube_actor) scene.add(pts_actor) scene.add(tex_actor) showm = window.ShowManager(scene, size=(900, 768), reset_camera=False, order_transparent=True) showm.initialize() tb = ui.TextBlock2D(bold=True) # use itertools to avoid global variables counter = itertools.count() selm = pick.SelectionManager(select='faces') selm.selectable_off([tex_actor]) selm.selectable_on([tex_actor]) selm.selectable_off([tex_actor]) def timer_callback(_obj, _event): cnt = next(counter) tb.message = "Let's count up to 15 and exit :" + str(cnt) if cnt % 10 == 0: # select large area info_plus = selm.select((900 // 2, 768 // 2), scene, (30, 30)) for info in info_plus.keys(): if info_plus[info]['actor'] in [cube_actor, pts_actor]: npt.assert_(True) else: npt.assert_(False) # select single pixel info_ = selm.pick((900 // 2, 768 // 2), scene) if info_['actor'] in [cube_actor, pts_actor]: npt.assert_(True) else: npt.assert_(False) showm.render() if cnt == 15: showm.exit() pass scene.add(tb) # Run every 200 milliseconds showm.add_timer_callback(True, 200, timer_callback) showm.start()
def main(): parser = _build_arg_parser() args = parser.parse_args() # The number of labels maps must be equal to the number of bundles tmp = args.in_bundles + args.in_labels args.in_labels = args.in_bundles[(len(tmp) // 2):] + args.in_labels args.in_bundles = args.in_bundles[0:len(tmp) // 2] assert_inputs_exist(parser, args.in_bundles + args.in_labels) assert_output_dirs_exist_and_empty(parser, args, [], optional=args.save_rendering) stats = {} num_digits_labels = 3 scene = window.Scene() scene.background(tuple(map(int, args.background))) for i, filename in enumerate(args.in_bundles): sft = load_tractogram_with_reference(parser, args, filename) sft.to_vox() sft.to_corner() img_labels = nib.load(args.in_labels[i]) # same subject: same header or coregistered subjects: same header if not is_header_compatible(sft, args.in_bundles[0]) \ or not is_header_compatible(img_labels, args.in_bundles[0]): parser.error('All headers must be identical.') data_labels = img_labels.get_fdata() bundle_name, _ = os.path.splitext(os.path.basename(filename)) unique_labels = np.unique(data_labels)[1:].astype(int) # Empty bundle should at least return a json if not len(sft): tmp_dict = {} for label in unique_labels: tmp_dict['{}'.format(label).zfill(num_digits_labels)] \ = {'mean': 0.0, 'std': 0.0} stats[bundle_name] = {'diameter': tmp_dict} continue counter = 0 labels_dict = {label: ([], []) for label in unique_labels} pts_labels = map_coordinates(data_labels, sft.streamlines._data.T - 0.5, order=0) # For each label, all positions and directions are needed to get # a tube estimation per label. for streamline in sft.streamlines: direction = np.gradient(streamline, axis=0).tolist() curr_labels = pts_labels[counter:counter + len(streamline)].tolist() for i, label in enumerate(curr_labels): if label > 0: labels_dict[label][0].append(streamline[i]) labels_dict[label][1].append(direction[i]) counter += len(streamline) centroid = np.zeros((len(unique_labels), 3)) radius = np.zeros((len(unique_labels), 1)) error = np.zeros((len(unique_labels), 1)) for key in unique_labels: key = int(key) c, d, e = fit_circle_in_space(labels_dict[key][0], labels_dict[key][1], args.fitting_func) centroid[key - 1], radius[key - 1], error[key - 1] = c, d, e # Spatial smoothing to avoid degenerate estimation centroid_smooth = gaussian_filter(centroid, sigma=[1, 0], mode='nearest') centroid_smooth[::len(centroid) - 1] = centroid[::len(centroid) - 1] radius = gaussian_filter(radius, sigma=1, mode='nearest') error = gaussian_filter(error, sigma=1, mode='nearest') tmp_dict = {} for label in unique_labels: tmp_dict['{}'.format(label).zfill(num_digits_labels)] \ = {'mean': float(radius[label-1])*2, 'std': float(error[label-1])} stats[bundle_name] = {'diameter': tmp_dict} if args.show_rendering or args.save_rendering: tube_actor = create_tube_with_radii( centroid_smooth, radius, error, wireframe=args.wireframe, error_coloring=args.error_coloring) scene.add(tube_actor) cmap = plt.get_cmap('jet') coloring = cmap(pts_labels / np.max(pts_labels))[:, 0:3] streamlines_actor = actor.streamtube(sft.streamlines, linewidth=args.width, opacity=args.opacity, colors=coloring) scene.add(streamlines_actor) slice_actor = actor.slicer(data_labels, np.eye(4)) slice_actor.opacity(0.0) scene.add(slice_actor) # If there's actually streamlines to display if args.show_rendering: showm = window.ShowManager(scene, reset_camera=True) showm.initialize() showm.start() elif args.save_rendering: scene.reset_camera() snapshot(scene, os.path.join(args.save_rendering, 'superior.png'), size=(1920, 1080), offscreen=True) scene.pitch(180) scene.reset_camera() snapshot(scene, os.path.join(args.save_rendering, 'inferior.png'), size=(1920, 1080), offscreen=True) scene.pitch(90) scene.set_camera(view_up=(0, 0, 1)) scene.reset_camera() snapshot(scene, os.path.join(args.save_rendering, 'posterior.png'), size=(1920, 1080), offscreen=True) scene.pitch(180) scene.set_camera(view_up=(0, 0, 1)) scene.reset_camera() snapshot(scene, os.path.join(args.save_rendering, 'anterior.png'), size=(1920, 1080), offscreen=True) scene.yaw(90) scene.reset_camera() snapshot(scene, os.path.join(args.save_rendering, 'right.png'), size=(1920, 1080), offscreen=True) scene.yaw(180) scene.reset_camera() snapshot(scene, os.path.join(args.save_rendering, 'left.png'), size=(1920, 1080), offscreen=True) print(json.dumps(stats, indent=args.indent, sort_keys=args.sort_keys))
def test_grid_ui(interactive=False): vol1 = np.zeros((100, 100, 100)) vol1[25:75, 25:75, 25:75] = 100 colors = distinguishable_colormap(nb_colors=3) contour_actor1 = actor.contour_from_roi(vol1, np.eye(4), colors[0], 1.) vol2 = np.zeros((100, 100, 100)) vol2[25:75, 25:75, 25:75] = 100 contour_actor2 = actor.contour_from_roi(vol2, np.eye(4), colors[1], 1.) vol3 = np.zeros((100, 100, 100)) vol3[25:75, 25:75, 25:75] = 100 contour_actor3 = actor.contour_from_roi(vol3, np.eye(4), colors[2], 1.) scene = window.Scene() actors = [] texts = [] actors.append(contour_actor1) text_actor1 = actor.text_3d('cube 1', justification='center') texts.append(text_actor1) actors.append(contour_actor2) text_actor2 = actor.text_3d('cube 2', justification='center') texts.append(text_actor2) actors.append(contour_actor3) text_actor3 = actor.text_3d('cube 3', justification='center') texts.append(text_actor3) actors.append(shallow_copy(contour_actor1)) text_actor1 = actor.text_3d('cube 4', justification='center') texts.append(text_actor1) actors.append(shallow_copy(contour_actor2)) text_actor2 = actor.text_3d('cube 5', justification='center') texts.append(text_actor2) actors.append(shallow_copy(contour_actor3)) text_actor3 = actor.text_3d('cube 6', justification='center') texts.append(text_actor3) actors.append(shallow_copy(contour_actor1)) text_actor1 = actor.text_3d('cube 7', justification='center') texts.append(text_actor1) actors.append(shallow_copy(contour_actor2)) text_actor2 = actor.text_3d('cube 8', justification='center') texts.append(text_actor2) actors.append(shallow_copy(contour_actor3)) text_actor3 = actor.text_3d('cube 9', justification='center') texts.append(text_actor3) counter = itertools.count() show_m = window.ShowManager(scene) show_m.initialize() def timer_callback(_obj, _event): cnt = next(counter) show_m.scene.zoom(1) show_m.render() if cnt == 10: show_m.exit() # show the grid with the captions grid_ui = ui.GridUI(actors=actors, captions=texts, caption_offset=(0, -50, 0), cell_padding=(60, 60), dim=(3, 3), rotation_axis=(1, 0, 0)) scene.add(grid_ui) show_m.add_timer_callback(True, 200, timer_callback) show_m.start() arr = window.snapshot(scene) report = window.analyze_snapshot(arr) npt.assert_equal(report.objects > 9, True) # this needs to happen automatically when start() ends. for act in actors: act.RemoveAllObservers() filename = "test_grid_ui" recording_filename = pjoin(DATA_DIR, filename + ".log.gz") expected_events_counts_filename = pjoin(DATA_DIR, filename + ".pkl") current_size = (900, 600) scene = window.Scene() show_manager = window.ShowManager(scene, size=current_size, title="FURY GridUI") show_manager.initialize() grid_ui2 = ui.GridUI(actors=actors, captions=texts, caption_offset=(0, -50, 0), cell_padding=(60, 60), dim=(3, 3), rotation_axis=None) scene.add(grid_ui2) event_counter = EventCounter() event_counter.monitor(grid_ui2) if interactive: show_manager.start() recording = False if recording: # Record the following events # 1. Left click on top left box (will rotate the box) show_manager.record_events_to_file(recording_filename) print(list(event_counter.events_counts.items())) event_counter.save(expected_events_counts_filename) else: show_manager.play_events_from_file(recording_filename) expected = EventCounter.load(expected_events_counts_filename) event_counter.check_counts(expected)
scene = window.Scene() camera = scene.camera() scene.add(lines_actor) scene.add(sphere_actor) ############################################################################### # The final step! Visualize the result of our creation! Also, we need to move # the camera a little bit farther from the network. you can increase the # parameter max_iteractions of the timer callback to let the animation run for # more time. showm = window.ShowManager(scene, reset_camera=False, size=(900, 768), order_transparent=True, multi_samples=8) showm.initialize() scene.set_camera(position=(0, 0, -300)) timer_callback = new_layout_timer(showm, edges, vertices_count, max_iterations=200, vertex_initial_positions=positions) # Run every 16 milliseconds showm.add_timer_callback(True, 16, timer_callback)
handle_side=25, range_slider_center=(200, 500), value_slider_center=(200, 400), length=250, min_value=0, max_value=10, font_size=18, range_precision=2, value_precision=4, shape="square") range_slider_ver = ui.RangeSlider(line_width=8, handle_side=25, range_slider_center=(475, 450), value_slider_center=(375, 450), length=250, min_value=0, max_value=10, font_size=18, range_precision=2, value_precision=4, orientation="vertical", shape="square") current_size = (800, 800) show_manager = window.ShowManager(size=current_size, title="Range Sliders Example") show_manager.scene.add(range_slider_hor) show_manager.scene.add(range_slider_ver) show_manager.start()
# Then we can draw a solid circle, or disk. disk = ui.Disk2D(outer_radius=50, center=(400, 200), color=(1, 1, 0)) ############################################################################### # Add an inner radius to make a ring. ring = ui.Disk2D(outer_radius=50, inner_radius=45, center=(500, 600), color=(0, 1, 1)) ############################################################################### # Now that all the elements have been initialised, we add them to the show # manager. current_size = (800, 800) show_manager = window.ShowManager(size=current_size, title="DIPY Shapes Example") show_manager.scene.add(rect) show_manager.scene.add(disk) show_manager.scene.add(ring) interactive = False if interactive: show_manager.start() window.record(show_manager.scene, size=current_size, out_path="viz_shapes.png")
from fury import window, actor, utils, primitive, io, ui from fury.data import read_viz_textures, fetch_viz_textures import itertools import vtk import glob import time import random #reading data output = "output00000000.xml" scene = window.Scene() showm = window.ShowManager(scene, size=(1600, 900), reset_camera=True, order_transparent=True) #%% #function to create sphere actors, this function works for only CRC organoid project mcds=pyMCDS(output) data=mcds.get_cell_df() Types = np.array([mcds.data['discrete_cells']['cell_type']]) Fibro = np.where(Types == 1) #Organoid = np.where(Types == 1) KRAS_positive = np.where(Types == 3) KRAS_negative = np.where(Types == 2)
# ================================== # # Now we create a callback for setting the chosen color. def change_color(combobox): label.color = colors[combobox.selected_text] # `on_change` callback is set to `change_color` method so that # it's called whenever a different option is selected. color_combobox.on_change = change_color ############################################################################### # Show Manager # ================================== # # Now we add label and combobox to the scene. current_size = (400, 400) showm = window.ShowManager(size=current_size, title="ComboBox UI Example") showm.scene.add(label, color_combobox) # To interact with the UI, set interactive = True interactive = False if interactive: showm.start() window.record(showm.scene, out_path="combobox_ui.png", size=(400, 400))
def test_grid(_interactive=False): vol1 = np.zeros((100, 100, 100)) vol1[25:75, 25:75, 25:75] = 100 contour_actor1 = actor.contour_from_roi(vol1, np.eye(4), (1., 0, 0), 1.) vol2 = np.zeros((100, 100, 100)) vol2[25:75, 25:75, 25:75] = 100 contour_actor2 = actor.contour_from_roi(vol2, np.eye(4), (1., 0.5, 0), 1.) vol3 = np.zeros((100, 100, 100)) vol3[25:75, 25:75, 25:75] = 100 contour_actor3 = actor.contour_from_roi(vol3, np.eye(4), (1., 0.5, 0.5), 1.) scene = window.Scene() actors = [] texts = [] actors.append(contour_actor1) text_actor1 = actor.text_3d('cube 1', justification='center') texts.append(text_actor1) actors.append(contour_actor2) text_actor2 = actor.text_3d('cube 2', justification='center') texts.append(text_actor2) actors.append(contour_actor3) text_actor3 = actor.text_3d('cube 3', justification='center') texts.append(text_actor3) actors.append(shallow_copy(contour_actor1)) text_actor1 = 'cube 4' texts.append(text_actor1) actors.append(shallow_copy(contour_actor2)) text_actor2 = 'cube 5' texts.append(text_actor2) actors.append(shallow_copy(contour_actor3)) text_actor3 = 'cube 6' texts.append(text_actor3) # show the grid without the captions container = grid(actors=actors, captions=None, caption_offset=(0, -40, 0), cell_padding=(10, 10), dim=(2, 3)) scene.add(container) scene.projection('orthogonal') counter = itertools.count() show_m = window.ShowManager(scene) show_m.initialize() def timer_callback(_obj, _event): cnt = next(counter) # show_m.scene.zoom(1) show_m.render() if cnt == 4: show_m.exit() show_m.destroy_timers() show_m.add_timer_callback(True, 200, timer_callback) show_m.start() arr = window.snapshot(scene) report = window.analyze_snapshot(arr) npt.assert_equal(report.objects, 6) scene.rm_all() counter = itertools.count() show_m = window.ShowManager(scene) show_m.initialize() # show the grid with the captions container = grid(actors=actors, captions=texts, caption_offset=(0, -50, 0), cell_padding=(10, 10), dim=(3, 3)) scene.add(container) show_m.add_timer_callback(True, 200, timer_callback) show_m.start() arr = window.snapshot(scene) report = window.analyze_snapshot(arr) npt.assert_equal(report.objects > 6, True)
async def test(use_raw_array, ms_stream=16): width_0 = 300 height_0 = 200 centers = np.array([[0, 0, 0], [-1, 0, 0], [1, 0, 0]]) colors = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) actors = actor.sphere(centers, colors=colors, radii=.1) scene = window.Scene() scene.add(actors) showm = window.ShowManager( scene, reset_camera=False, size=(width_0, height_0), order_transparent=False, ) showm.initialize() stream = FuryStreamClient(showm, use_raw_array=use_raw_array, whithout_iren_start=True) stream_interaction = FuryStreamInteraction(max_queue_size=500, showm=showm, use_raw_array=use_raw_array, whithout_iren_start=True) showm.render() # test jpeg method for _ in range(10): stream_interaction.circular_queue.enqueue( np.array([_CQUEUE.event_ids.mouse_weel, 1, 0, 0, 0, 0, .1, 0], dtype='d')) for _ in range(10): stream_interaction.circular_queue.enqueue( np.array([_CQUEUE.event_ids.mouse_weel, -1, 0, 0, 0, 0, .1, 0], dtype='d')) dxs = [] for shift, ctrl in ((0, 1), (1, 0), (0, 0)): x = width_0 / 2 y = height_0 / 2 stream_interaction.circular_queue.enqueue( np.array([ _CQUEUE.event_ids.left_btn_press, 0, x, y, ctrl, shift, .1, 0 ], dtype='d')) for i in range(50): if ctrl == 1: x = x + i / 50 * width_0 / 4 else: if i < 25: dx = +i / 50 dxs.append(dx) x = x - dx else: x = x + dxs[::-1][i - 25] stream_interaction.circular_queue.enqueue( np.array([ _CQUEUE.event_ids.mouse_move, 0, x, y, ctrl, shift, .1, 0 ], dtype='d')) stream_interaction.circular_queue.enqueue( np.array([ _CQUEUE.event_ids.left_btn_release, 0, x, y, ctrl, shift, .1, 0 ], dtype='d')) stream_interaction.start(ms_stream, use_asyncio=True) while stream_interaction.circular_queue.head != -1: showm.render() await asyncio.sleep(.01) stream_interaction.stop() stream.stop() stream.cleanup() stream_interaction.cleanup()
# Create a Polydata pd = vtk.vtkPolyData() set_polydata_vertices(pd, big_vertices) set_polydata_triangles(pd, big_triangles) set_polydata_colors(pd, big_colors) set_polydata_normals(pd, big_normals) update_polydata_normals(pd) current_actor = get_actor_from_polydata(pd) if geom.lower() == 'square': current_actor.GetProperty().BackfaceCullingOff() return current_actor if __name__ == "__main__": showm = window.ShowManager(size=(1920, 1080), order_transparent=True) showm.initialize() # showm.scene.add(actor.axes()) centers = np.array([[0, 0, 0], [10, 0, 0], [20, 0, 0]]) centers1 = np.array([[5, 0, 0], [15, 0, 0], [25, 0, 0]]) directions = np.array([[0, 1, 0], [1, 0, 0], [0, 0, 1]]) colors = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1.]]) sq_params1 = np.array([1, 2, 5, 1, 1]) sq_params2 = np.array([1, 2, 1, 1, 1]) showm.scene.add(custom_glyph(centers=centers, colors=colors, sq_params=sq_params1, directions=directions, geom='superquadric')) showm.scene.add(custom_glyph(centers=centers1, colors=colors, sq_params=sq_params2,
import numpy as np from fury import window, actor, ui import itertools xyz = 10 * np.random.rand(100, 3) colors = np.random.rand(100, 4) radii = np.random.rand(100) + 0.5 scene = window.Scene() sphere_actor = actor.sphere(centers=xyz, colors=colors, radii=radii) scene.add(sphere_actor) showm = window.ShowManager(scene, size=(900, 768), reset_camera=False, order_transparent=True) showm.initialize() tb = ui.TextBlock2D(bold=True) # use itertools to avoid global variables counter = itertools.count() def timer_callback(_obj, _event): cnt = next(counter) tb.message = "Let's count up to 100 and exit :" + str(cnt) showm.scene.azimuth(0.05 * cnt) sphere_actor.GetProperty().SetOpacity(cnt / 100.)
from fury import window, actor, ui values = ["An Item" + str(i) for i in range(5)] new_values = [str(i) for i in range(5)] combobox = ui.ComboBox2D( items=values, position=(0, 100), size=(300, 200), draggable=True) # disk = ui.Disk2D(10, center=(0, 100)) # count = 0 # def add_val(combobox): # global count # combobox.append_item("Test" + str(count)) # count += 1 # def add_val_disk(i_ren, obj, element): # global count, combobox # combobox.append_item("Test" + str(count)) # count += 1 # combobox.position = (0, 100) # print(combobox.size) # combobox.resize((150, 100)) # print(combobox.size) # disk.on_left_mouse_button_clicked = add_val_disk combobox.append_item(*new_values) # combobox.on_change = add_val showm = window.ShowManager(title="ComboBox UI Test") showm.scene.add(combobox) showm.start()
def test_ui_checkbox_initial_state(interactive=False): filename = "test_ui_checkbox" recording_filename = pjoin(DATA_DIR, filename + ".log.gz") expected_events_counts_filename = pjoin(DATA_DIR, filename + ".json") checkbox_test = ui.Checkbox(labels=["option 1", "option 2\nOption 2", "option 3", "option 4"], position=(100, 100), checked_labels=["option 1", "option 4"]) # Collect the sequence of options that have been checked in this list. selected_options = [] def _on_change(checkbox): selected_options.append(list(checkbox.checked_labels)) # Set up a callback when selection changes checkbox_test.on_change = _on_change event_counter = EventCounter() event_counter.monitor(checkbox_test) # Create a show manager and record/play events. show_manager = window.ShowManager(size=(600, 600), title="FURY Checkbox") show_manager.scene.add(checkbox_test) show_manager.play_events_from_file(recording_filename) expected = EventCounter.load(expected_events_counts_filename) event_counter.check_counts(expected) # Recorded events: # 1. Click on button of option 1. # 2. Click on button of option 2. # 3. Click on button of option 1. # 4. Click on text of option 3. # 5. Click on text of option 1. # 6. Click on button of option 4. # 7. Click on text of option 1. # 8. Click on text of option 2. # 9. Click on text of option 4. # 10. Click on button of option 3. # Check if the right options were selected. expected = [['option 4'], ['option 4', 'option 2\nOption 2'], ['option 4', 'option 2\nOption 2', 'option 1'], ['option 4', 'option 2\nOption 2', 'option 1', 'option 3'], ['option 4', 'option 2\nOption 2', 'option 3'], ['option 2\nOption 2', 'option 3'], ['option 2\nOption 2', 'option 3', 'option 1'], ['option 3', 'option 1'], ['option 3', 'option 1', 'option 4'], ['option 1', 'option 4']] npt.assert_equal(len(selected_options), len(expected)) assert_arrays_equal(selected_options, expected) del show_manager if interactive: checkbox_test = ui.Checkbox(labels=["option 1", "option 2\nOption 2", "option 3", "option 4"], position=(100, 100), checked_labels=[]) showm = window.ShowManager(size=(600, 600)) showm.scene.add(checkbox_test) showm.start()
import time import asyncio import platform import numpy as np from fury import actor, window from fury.stream.widget import Widget interactive = False window_size = (720, 500) N = 4 centers = np.random.normal(size=(N, 3)) colors = np.random.uniform(0.1, 1.0, size=(N, 3)) actors = actor.sphere(centers, opacity=.5, radii=.4, colors=colors) scene = window.Scene() scene.add(actors) showm = window.ShowManager(scene, size=(window_size[0], window_size[1])) ########################################################################## # Create a stream widget widget = Widget(showm, port=8000) # if you want to use webRTC, you can pass the argument to choose this encoding # which is a more robust option. # `widget = Widget(showm, port=8000, encoding='webrtc')` time_sleep = 1000 if interactive else 1 ########################################################################### # If you want to use the widget in a Windows environment without the WSL # you need to use the asyncio version of the widget.
def test_ui_listbox_2d(interactive=False): filename = "test_ui_listbox_2d" recording_filename = pjoin(DATA_DIR, filename + ".log.gz") expected_events_counts_filename = pjoin(DATA_DIR, filename + ".json") # Values that will be displayed by the listbox. values = list(range(1, 42 + 1)) values.append("A Very Very Long Item To Test Text Overflow of List Box 2D") if interactive: listbox = ui.ListBox2D(values=values, size=(500, 500), multiselection=True, reverse_scrolling=False, background_opacity=0.3) listbox.center = (300, 300) listbox.panel.opacity = 0.2 show_manager = window.ShowManager(size=(600, 600), title="FURY ListBox") show_manager.initialize() show_manager.scene.add(listbox) show_manager.start() # Recorded events: # 1. Click on 1 # 2. Ctrl + click on 2, # 3. Ctrl + click on 2. # 4. Use scroll bar to scroll to the bottom. # 5. Click on "A Very Very Long Item...". # 6. Use scroll bar to scroll to the top. # 7. Click on 1 # 8. Use mouse wheel to scroll down. # 9. Shift + click on "A Very Very Long Item...". # 10. Use mouse wheel to scroll back up. listbox = ui.ListBox2D(values=values, size=(500, 500), multiselection=True, reverse_scrolling=False) listbox.center = (300, 300) # We will collect the sequence of values that have been selected. selected_values = [] def _on_change(): selected_values.append(list(listbox.selected)) # Set up a callback when selection changes. listbox.on_change = _on_change # Assign the counter callback to every possible event. event_counter = EventCounter() event_counter.monitor(listbox) show_manager = window.ShowManager(size=(600, 600), title="FURY ListBox") show_manager.scene.add(listbox) show_manager.play_events_from_file(recording_filename) expected = EventCounter.load(expected_events_counts_filename) event_counter.check_counts(expected) # Check if the right values were selected. expected = [[1], [1, 2], [1], ["A Very Very Long Item To \ Test Text Overflow of List Box 2D"], [1], values] npt.assert_equal(len(selected_values), len(expected)) assert_arrays_equal(selected_values, expected) # Test without multiselection enabled. listbox.multiselection = False del selected_values[:] # Clear the list. show_manager.play_events_from_file(recording_filename) # Check if the right values were selected. expected = [[1], [2], [2], ["A Very Very Long Item To \ Test Text Overflow of List Box 2D"], [1], ["A Very Very Long Item To Test \ Text Overflow of List Box 2D"]] npt.assert_equal(len(selected_values), len(expected)) assert_arrays_equal(selected_values, expected)
def test_custom_interactor_style_events(recording=False): print("Using VTK {}".format(vtk.vtkVersion.GetVTKVersion())) filename = "test_custom_interactor_style_events.log.gz" recording_filename = pjoin(DATA_DIR, filename) scene = window.Scene() # the show manager allows to break the rendering process # in steps so that the widgets can be added properly interactor_style = interactor.CustomInteractorStyle() show_manager = window.ShowManager(scene, size=(800, 800), reset_camera=False, interactor_style=interactor_style) # Create a cursor, a circle that will follow the mouse. polygon_source = vtk.vtkRegularPolygonSource() polygon_source.GeneratePolygonOff() # Only the outline of the circle. polygon_source.SetNumberOfSides(50) polygon_source.SetRadius(10) # polygon_source.SetRadius polygon_source.SetCenter(0, 0, 0) mapper = vtk.vtkPolyDataMapper2D() vtk_utils.set_input(mapper, polygon_source.GetOutputPort()) cursor = vtk.vtkActor2D() cursor.SetMapper(mapper) cursor.GetProperty().SetColor(1, 0.5, 0) scene.add(cursor) def follow_mouse(iren, obj): obj.SetPosition(*iren.event.position) iren.force_render() interactor_style.add_active_prop(cursor) interactor_style.add_callback(cursor, "MouseMoveEvent", follow_mouse) # create some minimalistic streamlines lines = [ np.array([[-1, 0, 0.], [1, 0, 0.]]), np.array([[-1, 1, 0.], [1, 1, 0.]]) ] colors = np.array([[1., 0., 0.], [0.3, 0.7, 0.]]) tube1 = actor.streamtube([lines[0]], colors[0]) tube2 = actor.streamtube([lines[1]], colors[1]) scene.add(tube1) scene.add(tube2) # Define some counter callback. states = defaultdict(lambda: 0) def counter(iren, _obj): states[iren.event.name] += 1 # Assign the counter callback to every possible event. for event in [ "CharEvent", "MouseMoveEvent", "KeyPressEvent", "KeyReleaseEvent", "LeftButtonPressEvent", "LeftButtonReleaseEvent", "RightButtonPressEvent", "RightButtonReleaseEvent", "MiddleButtonPressEvent", "MiddleButtonReleaseEvent" ]: interactor_style.add_callback(tube1, event, counter) # Add callback to scale up/down tube1. def scale_up_obj(iren, obj): counter(iren, obj) scale = np.asarray(obj.GetScale()) + 0.1 obj.SetScale(*scale) iren.force_render() iren.event.abort() # Stop propagating the event. def scale_down_obj(iren, obj): counter(iren, obj) scale = np.array(obj.GetScale()) - 0.1 obj.SetScale(*scale) iren.force_render() iren.event.abort() # Stop propagating the event. interactor_style.add_callback(tube2, "MouseWheelForwardEvent", scale_up_obj) interactor_style.add_callback(tube2, "MouseWheelBackwardEvent", scale_down_obj) # Add callback to hide/show tube1. def toggle_visibility(iren, obj): key = iren.event.key if key.lower() == "v": obj.SetVisibility(not obj.GetVisibility()) iren.force_render() interactor_style.add_active_prop(tube1) interactor_style.add_active_prop(tube2) interactor_style.remove_active_prop(tube2) interactor_style.add_callback(tube1, "CharEvent", toggle_visibility) if recording: show_manager.record_events_to_file(recording_filename) print(list(states.items())) else: show_manager.play_events_from_file(recording_filename) msg = ("Wrong count for '{}'.") expected = [('CharEvent', 6), ('KeyPressEvent', 6), ('KeyReleaseEvent', 6), ('MouseMoveEvent', 1652), ('LeftButtonPressEvent', 1), ('RightButtonPressEvent', 1), ('MiddleButtonPressEvent', 2), ('LeftButtonReleaseEvent', 1), ('MouseWheelForwardEvent', 3), ('MouseWheelBackwardEvent', 1), ('MiddleButtonReleaseEvent', 2), ('RightButtonReleaseEvent', 1)] # Useful loop for debugging. for event, count in expected: if states[event] != count: print("{}: {} vs. {} (expected)".format( event, states[event], count)) for event, count in expected: npt.assert_equal(states[event], count, err_msg=msg.format(event))