Coverage for /builds/kinetik161/ase/ase/gui/render.py: 86.79%

106 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-12-10 11:04 +0000

1from os import unlink 

2 

3import numpy as np 

4 

5import ase.gui.ui as ui 

6from ase.gui.i18n import _ 

7from ase.io.pov import get_bondpairs, write_pov 

8 

9pack = error = Help = 42 

10 

11 

12class Render: 

13 texture_list = ['ase2', 'ase3', 'glass', 'simple', 'pale', 

14 'intermediate', 'vmd', 'jmol'] 

15 cameras = ['orthographic', 'perspective', 'ultra_wide_angle'] 

16 

17 def __init__(self, gui): 

18 self.gui = gui 

19 self.win = win = ui.Window( 

20 _('Render current view in povray ... '), wmtype='utility') 

21 win.add(ui.Label(_("Rendering %d atoms.") % len(self.gui.atoms))) 

22 

23 guiwidth, guiheight = self.get_guisize() 

24 self.width_widget = ui.SpinBox(guiwidth, start=1, end=9999, step=1) 

25 self.height_widget = ui.SpinBox(guiheight, start=1, end=9999, step=1) 

26 win.add([ui.Label(_('Size')), self.width_widget, 

27 ui.Label('⨯'), self.height_widget]) 

28 

29 self.linewidth_widget = ui.SpinBox(0.07, start=0.01, end=9.99, 

30 step=0.01) 

31 win.add([ui.Label(_('Line width')), self.linewidth_widget, 

32 ui.Label(_('Ångström'))]) 

33 

34 self.constraints_widget = ui.CheckButton(_("Render constraints")) 

35 self.cell_widget = ui.CheckButton(_("Render unit cell"), value=True) 

36 win.add([self.cell_widget, self.constraints_widget]) 

37 

38 formula = gui.atoms.get_chemical_formula(mode='hill') 

39 self.basename_widget = ui.Entry(width=30, value=formula, 

40 callback=self.update_outputname) 

41 win.add([ui.Label(_('Output basename: ')), self.basename_widget]) 

42 self.povray_executable = ui.Entry(width=30, value='povray') 

43 win.add([ui.Label(_('POVRAY executable')), self.povray_executable]) 

44 self.outputname_widget = ui.Label() 

45 win.add([ui.Label(_('Output filename: ')), self.outputname_widget]) 

46 self.update_outputname() 

47 

48 self.texture_widget = ui.ComboBox(labels=self.texture_list, 

49 values=self.texture_list) 

50 win.add([ui.Label(_('Atomic texture set:')), 

51 self.texture_widget]) 

52 # complicated texture stuff 

53 

54 self.camera_widget = ui.ComboBox(labels=self.cameras, 

55 values=self.cameras) 

56 self.camera_distance_widget = ui.SpinBox(50.0, -99.0, 99.0, 1.0) 

57 win.add([ui.Label(_('Camera type: ')), self.camera_widget]) 

58 win.add([ui.Label(_('Camera distance')), self.camera_distance_widget]) 

59 

60 # render current frame/all frames 

61 self.frames_widget = ui.RadioButtons([_('Render current frame'), 

62 _('Render all frames')]) 

63 win.add(self.frames_widget) 

64 if len(gui.images) == 1: 

65 self.frames_widget.buttons[1].widget.configure(state='disabled') 

66 

67 self.run_povray_widget = ui.CheckButton(_('Run povray'), True) 

68 self.keep_files_widget = ui.CheckButton(_('Keep povray files'), False) 

69 self.show_output_widget = ui.CheckButton(_('Show output window'), True) 

70 self.transparent = ui.CheckButton(_("Transparent background"), True) 

71 win.add(self.transparent) 

72 win.add([self.run_povray_widget, self.keep_files_widget, 

73 self.show_output_widget]) 

74 win.add(ui.Button(_('Render'), self.ok)) 

75 

76 def get_guisize(self): 

77 win = self.gui.window.win 

78 return win.winfo_width(), win.winfo_height() 

79 

80 def ok(self, *args): 

81 print("Rendering with povray:") 

82 guiwidth, guiheight = self.get_guisize() 

83 width = self.width_widget.value 

84 height = self.height_widget.value 

85 # (Do width/height become inconsistent upon gui resize? Not critical) 

86 scale = self.gui.scale * height / guiheight 

87 bbox = np.empty(4) 

88 size = np.array([width, height]) / scale 

89 bbox[0:2] = np.dot(self.gui.center, self.gui.axes[:, :2]) - size / 2 

90 bbox[2:] = bbox[:2] + size 

91 

92 plotting_var_settings = { 

93 'bbox': bbox, 

94 'rotation': self.gui.axes, 

95 'show_unit_cell': self.cell_widget.value 

96 } 

97 

98 povray_settings = { 

99 'display': self.show_output_widget.value, 

100 'transparent': self.transparent.value, 

101 'camera_type': self.camera_widget.value, 

102 'camera_dist': self.camera_distance_widget.value, 

103 'canvas_width': width, 

104 'celllinewidth': self.linewidth_widget.value, 

105 'exportconstraints': self.constraints_widget.value, 

106 } 

107 

108 multiframe = bool(self.frames_widget.value) 

109 if multiframe: 

110 assert len(self.gui.images) > 1 

111 

112 if multiframe: 

113 frames = range(len(self.gui.images)) 

114 else: 

115 frames = [self.gui.frame] 

116 

117 initial_frame = self.gui.frame 

118 for frame in frames: 

119 self.gui.set_frame(frame) 

120 povray_settings['textures'] = self.get_textures() 

121 povray_settings['colors'] = self.gui.get_colors(rgb=True) 

122 atoms = self.gui.images.get_atoms(frame) 

123 radii_scale = 1 # atom size multiplier 

124 # self.gui.config['show_bonds'] is always False 

125 if self.gui.window['toggle-show-bonds']: 

126 print(" | Building bonds") 

127 povray_settings['bondatoms'] = get_bondpairs(atoms) 

128 radii_scale = 0.65 # value from draw method of View class 

129 filename = self.update_outputname() 

130 print(" | Writing files for image", filename, "...") 

131 plotting_var_settings['radii'] = radii_scale * \ 

132 self.gui.get_covalent_radii() 

133 renderer = write_pov( 

134 filename, atoms, 

135 povray_settings=povray_settings, 

136 **plotting_var_settings) 

137 if self.run_povray_widget.value: 

138 renderer.render( 

139 povray_executable=self.povray_executable.value, 

140 clean_up=False) 

141 if not self.keep_files_widget.value: 

142 print(" | Deleting temporary file ", filename) 

143 unlink(filename) 

144 filename = filename[:-4] + '.ini' 

145 print(" | Deleting temporary file ", filename) 

146 unlink(filename) 

147 self.gui.set_frame(initial_frame) 

148 self.update_outputname() 

149 

150 def update_outputname(self): 

151 tokens = [self.basename_widget.value] 

152 movielen = len(self.gui.images) 

153 if movielen > 1: 

154 ndigits = len(str(movielen)) 

155 token = ('{:0' + str(ndigits) + 'd}').format(self.gui.frame) 

156 tokens.append(token) 

157 tokens.append('pov') 

158 fname = '.'.join(tokens) 

159 self.outputname_widget.text = fname 

160 return fname 

161 # if self.movie.get_active(): 

162 # while len(movie_index) + len(str(self.iframe)) < len( 

163 # str(self.nimages)): 

164 # movie_index += '0' 

165 # movie_index = '.' + movie_index + str(self.iframe) 

166 # name = self.basename.get_text() + movie_index + '.pov' 

167 # self.outputname.set_text(name) 

168 

169 def get_textures(self): 

170 return [self.texture_widget.value] * len(self.gui.atoms) 

171 # natoms = len(self.gui.atoms) 

172 # textures = natoms * [ 

173 # self.texture_list[0] #self.default_texture.get_active()] 

174 # ] 

175 # for mat in self.materials: 

176 # sel = mat[1] 

177 # t = self.finish_list[mat[2].get_active()] 

178 # if mat[0]: 

179 # for n, val in enumerate(sel): 

180 # if val: 

181 # textures[n] = t 

182 # return textures