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

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from ase.gui.i18n import _
2import ase.gui.ui as ui
3from ase.io.pov import write_pov, get_bondpairs
4from os import unlink
5import numpy as np
7pack = error = Help = 42
10class Render:
11 texture_list = ['ase2', 'ase3', 'glass', 'simple', 'pale',
12 'intermediate', 'vmd', 'jmol']
13 cameras = ['orthographic', 'perspective', 'ultra_wide_angle']
15 def __init__(self, gui):
16 self.gui = gui
17 self.win = win = ui.Window(
18 _('Render current view in povray ... '), wmtype='utility')
19 win.add(ui.Label(_("Rendering %d atoms.") % len(self.gui.atoms)))
21 guiwidth, guiheight = self.get_guisize()
22 self.width_widget = ui.SpinBox(guiwidth, start=1, end=9999, step=1)
23 self.height_widget = ui.SpinBox(guiheight, start=1, end=9999, step=1)
24 win.add([ui.Label(_('Size')), self.width_widget,
25 ui.Label('⨯'), self.height_widget])
27 self.linewidth_widget = ui.SpinBox(0.07, start=0.01, end=9.99,
28 step=0.01)
29 win.add([ui.Label(_('Line width')), self.linewidth_widget,
30 ui.Label(_('Ångström'))])
32 self.constraints_widget = ui.CheckButton(_("Render constraints"))
33 self.cell_widget = ui.CheckButton(_("Render unit cell"), value=True)
34 win.add([self.cell_widget, self.constraints_widget])
36 formula = gui.atoms.get_chemical_formula(mode='hill')
37 self.basename_widget = ui.Entry(width=30, value=formula,
38 callback=self.update_outputname)
39 win.add([ui.Label(_('Output basename: ')), self.basename_widget])
40 self.povray_executable = ui.Entry(width=30, value='povray')
41 win.add([ui.Label(_('POVRAY executable')), self.povray_executable])
42 self.outputname_widget = ui.Label()
43 win.add([ui.Label(_('Output filename: ')), self.outputname_widget])
44 self.update_outputname()
46 self.texture_widget = ui.ComboBox(labels=self.texture_list,
47 values=self.texture_list)
48 win.add([ui.Label(_('Atomic texture set:')),
49 self.texture_widget])
50 # complicated texture stuff
52 self.camera_widget = ui.ComboBox(labels=self.cameras,
53 values=self.cameras)
54 self.camera_distance_widget = ui.SpinBox(50.0, -99.0, 99.0, 1.0)
55 win.add([ui.Label(_('Camera type: ')), self.camera_widget])
56 win.add([ui.Label(_('Camera distance')), self.camera_distance_widget])
58 # render current frame/all frames
59 self.frames_widget = ui.RadioButtons([_('Render current frame'),
60 _('Render all frames')])
61 win.add(self.frames_widget)
62 if len(gui.images) == 1:
63 self.frames_widget.buttons[1].widget.configure(state='disabled')
65 self.run_povray_widget = ui.CheckButton(_('Run povray'), True)
66 self.keep_files_widget = ui.CheckButton(_('Keep povray files'), False)
67 self.show_output_widget = ui.CheckButton(_('Show output window'), True)
68 self.transparent = ui.CheckButton(_("Transparent background"), True)
69 win.add(self.transparent)
70 win.add([self.run_povray_widget, self.keep_files_widget,
71 self.show_output_widget])
72 win.add(ui.Button(_('Render'), self.ok))
74 def get_guisize(self):
75 win = self.gui.window.win
76 return win.winfo_width(), win.winfo_height()
78 def ok(self, *args):
79 print("Rendering with povray:")
80 guiwidth, guiheight = self.get_guisize()
81 width = self.width_widget.value
82 height = self.height_widget.value
83 # (Do width/height become inconsistent upon gui resize? Not critical)
84 scale = self.gui.scale * height / guiheight
85 bbox = np.empty(4)
86 size = np.array([width, height]) / scale
87 bbox[0:2] = np.dot(self.gui.center, self.gui.axes[:, :2]) - size / 2
88 bbox[2:] = bbox[:2] + size
90 plotting_var_settings = {
91 'bbox': bbox,
92 'rotation': self.gui.axes,
93 'show_unit_cell': self.cell_widget.value
94 }
96 povray_settings = {
97 'display': self.show_output_widget.value,
98 'transparent': self.transparent.value,
99 'camera_type': self.camera_widget.value,
100 'camera_dist': self.camera_distance_widget.value,
101 'canvas_width': width,
102 'celllinewidth': self.linewidth_widget.value,
103 'exportconstraints': self.constraints_widget.value,
104 }
106 multiframe = bool(self.frames_widget.value)
107 if multiframe:
108 assert len(self.gui.images) > 1
110 if multiframe:
111 frames = range(len(self.gui.images))
112 else:
113 frames = [self.gui.frame]
115 initial_frame = self.gui.frame
116 for frame in frames:
117 self.gui.set_frame(frame)
118 povray_settings['textures'] = self.get_textures()
119 povray_settings['colors'] = self.gui.get_colors(rgb=True)
120 atoms = self.gui.images.get_atoms(frame)
121 radii_scale = 1 # atom size multiplier
122 # self.gui.config['show_bonds'] is always False
123 if self.gui.window['toggle-show-bonds']:
124 print(" | Building bonds")
125 povray_settings['bondatoms'] = get_bondpairs(atoms)
126 radii_scale = 0.65 # value from draw method of View class
127 filename = self.update_outputname()
128 print(" | Writing files for image", filename, "...")
129 plotting_var_settings['radii'] = radii_scale * \
130 self.gui.get_covalent_radii()
131 renderer = write_pov(
132 filename, atoms,
133 povray_settings=povray_settings,
134 **plotting_var_settings)
135 if self.run_povray_widget.value:
136 renderer.render(
137 povray_executable=self.povray_executable.value,
138 clean_up=False)
139 if not self.keep_files_widget.value:
140 print(" | Deleting temporary file ", filename)
141 unlink(filename)
142 filename = filename[:-4] + '.ini'
143 print(" | Deleting temporary file ", filename)
144 unlink(filename)
145 self.gui.set_frame(initial_frame)
146 self.update_outputname()
148 def update_outputname(self):
149 tokens = [self.basename_widget.value]
150 movielen = len(self.gui.images)
151 if movielen > 1:
152 ndigits = len(str(movielen))
153 token = ('{:0' + str(ndigits) + 'd}').format(self.gui.frame)
154 tokens.append(token)
155 tokens.append('pov')
156 fname = '.'.join(tokens)
157 self.outputname_widget.text = fname
158 return fname
159 # if self.movie.get_active():
160 # while len(movie_index) + len(str(self.iframe)) < len(
161 # str(self.nimages)):
162 # movie_index += '0'
163 # movie_index = '.' + movie_index + str(self.iframe)
164 # name = self.basename.get_text() + movie_index + '.pov'
165 # self.outputname.set_text(name)
167 def get_textures(self):
168 return [self.texture_widget.value] * len(self.gui.atoms)
169 # natoms = len(self.gui.atoms)
170 # textures = natoms * [
171 # self.texture_list[0] #self.default_texture.get_active()]
172 # ]
173 # for mat in self.materials:
174 # sel = mat[1]
175 # t = self.finish_list[mat[2].get_active()]
176 # if mat[0]:
177 # for n, val in enumerate(sel):
178 # if val:
179 # textures[n] = t
180 # return textures