|
| 1 | +""" |
| 2 | +Utilities for handling the Graphic Unit Interface. |
| 3 | +
|
| 4 | +.. todo:: |
| 5 | + Switch to Ttk instead of Tk for a better look of the GUI |
| 6 | +""" |
| 7 | + |
| 8 | +import Tkinter |
| 9 | +from tkFileDialog import askopenfilename |
| 10 | +from PIL import ImageTk, Image |
| 11 | +import pygem as pg |
| 12 | +import sys |
| 13 | +import os |
| 14 | +import webbrowser |
| 15 | + |
| 16 | +class Gui(object): |
| 17 | + """ |
| 18 | + The class for the Graphic Unit Interface. |
| 19 | +
|
| 20 | + :cvar string filename_geometry: input geometry to be morphed. |
| 21 | + :cvar string filename_parameters: input parameters file for FFD. |
| 22 | + :cvar int check_var_1: dump or not the original FFD lattice. |
| 23 | + :cvar int check_var_2: dump or not the morphed FFD lattice. |
| 24 | + :cvar string outfilename: name of the output file geometry. |
| 25 | + The extension of the file is set automatically equal to the on of input file 'filename_geometry'. |
| 26 | + :cvar string outfilename_lattice_orig: name of the dumped file for the original lattice. |
| 27 | + The extension of the file is set automatically equal to '.vtk'. |
| 28 | + :cvar string outfilename_lattice_mod: name of the dumped file for the morphed lattice. |
| 29 | + The extension of the file is set automatically equal to '.vtk'. |
| 30 | + :cvar Tkinter.Tk root: main window object of the GUI. |
| 31 | + :cvar string print_geometry_path: geometry path to be printed close to the 'pick geometry' button. |
| 32 | + :cvar string print_parameter_path: parameters file path to be printed close to the 'pick parameters' button. |
| 33 | + :cvar Tkinter.Label label_geo: label related to 'print_geometry_path'. |
| 34 | + :cvar Tkinter.Label label_params: label related to 'print_parameters_path'. |
| 35 | + :cvar string url: url of the github page of PyGeM. |
| 36 | + |
| 37 | + """ |
| 38 | + |
| 39 | + def __init__(self): |
| 40 | + |
| 41 | + self.root = Tkinter.Tk() |
| 42 | + self.root.title('PyGeM') |
| 43 | + |
| 44 | + self.filename_geometry = Tkinter.StringVar() |
| 45 | + self.filename_parameters = Tkinter.StringVar() |
| 46 | + self.check_var_1 = Tkinter.IntVar() |
| 47 | + self.check_var_2 = Tkinter.IntVar() |
| 48 | + self.outfilename = Tkinter.StringVar() |
| 49 | + self.outfilename_lattice_orig = Tkinter.StringVar() |
| 50 | + self.outfilename_lattice_mod = Tkinter.StringVar() |
| 51 | + self.print_geometry_path = Tkinter.StringVar() |
| 52 | + self.print_parameter_path = Tkinter.StringVar() |
| 53 | + self.label_geo = None |
| 54 | + self.label_params = None |
| 55 | + self.url = 'https://github.com/mathLab/PyGeM' |
| 56 | + |
| 57 | + |
| 58 | + |
| 59 | + def _chose_geometry(self): |
| 60 | + """ |
| 61 | + The private method explores the file system and allows to select the wanted geometry. |
| 62 | + Up to now, you can select only IGES, OpenFOAM, STL, UNV or VTK geometry file. |
| 63 | + """ |
| 64 | + self.filename_geometry = askopenfilename(filetypes=[("IGES File",('*.iges', '*.igs')), \ |
| 65 | + ("OpenFOAM File",'*'),('STL File','*.stl'),('UNV File','*.unv'),('VTK File','*.vtk'),('All','*')]) |
| 66 | + self.print_geometry_path.set(self.filename_geometry) |
| 67 | + self.label_geo.configure(fg='green') |
| 68 | + |
| 69 | + |
| 70 | + def _chose_parameters(self): |
| 71 | + """ |
| 72 | + The private method explores the file system and allows to select the wanted parameters file. |
| 73 | + It visualizes only .prm files. |
| 74 | + """ |
| 75 | + self.filename_parameters = askopenfilename(filetypes=[("Params File","*.prm")]) |
| 76 | + self.print_parameter_path.set(self.filename_parameters) |
| 77 | + self.label_params.configure(fg='green') |
| 78 | + |
| 79 | + |
| 80 | + def _run_simulation(self): |
| 81 | + """ |
| 82 | + The private method runs the geometrical morphing. |
| 83 | + """ |
| 84 | + params = pg.params.FFDParameters() |
| 85 | + params.read_parameters(filename=self.filename_parameters) |
| 86 | + |
| 87 | + (__,file_extension_in) = os.path.splitext(self.filename_geometry) |
| 88 | + |
| 89 | + if file_extension_in == '.stl': |
| 90 | + geo_handler = pg.stlhandler.StlHandler() |
| 91 | + elif file_extension_in in ['.iges', '.igs']: |
| 92 | + geo_handler = pg.igeshandler.IgesHandler() |
| 93 | + elif file_extension_in == '.unv': |
| 94 | + geo_handler = pg.unvhandler.UnvHandler() |
| 95 | + elif file_extension_in == '': |
| 96 | + geo_handler = pg.openfhandler.OpenFoamHandler() |
| 97 | + elif file_extension_in == '.vtk': |
| 98 | + geo_handler = pg.vtkhandler.VtkHandler() |
| 99 | + else: |
| 100 | + raise NotImplementedError("Format not implemented yet") |
| 101 | + |
| 102 | + mesh_points = geo_handler.parse(self.filename_geometry) |
| 103 | + |
| 104 | + free_form = pg.freeform.FFD(params, mesh_points) |
| 105 | + free_form.perform() |
| 106 | + new_mesh_points = free_form.modified_mesh_points |
| 107 | + |
| 108 | + geo_handler.write(new_mesh_points, self.outfilename.get() + file_extension_in) |
| 109 | + |
| 110 | + if self.check_var_1.get() == 1: |
| 111 | + pg.utils.write_bounding_box(params, self.outfilename_lattice_orig.get() + '.vtk', False) |
| 112 | + if self.check_var_2.get() == 1: |
| 113 | + pg.utils.write_bounding_box(params, self.outfilename_lattice_mod.get() + '.vtk', True) |
| 114 | + |
| 115 | + |
| 116 | + def _goto_website(self): |
| 117 | + """ |
| 118 | + The private method opens the PyGeM main page on github. |
| 119 | + It is used for info about PyGeM in the menu. |
| 120 | + """ |
| 121 | + webbrowser.open(self.url) |
| 122 | + |
| 123 | + |
| 124 | + def start(self): |
| 125 | + """ |
| 126 | + The method inizializes and visualizes the window. |
| 127 | + """ |
| 128 | + |
| 129 | + image = Image.open('readme/logo_PyGeM_small.png') |
| 130 | + image = image.resize((50, 50), Image.ANTIALIAS) |
| 131 | + img = ImageTk.PhotoImage(image) |
| 132 | + panel = Label(self.root, image = img) |
| 133 | + panel.pack(side = "bottom", padx = 5, pady = 5,anchor=SE) |
| 134 | + |
| 135 | + geo_frame = Frame(self.root) |
| 136 | + geo_frame.pack(anchor=W) |
| 137 | + |
| 138 | + # Buttons 1 |
| 139 | + button_1 = Tkinter.Button(geo_frame, text ="Pick the geometry", command = self._chose_geometry) |
| 140 | + button_1.pack(side=LEFT, padx = 5, pady = 5) |
| 141 | + self.label_geo=Label(geo_frame, textvariable=self.print_geometry_path, fg='red') |
| 142 | + self.print_geometry_path.set("No geometry chosen!") |
| 143 | + self.label_geo.pack(side=LEFT, padx = 5, pady = 5) |
| 144 | + |
| 145 | + # Button 2 |
| 146 | + params_frame = Frame(self.root) |
| 147 | + params_frame.pack(anchor=W) |
| 148 | + |
| 149 | + button_2 = Tkinter.Button(params_frame, text ="Pick the parameters", command = self._chose_parameters) |
| 150 | + button_2.pack(side=LEFT, padx = 5, pady = 5) |
| 151 | + self.label_params = Label( params_frame, textvariable=self.print_parameter_path, fg='red') |
| 152 | + self.print_parameter_path.set("No parameters file chosen!") |
| 153 | + self.label_params.pack(side=LEFT, padx = 5, pady = 5) |
| 154 | + |
| 155 | + # Entry |
| 156 | + entryframe = Frame(self.root) |
| 157 | + entryframe.pack(padx = 5, pady = 5, anchor=W) |
| 158 | + |
| 159 | + label_geo_out = Label(entryframe, text="Output geometry file") |
| 160 | + label_geo_out.pack( side = LEFT) |
| 161 | + entry_geo_out = Entry(entryframe, bd =5, textvariable=self.outfilename) |
| 162 | + entry_geo_out.pack(side = LEFT) |
| 163 | + |
| 164 | + # Checkboxes |
| 165 | + checkframe_orig = Frame(self.root) |
| 166 | + checkframe_orig.pack(anchor=W) |
| 167 | + |
| 168 | + check_lattice_orig = Checkbutton(checkframe_orig, text = "Dump Original FFD lattice", variable = self.check_var_1, \ |
| 169 | + onvalue = 1, offvalue = 0, height=3, \ |
| 170 | + width = 20) |
| 171 | + |
| 172 | + check_lattice_orig.pack(side=LEFT) |
| 173 | + |
| 174 | + entry_lattice_orig = Entry(checkframe_orig, bd =5, textvariable=self.outfilename_lattice_orig) |
| 175 | + entry_lattice_orig.pack(side = LEFT) |
| 176 | + |
| 177 | + checkframe_mod = Frame(self.root) |
| 178 | + checkframe_mod.pack(anchor=W) |
| 179 | + |
| 180 | + check_lattice_mod = Checkbutton(checkframe_mod, text = "Dump Morphed FFD lattice", variable = self.check_var_2, \ |
| 181 | + onvalue = 1, offvalue = 0, height=3, \ |
| 182 | + width = 20) |
| 183 | + |
| 184 | + check_lattice_mod.pack(side=LEFT) |
| 185 | + |
| 186 | + entry_lattice_mod = Entry(checkframe_mod, bd =5, textvariable=self.outfilename_lattice_mod) |
| 187 | + entry_lattice_mod.pack(side = LEFT) |
| 188 | + |
| 189 | + # Run button |
| 190 | + button_run = Tkinter.Button(self.root, text ="Run PyGeM", command = self._run_simulation, bg='#065893', fg='#f19625', font='bold') |
| 191 | + button_run.pack() |
| 192 | + |
| 193 | + # Menu |
| 194 | + menubar = Menu(self.root) |
| 195 | + |
| 196 | + helpmenu = Menu(menubar, tearoff=0) |
| 197 | + helpmenu.add_command(label="About...", command=self._goto_website) |
| 198 | + menubar.add_cascade(label="Help", menu=helpmenu) |
| 199 | + |
| 200 | + self.root.config(menu=menubar) |
| 201 | + |
| 202 | + self.root.mainloop() |
| 203 | + |
0 commit comments