From e67577c9b7cd35018a8d276cfe036ecd5be8fb39 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Wed, 8 Feb 2023 13:35:38 -0500 Subject: [PATCH 1/6] update snapshot and record --- fury/tests/test_actors.py | 14 ++--- fury/tests/test_thread.py | 28 ++++------ fury/window.py | 109 ++++++++++++++++++++++++++------------ 3 files changed, 94 insertions(+), 57 deletions(-) diff --git a/fury/tests/test_actors.py b/fury/tests/test_actors.py index a0e093477..a5bb8f2c2 100644 --- a/fury/tests/test_actors.py +++ b/fury/tests/test_actors.py @@ -61,7 +61,7 @@ def test_slicer(verbose=False): # window.show(scene) # copy pixels in numpy array directly - arr = window.snapshot(scene, 'test_slicer.png', offscreen=True) + arr = window.snapshot(scene, fname='test_slicer.png', offscreen=True) if verbose: print(arr.sum()) @@ -84,7 +84,7 @@ def test_slicer(verbose=False): # save pixels in png file not a numpy array with InTemporaryDirectory() as tmpdir: fname = os.path.join(tmpdir, 'slice.png') - window.snapshot(scene, fname, offscreen=True) + window.snapshot(scene, fname=fname, offscreen=True) report = window.analyze_snapshot(fname, find_objects=True) npt.assert_equal(report.objects, 1) @@ -191,7 +191,7 @@ def test_surface(): ) scene.add(surface_actor) # window.show(scene, size=(600, 600), reset_camera=False) - arr = window.snapshot(scene, 'test_surface.png', offscreen=True) + arr = window.snapshot(scene, fname='test_surface.png', offscreen=True) report = window.analyze_snapshot(arr, find_objects=True) npt.assert_equal(report.objects, 1) @@ -233,8 +233,8 @@ def test_contour_from_roi(interactive=False): if interactive: window.show(scene2) - arr = window.snapshot(scene, 'test_surface.png', offscreen=True) - arr2 = window.snapshot(scene2, 'test_surface2.png', offscreen=True) + arr = window.snapshot(scene, fname='test_surface.png', offscreen=True) + arr2 = window.snapshot(scene2, fname='test_surface2.png', offscreen=True) report = window.analyze_snapshot(arr, find_objects=True) report2 = window.analyze_snapshot(arr2, find_objects=True) @@ -292,10 +292,10 @@ def test_contour_from_label(interactive=False): window.show(scene2) arr = window.snapshot( - scene, 'test_surface.png', offscreen=True, order_transparent=False + scene, fname='test_surface.png', offscreen=True, order_transparent=False ) arr2 = window.snapshot( - scene2, 'test_surface2.png', offscreen=True, order_transparent=True + scene2, fname='test_surface2.png', offscreen=True, order_transparent=True ) report = window.analyze_snapshot( diff --git a/fury/tests/test_thread.py b/fury/tests/test_thread.py index 86c850b54..f3a158c96 100644 --- a/fury/tests/test_thread.py +++ b/fury/tests/test_thread.py @@ -1,11 +1,12 @@ - import time from threading import Thread -from fury.utils import rotate, update_actor, vertices_from_actor + import numpy as np import numpy.testing as npt import pytest + from fury import actor, window +from fury.utils import rotate, update_actor, vertices_from_actor def test_multithreading(): @@ -14,17 +15,15 @@ def test_multithreading(): radii = np.random.random(100) + 0.5 scene = window.Scene() - sphere_actor = actor.sphere(centers = xyz, - colors = colors, - radii = radii, - use_primitive = False) + sphere_actor = actor.sphere( + centers=xyz, colors=colors, radii=radii, use_primitive=False + ) scene.add(sphere_actor) # Preparing the show manager as usual - showm = window.ShowManager(scene, - size = (900, 768), - reset_camera = False, - order_transparent = True) + showm = window.ShowManager( + scene, size=(900, 768), reset_camera=False, order_transparent=True + ) # showm.initialize() @@ -36,7 +35,6 @@ def callback1(): rotate(sphere_actor, rotation=(0.01 * i, 1, 0, 0)) vsa[:] = 1.01 * vsa[:] update_actor(sphere_actor) - print(i) showm.release_current() time.sleep(0.01) else: @@ -48,12 +46,8 @@ def callback1(): # showm.exit() # npt.assert_equal(np.sum(arr) > 1, True) - - thread_a = Thread(target = callback1) + thread_a = Thread(target=callback1) thread_a.start() - showm.start(multithreaded = True) + showm.start(multithreaded=True) thread_a.join() - - -test_multithreading() \ No newline at end of file diff --git a/fury/window.py b/fury/window.py index a31aba7aa..e57d2aa91 100644 --- a/fury/window.py +++ b/fury/window.py @@ -816,7 +816,7 @@ def save_screenshot(self, fname, magnification=1, size=None, stereo=None): stereo = self.stereo.lower() record( - scene=self.scene, + self, out_path=fname, magnification=magnification, size=size, @@ -914,7 +914,9 @@ def show( show_manager.start() +@deprecated_params('scene', None, since='0.8', until='0.11') def record( + showm, scene=None, cam_pos=None, cam_focal=None, @@ -937,6 +939,8 @@ def record( Parameters ----------- + showm : ShowManager() object + ShowManager instance scene : Scene() or vtkRenderer() object Scene instance cam_pos : None or sequence (3,), optional @@ -986,26 +990,34 @@ def record( Examples --------- >>> from fury import window, actor - >>> scene = window.Scene() + >>> showm = window.ShowManager() >>> a = actor.axes() - >>> scene.add(a) + >>> showm.scene.add(a) >>> # uncomment below to record - >>> # window.record(scene) + >>> # window.record(showm) >>> # check for new images in current directory """ - if scene is None: - scene = Scene() + if isinstance(showm, ShowManager): + renWin = showm.window + scene = showm.scene + elif isinstance(showm, RenderWindow): + renWin = showm + scene = showm.GetRenderers().GetFirstRenderer() + elif isinstance(showm, (Scene, OpenGLRenderer)): + warn( + 'The scene instance parameter is deprecated. Please use the ShowManager ' + 'instance instead', + DeprecationWarning, + ) + renWin = RenderWindow() - renWin = RenderWindow() + renWin.SetOffScreenRendering(1) + renWin.SetBorders(screen_clip) + renWin.AddRenderer(scene or showm) - renWin.SetOffScreenRendering(1) - renWin.SetBorders(screen_clip) - renWin.AddRenderer(scene) renWin.SetSize(size[0], size[1]) - # scene.GetActiveCamera().Azimuth(180) - if reset_camera: scene.ResetCamera() @@ -1064,8 +1076,9 @@ def record( ang = +az_ang - renWin.RemoveRenderer(scene) - renWin.Finalize() + if isinstance(showm, (Scene, OpenGLRenderer)): + renWin.RemoveRenderer(scene or showm) + renWin.Finalize() def antialiasing(scene, win, multi_samples=8, max_peels=4, occlusion_ratio=0.0): @@ -1111,8 +1124,10 @@ def antialiasing(scene, win, multi_samples=8, max_peels=4, occlusion_ratio=0.0): scene.SetOcclusionRatio(occlusion_ratio) +@deprecated_params(['scene', 'render_window'], None, since='0.8', until='0.11') def snapshot( - scene, + showm, + scene=None, fname=None, size=(300, 300), offscreen=True, @@ -1129,8 +1144,10 @@ def snapshot( Parameters ----------- - scene : Scene() or vtkRenderer - Scene instance + showm : ShowManager + ShowManager instance + scene : Scene() or vtkRenderer, optional + Deprecated, Scene instance fname : str or None Save PNG file. If None return only an array without saving PNG. size : (int, int) @@ -1165,7 +1182,7 @@ def snapshot( Dots per inch (dpi) for saved image. Single values are applied as dpi for both dimensions. render_window : RenderWindow - If provided, use this window instead of creating a new one. + Deprecated, If provided, use this window instead of creating a new one. Returns ------- @@ -1175,20 +1192,45 @@ def snapshot( """ width, height = size - if render_window is None: - render_window = RenderWindow() - if offscreen: - render_window.SetOffScreenRendering(1) - if stereo.lower() != 'off': - enable_stereo(render_window, stereo) - render_window.AddRenderer(scene) - render_window.SetSize(width, height) - - if order_transparent: - antialiasing( - scene, render_window, multi_samples, max_peels, occlusion_ratio + if isinstance(showm, ShowManager): + render_window = showm.window + elif isinstance(showm, RenderWindow): + render_window = showm + elif isinstance(showm, (Scene, OpenGLRenderer)) or scene is not None: + warn( + 'The scene instance parameter is deprecated. Please use the ShowManager ' + 'instance or RenderWindow instance instead', + DeprecationWarning, + ) + + if render_window is None: + if isinstance(scene, str): + # small hack for backward compatibility + fname = scene + scene = None + render_window = RenderWindow() + if offscreen: + render_window.SetOffScreenRendering(1) + if stereo.lower() != 'off': + enable_stereo(render_window, stereo) + render_window.AddRenderer(scene or showm) + render_window.SetSize(width, height) + + if order_transparent: + antialiasing( + scene or showm, + render_window, + multi_samples, + max_peels, + occlusion_ratio, + ) + render_window.Render() + else: + warn( + 'The render_window parameter is deprecated. Please use the ShowManager ' + 'instance instead', + DeprecationWarning, ) - render_window.Render() window_to_image_filter = WindowToImageFilter() window_to_image_filter.SetInput(render_window) @@ -1206,8 +1248,9 @@ def snapshot( save_image(arr, fname, dpi=dpi) - render_window.RemoveRenderer(scene) - render_window.Finalize() + if isinstance(showm, (Scene, OpenGLRenderer)): + render_window.RemoveRenderer(scene or showm) + render_window.Finalize() return arr From 7a5bc7a66b41c9a0dc1b78bff85a5512e93822cd Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Fri, 10 Feb 2023 16:08:57 -0500 Subject: [PATCH 2/6] move some function to showmanager --- fury/window.py | 293 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 288 insertions(+), 5 deletions(-) diff --git a/fury/window.py b/fury/window.py index e57d2aa91..6d5c6fde6 100644 --- a/fury/window.py +++ b/fury/window.py @@ -10,6 +10,7 @@ from fury import __version__ as fury_version from fury.animation import Animation, Timeline +from fury.deprecator import deprecate_with_version, deprecated_params from fury.interactor import CustomInteractorStyle from fury.io import load_image, save_image from fury.lib import ( @@ -422,6 +423,7 @@ def __init__( self._timelines = [] self._animations = [] self._animation_callback = None + self.window_to_image_filter = None def initialize(self): """Initialize interaction.""" @@ -779,6 +781,255 @@ def exit(self): self.destroy_timers() self.timers.clear() + def record( + self, + cam_pos=None, + cam_focal=None, + cam_view=None, + out_path=None, + path_numbering=False, + n_frames=1, + az_ang=10, + magnification=1, + size=(300, 300), + reset_camera=True, + screen_clip=False, + stereo='off', + verbose=False, + ): + """Record a video of your scene. + + Records a video as a series of ``.png`` files of your scene by rotating the + azimuth angle az_angle in every frame. + + Parameters + ----------- + cam_pos : None or sequence (3,), optional + Camera's position. If None then default camera's position is used. + cam_focal : None or sequence (3,), optional + Camera's focal point. If None then default camera's focal point is + used. + cam_view : None or sequence (3,), optional + Camera's view up direction. If None then default camera's view up + vector is used. + out_path : str, optional + Output path for the frames. If None a default fury.png is created. + path_numbering : bool + When recording it changes out_path to out_path + str(frame number) + n_frames : int, optional + Number of frames to save, default 1 + az_ang : float, optional + Azimuthal angle of camera rotation. + magnification : int, optional + How much to magnify the saved frame. Default is 1. A value greater + than 1 increases the quality of the image. However, the output + size will be larger. For example, 200x200 image with magnification + of 2 will be a 400x400 image. + size : (int, int) + ``(width, height)`` of the window. Default is (300, 300). + screen_clip: bool + Clip the png based on screen resolution. Default is False. + reset_camera : bool + If True Call ``scene.reset_camera()``. Otherwise you need to set the + camera before calling this function. + stereo: string + Set the stereo type. Default is 'off'. Other types include: + + * 'opengl': OpenGL frame-sequential stereo. Referred to as + 'CrystalEyes' by VTK. + * 'anaglyph': For use with red/blue glasses. See VTK docs to + use different colors. + * 'interlaced': Line interlaced. + * 'checkerboard': Checkerboard interlaced. + * 'left': Left eye only. + * 'right': Right eye only. + * 'horizontal': Side-by-side. + + verbose : bool + print information about the camera. Default is False. + + Examples + --------- + >>> from fury import window, actor + >>> showm = window.ShowManager() + >>> a = actor.axes() + >>> showm.scene.add(a) + >>> # uncomment below to record + >>> # window.record(showm) + >>> # check for new images in current directory + + """ + previous_offscreen = self.window.GetOffScreenRendering() + + self.window.SetOffScreenRendering(1) + self.window.SetBorders(screen_clip) + + self.window.SetSize(size[0], size[1]) + # scene.GetActiveCamera().Azimuth(180) + if reset_camera: + self.scene.ResetCamera() + + if stereo.lower() != 'off': + enable_stereo(self.window, stereo) + + renderLarge = RenderLargeImage() + renderLarge.SetInput(self.scene) + renderLarge.SetMagnification(magnification) + renderLarge.Update() + + ang = 0 + + if cam_pos is not None: + cx, cy, cz = cam_pos + self.scene.GetActiveCamera().SetPosition(cx, cy, cz) + if cam_focal is not None: + fx, fy, fz = cam_focal + self.scene.GetActiveCamera().SetFocalPoint(fx, fy, fz) + if cam_view is not None: + ux, uy, uz = cam_view + self.scene.GetActiveCamera().SetViewUp(ux, uy, uz) + + cam = self.scene.GetActiveCamera() + if verbose: + print('Camera Position (%.2f, %.2f, %.2f)' % cam.GetPosition()) + print('Camera Focal Point (%.2f, %.2f, %.2f)' % cam.GetFocalPoint()) + print('Camera View Up (%.2f, %.2f, %.2f)' % cam.GetViewUp()) + + for i in range(n_frames): + self.scene.GetActiveCamera().Azimuth(ang) + renderLarge = RenderLargeImage() + renderLarge.SetInput(self.scene) + renderLarge.SetMagnification(magnification) + renderLarge.Update() + + if path_numbering: + if out_path is None: + filename = str(i).zfill(6) + '.png' + else: + filename = out_path + str(i).zfill(6) + '.png' + else: + if out_path is None: + filename = 'fury.png' + else: + filename = out_path + + arr = numpy_support.vtk_to_numpy( + renderLarge.GetOutput().GetPointData().GetScalars() + ) + w, h, _ = renderLarge.GetOutput().GetDimensions() + components = renderLarge.GetOutput().GetNumberOfScalarComponents() + arr = arr.reshape((h, w, components)) + arr = np.flipud(arr) + save_image(arr, filename) + + ang = +az_ang + + self.window.SetOffScreenRendering(previous_offscreen) + + def snapshot( + self, + fname=None, + size=(300, 300), + offscreen=True, + order_transparent=False, + stereo='off', + multi_samples=8, + max_peels=4, + occlusion_ratio=0.0, + dpi=(72, 72), + ): + + """Save a snapshot of the scene in a file or in memory. + + Parameters + ----------- + fname : str or None + Save PNG file. If None return only an array without saving PNG. + size : (int, int) + ``(width, height)`` of the window. Default is (300, 300). + offscreen : bool + Default True. Go stealth mode no window should appear. + order_transparent : bool + Default False. Use depth peeling to sort transparent objects. + If True also enables anti-aliasing. + + stereo: string + Set the stereo type. Default is 'off'. Other types include: + + * 'opengl': OpenGL frame-sequential stereo. Referred to as + 'CrystalEyes' by VTK. + * 'anaglyph': For use with red/blue glasses. See VTK docs to + use different colors. + * 'interlaced': Line interlaced. + * 'checkerboard': Checkerboard interlaced. + * 'left': Left eye only. + * 'right': Right eye only. + * 'horizontal': Side-by-side. + + multi_samples : int + Number of samples for anti-aliazing (Default 8). + For no anti-aliasing use 0. + max_peels : int + Maximum number of peels for depth peeling (Default 4). + occlusion_ratio : float + Occlusion ration for depth peeling (Default 0 - exact image). + dpi : float or (float, float) + Dots per inch (dpi) for saved image. + Single values are applied as dpi for both dimensions. + + Returns + ------- + arr : ndarray + Color array of size (width, height, 3) where the last dimension + holds the RGB values. + + """ + previous_size = self.window.GetSize() + previous_offscreen = self.window.GetOffScreenRendering() + width, height = size + + if offscreen: + self.window.SetOffScreenRendering(1) + if stereo.lower() != 'off': + enable_stereo(self.window, stereo) + + window.SetSize(width, height) + + if order_transparent: + antialiasing( + self.scene, + self.window, + multi_samples, + max_peels, + occlusion_ratio, + ) + + self.render() + + if self.window_to_image_filter is None: + self.window_to_image_filter = WindowToImageFilter() + self.window_to_image_filter.SetInput(self.window) + + self.window_to_image_filter.Update() + + vtk_image = window_to_image_filter.GetOutput() + h, w, _ = vtk_image.GetDimensions() + vtk_array = vtk_image.GetPointData().GetScalars() + components = vtk_array.GetNumberOfComponents() + arr = numpy_support.vtk_to_numpy(vtk_array).reshape(w, h, components).copy() + arr = np.flipud(arr) + + if fname is None: + return arr + + save_image(arr, fname, dpi=dpi) + + if offscreen: + self.window.SetOffScreenRendering(previous_offscreen) + window.SetSize(previous_size[0], previous_size[1]) + + return arr + def save_screenshot(self, fname, magnification=1, size=None, stereo=None): """Save a screenshot of the current window in the specified filename. @@ -815,8 +1066,7 @@ def save_screenshot(self, fname, magnification=1, size=None, stereo=None): if stereo is None: stereo = self.stereo.lower() - record( - self, + self.record( out_path=fname, magnification=magnification, size=size, @@ -914,6 +1164,11 @@ def show( show_manager.start() +@deprecate_with_version( + 'This function is deprecated, please use ShowManager.record instead.', + since='0.8', + until='0.11', +) @deprecated_params('scene', None, since='0.8', until='0.11') def record( showm, @@ -999,8 +1254,21 @@ def record( """ if isinstance(showm, ShowManager): - renWin = showm.window - scene = showm.scene + showm.record( + cam_pos=cam_pos, + cam_focal=cam_focal, + cam_view=cam_view, + out_path=out_path, + path_numbering=path_numbering, + n_frames=n_frames, + az_ang=az_ang, + magnification=magnification, + size=size, + reset_camera=reset_camera, + screen_clip=screen_clip, + stereo=stereo, + verbose=verbose, + ) elif isinstance(showm, RenderWindow): renWin = showm scene = showm.GetRenderers().GetFirstRenderer() @@ -1124,6 +1392,11 @@ def antialiasing(scene, win, multi_samples=8, max_peels=4, occlusion_ratio=0.0): scene.SetOcclusionRatio(occlusion_ratio) +@deprecate_with_version( + 'This function is deprecated, please use ShowManager.snapshot instead.', + since='0.8', + until='0.11', +) @deprecated_params(['scene', 'render_window'], None, since='0.8', until='0.11') def snapshot( showm, @@ -1193,7 +1466,17 @@ def snapshot( """ width, height = size if isinstance(showm, ShowManager): - render_window = showm.window + return showm.snapshot( + fname=fname, + size=size, + offscreen=offscreen, + order_transparent=order_transparent, + stereo=stereo, + multi_samples=multi_samples, + max_peels=max_peels, + occlusion_ratio=occlusion_ratio, + dpi=dpi, + ) elif isinstance(showm, RenderWindow): render_window = showm elif isinstance(showm, (Scene, OpenGLRenderer)) or scene is not None: From f645e55a251594468109773a169b648e9c8476b9 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Wed, 15 Feb 2023 11:59:01 -0500 Subject: [PATCH 3/6] add tests --- fury/tests/test_window.py | 32 +++++++++++++++----------------- fury/window.py | 8 +++++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/fury/tests/test_window.py b/fury/tests/test_window.py index f45607fc9..e1494becc 100644 --- a/fury/tests/test_window.py +++ b/fury/tests/test_window.py @@ -227,6 +227,7 @@ def test_parallel_projection(): def test_order_transparent(): scene = window.Scene() + show_m = window.ShowManager(scene) red_cube = actor.cube( centers=np.array([[0.0, 0.0, 2]]), @@ -251,14 +252,14 @@ def test_order_transparent(): # without order_transparency the green will look stronger # when looked from behind the red cube - arr = window.snapshot(scene, fname=None, offscreen=True, order_transparent=False) + arr = show_m.snapshot(fname=None, offscreen=True, order_transparent=False) # check if flags are set as expected (here no order transparency) npt.assert_equal(scene.GetLastRenderingUsedDepthPeeling(), 0) green_stronger = arr[150, 150, 1] - arr = window.snapshot(scene, fname=None, offscreen=True, order_transparent=True) + arr = show_m.snapshot(fname=None, offscreen=True, order_transparent=True) # # check if flags are set as expected (here with order transparency) npt.assert_equal(scene.GetLastRenderingUsedDepthPeeling(), 1) @@ -266,6 +267,7 @@ def test_order_transparent(): # when order transparency is True green should be weaker green_weaker = arr[150, 150, 1] + print(green_stronger, green_weaker) assert_greater(green_stronger, green_weaker) @@ -447,7 +449,9 @@ def test_record(): use_primitive=True, ) scene = window.Scene() - scene.add(sphere_actor) + + show_m = window.ShowManager(scene) + show_m.scene.add(sphere_actor) def test_content(filename='fury.png', colors_found=(True, True)): npt.assert_equal(os.path.isfile(filename), True) @@ -459,17 +463,17 @@ def test_content(filename='fury.png', colors_found=(True, True)): # Basic test with InTemporaryDirectory(): - window.record(scene) + show_m.record() test_content() # test out_path and path_numbering, n_frame with InTemporaryDirectory(): filename = 'tmp_snapshot.png' - window.record(scene, out_path=filename) + show_m.record(out_path=filename) test_content(filename) - window.record(scene, out_path=filename, path_numbering=True) + show_m.record(out_path=filename, path_numbering=True) test_content(filename + '000000.png') - window.record(scene, out_path=filename, path_numbering=True, n_frames=3) + show_m.record(out_path=filename, path_numbering=True, n_frames=3) test_content(filename + '000000.png') test_content(filename + '000001.png') test_content(filename + '000002.png') @@ -477,7 +481,7 @@ def test_content(filename='fury.png', colors_found=(True, True)): # test verbose with captured_output() as (out, _): - window.record(scene, verbose=True) + show_m.record(verbose=True) npt.assert_equal( out.getvalue().strip(), @@ -487,9 +491,7 @@ def test_content(filename='fury.png', colors_found=(True, True)): ) # test camera option with InTemporaryDirectory(): - window.record( - scene, cam_pos=(310, 0, 530), cam_focal=(120, 0, 0), cam_view=(0, 0, 1) - ) + show_m.record(cam_pos=(310, 0, 530), cam_focal=(120, 0, 0), cam_view=(0, 0, 1)) test_content() # test size and clipping @@ -498,17 +500,13 @@ def test_content(filename='fury.png', colors_found=(True, True)): # ReadFrontBufferOff(), ShouldRerenderOn() could improved this OSX case. if not skip_osx: with InTemporaryDirectory(): - window.record( - scene, out_path='fury_1.png', size=(1000, 1000), magnification=5 - ) + show_m.record(out_path='fury_1.png', size=(1000, 1000), magnification=5) npt.assert_equal(os.path.isfile('fury_1.png'), True) arr = io.load_image('fury_1.png') npt.assert_equal(arr.shape, (5000, 5000, 3)) - window.record( - scene, out_path='fury_2.png', size=(5000, 5000), screen_clip=True - ) + show_m.record(out_path='fury_2.png', size=(5000, 5000), screen_clip=True) npt.assert_equal(os.path.isfile('fury_2.png'), True) arr = io.load_image('fury_2.png') diff --git a/fury/window.py b/fury/window.py index 6d5c6fde6..4ad98afed 100644 --- a/fury/window.py +++ b/fury/window.py @@ -993,9 +993,10 @@ def snapshot( if stereo.lower() != 'off': enable_stereo(self.window, stereo) - window.SetSize(width, height) + self.window.SetSize(width, height) if order_transparent: + # import ipdb; ipdb.set_trace() antialiasing( self.scene, self.window, @@ -1010,9 +1011,10 @@ def snapshot( self.window_to_image_filter = WindowToImageFilter() self.window_to_image_filter.SetInput(self.window) + self.window_to_image_filter.Modified() self.window_to_image_filter.Update() - vtk_image = window_to_image_filter.GetOutput() + vtk_image = self.window_to_image_filter.GetOutput() h, w, _ = vtk_image.GetDimensions() vtk_array = vtk_image.GetPointData().GetScalars() components = vtk_array.GetNumberOfComponents() @@ -1026,7 +1028,7 @@ def snapshot( if offscreen: self.window.SetOffScreenRendering(previous_offscreen) - window.SetSize(previous_size[0], previous_size[1]) + self.window.SetSize(previous_size[0], previous_size[1]) return arr From cbeec71494a21dd00a1ce9862d3cd2cde49423f7 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Wed, 15 Feb 2023 12:24:11 -0500 Subject: [PATCH 4/6] update some tutorial --- docs/tutorials/01_introductory/viz_arrow.py | 10 +++++----- docs/tutorials/01_introductory/viz_cone.py | 10 +++++----- docs/tutorials/01_introductory/viz_earth_animation.py | 2 +- .../tutorials/01_introductory/viz_earth_coordinates.py | 3 +-- docs/tutorials/01_introductory/viz_gltf_animated.py | 2 +- docs/tutorials/01_introductory/viz_gltf_export.py | 7 +++++-- docs/tutorials/01_introductory/viz_picking.py | 2 +- docs/tutorials/01_introductory/viz_timers.py | 2 +- fury/window.py | 1 - 9 files changed, 20 insertions(+), 19 deletions(-) diff --git a/docs/tutorials/01_introductory/viz_arrow.py b/docs/tutorials/01_introductory/viz_arrow.py index f65c6bf8e..68ff497d7 100644 --- a/docs/tutorials/01_introductory/viz_arrow.py +++ b/docs/tutorials/01_introductory/viz_arrow.py @@ -37,17 +37,17 @@ arrow_actor2 = actor.arrow(cen2, dir2, colors=cols2, scales=1.5) -scene = window.Scene() +showm = window.ShowManager(size=(600, 600)) ############################################################################ # Adding our Arrow actors to scene. -scene.add(arrow_actor) -scene.add(arrow_actor2) +showm.scene.add(arrow_actor) +showm.scene.add(arrow_actor2) interactive = False if interactive: - window.show(scene, size=(600, 600)) + showm.start() -window.record(scene, out_path='viz_arrow.png', size=(600, 600)) +showm.record(out_path='viz_arrow.png', size=(600, 600)) diff --git a/docs/tutorials/01_introductory/viz_cone.py b/docs/tutorials/01_introductory/viz_cone.py index 188bafbfc..b8a2d36d1 100644 --- a/docs/tutorials/01_introductory/viz_cone.py +++ b/docs/tutorials/01_introductory/viz_cone.py @@ -31,17 +31,17 @@ cone_actor2 = actor.cone(cen2, dir2, colors=cols2, heights=1.5, use_primitive=False) -scene = window.Scene() +showm = window.ShowManager(size=(600, 600)) ############################################################################ # Adding our cone actors to scene. -scene.add(cone_actor1) -scene.add(cone_actor2) +showm.scene.add(cone_actor1) +showm.scene.add(cone_actor2) interactive = False if interactive: - window.show(scene, size=(600, 600)) + showm.start() -window.record(scene, out_path='viz_cone.png', size=(600, 600)) +showm.record(out_path='viz_cone.png', size=(600, 600)) diff --git a/docs/tutorials/01_introductory/viz_earth_animation.py b/docs/tutorials/01_introductory/viz_earth_animation.py index 38cd7f286..3d40997ad 100644 --- a/docs/tutorials/01_introductory/viz_earth_animation.py +++ b/docs/tutorials/01_introductory/viz_earth_animation.py @@ -172,4 +172,4 @@ def timer_callback(_obj, _event): showm.add_timer_callback(True, 35, timer_callback) showm.start() -window.record(showm.scene, size=(900, 768), out_path='viz_earth_animation.png') +showm.record(size=(900, 768), out_path='viz_earth_animation.png') diff --git a/docs/tutorials/01_introductory/viz_earth_coordinates.py b/docs/tutorials/01_introductory/viz_earth_coordinates.py index 48232a3c0..9f029ece8 100644 --- a/docs/tutorials/01_introductory/viz_earth_coordinates.py +++ b/docs/tutorials/01_introductory/viz_earth_coordinates.py @@ -156,5 +156,4 @@ def timer_callback(_obj, _event): showm.add_timer_callback(True, 25, timer_callback) showm.start() - -window.record(showm.scene, size=(900, 768), out_path='viz_earth_coordinates.png') +showm.record(size=(900, 768), out_path='viz_earth_coordinates.png') diff --git a/docs/tutorials/01_introductory/viz_gltf_animated.py b/docs/tutorials/01_introductory/viz_gltf_animated.py index 6060a4030..02ea52758 100644 --- a/docs/tutorials/01_introductory/viz_gltf_animated.py +++ b/docs/tutorials/01_introductory/viz_gltf_animated.py @@ -54,4 +54,4 @@ def timer_callback(_obj, _event): if interactive: showm.start() -window.record(scene, out_path='viz_gltf_animated.png', size=(900, 768)) +showm.record(out_path='viz_gltf_animated.png', size=(900, 768)) diff --git a/docs/tutorials/01_introductory/viz_gltf_export.py b/docs/tutorials/01_introductory/viz_gltf_export.py index 6595c91cf..49ef94251 100644 --- a/docs/tutorials/01_introductory/viz_gltf_export.py +++ b/docs/tutorials/01_introductory/viz_gltf_export.py @@ -21,6 +21,9 @@ scene = window.Scene() +showm = window.ShowManager(scene, size=(1280, 720)) +showm.initialize() + ############################################################################## # Creating actors and adding to scene. @@ -62,6 +65,6 @@ interactive = False if interactive: - window.show(scene, size=(1280, 720)) + showm.start() -window.record(scene, out_path='viz_gltf_export.png', size=(1280, 720)) +showm.record(scene, out_path='viz_gltf_export.png', size=(1280, 720)) diff --git a/docs/tutorials/01_introductory/viz_picking.py b/docs/tutorials/01_introductory/viz_picking.py index 00b14c5f8..2304103f8 100644 --- a/docs/tutorials/01_introductory/viz_picking.py +++ b/docs/tutorials/01_introductory/viz_picking.py @@ -157,4 +157,4 @@ def left_click_callback(obj, event): ############################################################################### # Save the current framebuffer in a PNG file -window.record(showm.scene, size=(1024, 768), out_path='viz_picking.png') +showm.record(size=(1024, 768), out_path='viz_picking.png') diff --git a/docs/tutorials/01_introductory/viz_timers.py b/docs/tutorials/01_introductory/viz_timers.py index c529a5768..4c0794039 100644 --- a/docs/tutorials/01_introductory/viz_timers.py +++ b/docs/tutorials/01_introductory/viz_timers.py @@ -67,4 +67,4 @@ def timer_callback(_obj, _event): showm.start() -window.record(showm.scene, size=(900, 768), out_path='viz_timer.png') +showm.record(showm.scene, size=(900, 768), out_path='viz_timer.png') diff --git a/fury/window.py b/fury/window.py index 4ad98afed..3d4bc0358 100644 --- a/fury/window.py +++ b/fury/window.py @@ -996,7 +996,6 @@ def snapshot( self.window.SetSize(width, height) if order_transparent: - # import ipdb; ipdb.set_trace() antialiasing( self.scene, self.window, From 840b7ef86c2c8b08da1cf693c29b5e0e56a69347 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Fri, 17 Feb 2023 11:10:21 -0500 Subject: [PATCH 5/6] avoid removing scene --- docs/tutorials/01_introductory/viz_gltf.py | 6 ++++-- docs/tutorials/01_introductory/viz_gltf_export.py | 2 +- docs/tutorials/01_introductory/viz_morphing.py | 2 +- docs/tutorials/01_introductory/viz_selection.py | 2 +- docs/tutorials/01_introductory/viz_skinning.py | 2 +- docs/tutorials/01_introductory/viz_slice.py | 2 +- docs/tutorials/01_introductory/viz_solar_system.py | 2 +- docs/tutorials/01_introductory/viz_timers.py | 4 ++-- fury/window.py | 12 +++++++----- 9 files changed, 19 insertions(+), 15 deletions(-) diff --git a/docs/tutorials/01_introductory/viz_gltf.py b/docs/tutorials/01_introductory/viz_gltf.py index fd64cacad..20b9f5d24 100644 --- a/docs/tutorials/01_introductory/viz_gltf.py +++ b/docs/tutorials/01_introductory/viz_gltf.py @@ -15,6 +15,8 @@ scene = window.Scene() scene.SetBackground(0.1, 0.1, 0.4) +showm = window.ShowManager(scene, size=(1280, 720)) + ############################################################################## # Retrieving the gltf model. fetch_gltf('Duck', 'glTF') @@ -44,6 +46,6 @@ interactive = False if interactive: - window.show(scene, size=(1280, 720)) + showm.start() -window.record(scene, out_path='viz_gltf.png', size=(1280, 720)) +showm.record(out_path='viz_gltf.png', size=(1280, 720)) diff --git a/docs/tutorials/01_introductory/viz_gltf_export.py b/docs/tutorials/01_introductory/viz_gltf_export.py index 49ef94251..ee740f498 100644 --- a/docs/tutorials/01_introductory/viz_gltf_export.py +++ b/docs/tutorials/01_introductory/viz_gltf_export.py @@ -67,4 +67,4 @@ if interactive: showm.start() -showm.record(scene, out_path='viz_gltf_export.png', size=(1280, 720)) +showm.record(out_path='viz_gltf_export.png', size=(1280, 720)) diff --git a/docs/tutorials/01_introductory/viz_morphing.py b/docs/tutorials/01_introductory/viz_morphing.py index 6d8fa21f4..7fcc8a758 100644 --- a/docs/tutorials/01_introductory/viz_morphing.py +++ b/docs/tutorials/01_introductory/viz_morphing.py @@ -71,4 +71,4 @@ def timer_callback(_obj, _event): if interactive: showm.start() -window.record(scene, out_path='viz_morphing.png', size=(900, 768)) +showm.record(out_path='viz_morphing.png', size=(900, 768)) diff --git a/docs/tutorials/01_introductory/viz_selection.py b/docs/tutorials/01_introductory/viz_selection.py index 968d5f315..fa567b5d6 100644 --- a/docs/tutorials/01_introductory/viz_selection.py +++ b/docs/tutorials/01_introductory/viz_selection.py @@ -139,4 +139,4 @@ def hover_callback(_obj, _event): ############################################################################### # Save the current framebuffer in a PNG file -window.record(showm.scene, size=(1024, 768), out_path='viz_selection.png') +showm.record(size=(1024, 768), out_path='viz_selection.png') diff --git a/docs/tutorials/01_introductory/viz_skinning.py b/docs/tutorials/01_introductory/viz_skinning.py index f537933a9..db46ae8c7 100644 --- a/docs/tutorials/01_introductory/viz_skinning.py +++ b/docs/tutorials/01_introductory/viz_skinning.py @@ -73,4 +73,4 @@ def timer_callback(_obj, _event): if interactive: showm.start() -window.record(scene, out_path='viz_skinning.png', size=(900, 768)) +showm.record(out_path='viz_skinning.png', size=(900, 768)) diff --git a/docs/tutorials/01_introductory/viz_slice.py b/docs/tutorials/01_introductory/viz_slice.py index f6da76cad..1e9e886af 100644 --- a/docs/tutorials/01_introductory/viz_slice.py +++ b/docs/tutorials/01_introductory/viz_slice.py @@ -260,4 +260,4 @@ def left_click_callback_mosaic(obj, _ev): # zoom in/out using the scroll wheel, and pick voxels with left click. -window.record(scene, out_path='mosaic.png', size=(900, 600), reset_camera=False) +show_m_mosaic.record(out_path='mosaic.png', size=(900, 600), reset_camera=False) diff --git a/docs/tutorials/01_introductory/viz_solar_system.py b/docs/tutorials/01_introductory/viz_solar_system.py index 185b044a3..1b1044faf 100644 --- a/docs/tutorials/01_introductory/viz_solar_system.py +++ b/docs/tutorials/01_introductory/viz_solar_system.py @@ -331,4 +331,4 @@ def pause_animation(i_ren, _obj, _button): showm.add_timer_callback(True, 10, timer_callback) showm.start() -window.record(showm.scene, size=(900, 768), out_path='viz_solar_system_animation.png') +showm.record(size=(900, 768), out_path='viz_solar_system_animation.png') diff --git a/docs/tutorials/01_introductory/viz_timers.py b/docs/tutorials/01_introductory/viz_timers.py index 4c0794039..22fe298cb 100644 --- a/docs/tutorials/01_introductory/viz_timers.py +++ b/docs/tutorials/01_introductory/viz_timers.py @@ -65,6 +65,6 @@ def timer_callback(_obj, _event): # Run every 200 milliseconds timer_id = showm.add_timer_callback(True, 200, timer_callback) -showm.start() +showm.start(keep_alive=True) -showm.record(showm.scene, size=(900, 768), out_path='viz_timer.png') +showm.record(size=(900, 768), out_path='viz_timer.png') diff --git a/fury/window.py b/fury/window.py index 3d4bc0358..cb887b233 100644 --- a/fury/window.py +++ b/fury/window.py @@ -551,6 +551,8 @@ def start(self, multithreaded=False, desired_fps=60): if end_time - start_time < time_per_frame: time.sleep(time_per_frame - (end_time - start_time)) else: + if not self.iren.GetInitialized(): + self.initialize() self.render() self.iren.Start() @@ -571,11 +573,7 @@ def start(self, multithreaded=False, desired_fps=60): self.window.SetWindowName(self.title) self.iren.Start() - self.window.RemoveRenderer(self.scene) - self.scene.SetRenderWindow(None) self.window.Finalize() - del self.iren - del self.window def lock(self): """Lock the render window.""" @@ -781,6 +779,11 @@ def exit(self): self.destroy_timers() self.timers.clear() + def remove_scene(self): + self.window.RemoveRenderer(self.scene) + self.scene.SetRenderWindow(None) + self.scene = None + def record( self, cam_pos=None, @@ -938,7 +941,6 @@ def snapshot( occlusion_ratio=0.0, dpi=(72, 72), ): - """Save a snapshot of the scene in a file or in memory. Parameters From b61f43e44bbd7d7a5abc75847fc71ca044eb5fd3 Mon Sep 17 00:00:00 2001 From: Serge Koudoro Date: Tue, 21 Feb 2023 14:09:28 -0500 Subject: [PATCH 6/6] initialize in the timer callback --- docs/tutorials/01_introductory/viz_timers.py | 2 +- fury/window.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/tutorials/01_introductory/viz_timers.py b/docs/tutorials/01_introductory/viz_timers.py index 22fe298cb..5036c2f30 100644 --- a/docs/tutorials/01_introductory/viz_timers.py +++ b/docs/tutorials/01_introductory/viz_timers.py @@ -65,6 +65,6 @@ def timer_callback(_obj, _event): # Run every 200 milliseconds timer_id = showm.add_timer_callback(True, 200, timer_callback) -showm.start(keep_alive=True) +showm.start() showm.record(size=(900, 768), out_path='viz_timer.png') diff --git a/fury/window.py b/fury/window.py index cb887b233..64024e136 100644 --- a/fury/window.py +++ b/fury/window.py @@ -551,8 +551,6 @@ def start(self, multithreaded=False, desired_fps=60): if end_time - start_time < time_per_frame: time.sleep(time_per_frame - (end_time - start_time)) else: - if not self.iren.GetInitialized(): - self.initialize() self.render() self.iren.Start()