1616import genesis as gs
1717from genesis .vis .rasterizer_context import RasterizerContext
1818
19+ # Importing Tkinter and creating a first context before importing pyglet is necessary to avoid later segfault on MacOS.
20+ # Note that destroying the window will cause segfault at exit.
1921if sys .platform .startswith ("darwin" ):
20- # Mac OS
2122 from tkinter import Tk
22- from tkinter import filedialog
23- else :
24- try :
25- from Tkinter import Tk
26- from Tkinter import tkFileDialog as filedialog
27- except Exception :
28- try :
29- from tkinter import Tk
30- from tkinter import filedialog as filedialog
31- except Exception :
32- pass
23+ from tkinter import filedialog as filedialog
3324
34-
35- try :
3625 root = Tk ()
3726 root .withdraw ()
38- except :
39- pass
27+ else :
28+ root = None
4029
4130import pyglet
42- from moviepy .video .io .ffmpeg_writer import FFMPEG_VideoWriter
4331from pyglet import clock
4432
4533from .camera import IntrinsicsCamera , OrthographicCamera , PerspectiveCamera
@@ -917,6 +905,9 @@ def on_key_press(self, symbol: int, modifiers: int) -> EVENT_HANDLE_STATE:
917905 self .save_video ()
918906 self .set_caption (self .viewer_flags ["window_title" ])
919907 else :
908+ # Importing moviepy is very slow and not used very often. Let's delay import.
909+ from moviepy .video .io .ffmpeg_writer import FFMPEG_VideoWriter
910+
920911 self .video_recorder = FFMPEG_VideoWriter (
921912 filename = os .path .join (gs .utils .misc .get_cache_dir (), "tmp_video.mp4" ),
922913 fps = self .viewer_flags ["refresh_rate" ],
@@ -1037,6 +1028,8 @@ def _reset_view(self):
10371028 self ._trackball = Trackball (self ._default_camera_pose , self .viewport_size , scale , centroid )
10381029
10391030 def _get_save_filename (self , file_exts ):
1031+ global root
1032+
10401033 file_types = {
10411034 "mp4" : ("video files" , "*.mp4" ),
10421035 "png" : ("png files" , "*.png" ),
@@ -1048,17 +1041,23 @@ def _get_save_filename(self, file_exts):
10481041 save_dir = self .viewer_flags ["save_directory" ]
10491042 if save_dir is None :
10501043 save_dir = os .getcwd ()
1044+
1045+ # Importing tkinter is very slow and not used very often. Let's delay import.
1046+ try :
1047+ from tkinter import Tk
1048+ from tkinter import filedialog as filedialog
1049+ except ImportError :
1050+ from Tkinter import Tk
1051+ from Tkinter import tkFileDialog as filedialog
1052+
10511053 try :
1052- master = None
1053- if self ._run_in_thread :
1054- master = Tk ()
1055- master .withdraw ()
1054+ if root is None :
1055+ root = Tk ()
1056+ root .withdraw ()
10561057 dialog = filedialog .SaveAs (
1057- master = master , initialdir = save_dir , title = "Select file save location" , filetypes = filetypes
1058+ root , initialdir = save_dir , title = "Select file save location" , filetypes = filetypes
10581059 )
10591060 filename = dialog .show ()
1060- if self ._run_in_thread :
1061- master .destroy ()
10621061 except Exception :
10631062 gs .logger .warning ("Failed to open file save location dialog." )
10641063 return None
0 commit comments