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(_('Render current view in povray ... '))
18 win.add(ui.Label(_("Rendering %d atoms.") % len(self.gui.atoms)))
20 guiwidth, guiheight = self.get_guisize()
21 self.width_widget = ui.SpinBox(guiwidth, start=1, end=9999, step=1)
22 self.height_widget = ui.SpinBox(guiheight, start=1, end=9999, step=1)
23 win.add([ui.Label(_('Size')), self.width_widget,
24 ui.Label('⨯'), self.height_widget])
26 self.linewidth_widget = ui.SpinBox(0.07, start=0.01, end=9.99,
27 step=0.01)
28 win.add([ui.Label(_('Line width')), self.linewidth_widget,
29 ui.Label(_('Ångström'))])
31 self.constraints_widget = ui.CheckButton(_("Render constraints"))
32 self.cell_widget = ui.CheckButton(_("Render unit cell"), value=True)
33 win.add([self.cell_widget, self.constraints_widget])
35 formula = gui.atoms.get_chemical_formula(mode='hill')
36 self.basename_widget = ui.Entry(width=30, value=formula,
37 callback=self.update_outputname)
38 win.add([ui.Label(_('Output basename: ')), self.basename_widget])
39 self.povray_executable = ui.Entry(width=30, value='povray')
40 win.add([ui.Label(_('POVRAY executable')), self.povray_executable])
41 self.outputname_widget = ui.Label()
42 win.add([ui.Label(_('Output filename: ')), self.outputname_widget])
43 self.update_outputname()
45 self.texture_widget = ui.ComboBox(labels=self.texture_list,
46 values=self.texture_list)
47 win.add([ui.Label(_('Atomic texture set:')),
48 self.texture_widget])
49 # complicated texture stuff
51 self.camera_widget = ui.ComboBox(labels=self.cameras,
52 values=self.cameras)
53 self.camera_distance_widget = ui.SpinBox(50.0, -99.0, 99.0, 1.0)
54 win.add([ui.Label(_('Camera type: ')), self.camera_widget])
55 win.add([ui.Label(_('Camera distance')), self.camera_distance_widget])
57 # render current frame/all frames
58 self.frames_widget = ui.RadioButtons([_('Render current frame'),
59 _('Render all frames')])
60 win.add(self.frames_widget)
61 if len(gui.images) == 1:
62 self.frames_widget.buttons[1].widget.configure(state='disabled')
64 self.run_povray_widget = ui.CheckButton(_('Run povray'), True)
65 self.keep_files_widget = ui.CheckButton(_('Keep povray files'), False)
66 self.show_output_widget = ui.CheckButton(_('Show output window'), True)
67 self.transparent = ui.CheckButton(_("Transparent background"), True)
68 win.add(self.transparent)
69 win.add([self.run_povray_widget, self.keep_files_widget,
70 self.show_output_widget])
71 win.add(ui.Button(_('Render'), self.ok))
73 def get_guisize(self):
74 win = self.gui.window.win
75 return win.winfo_width(), win.winfo_height()
77 def ok(self, *args):
78 print("Rendering with povray:")
79 guiwidth, guiheight = self.get_guisize()
80 width = self.width_widget.value
81 height = self.height_widget.value
82 # (Do width/height become inconsistent upon gui resize? Not critical)
83 scale = self.gui.scale * height / guiheight
84 bbox = np.empty(4)
85 size = np.array([width, height]) / scale
86 bbox[0:2] = np.dot(self.gui.center, self.gui.axes[:, :2]) - size / 2
87 bbox[2:] = bbox[:2] + size
89 plotting_var_settings = {
90 'bbox': bbox,
91 'rotation': self.gui.axes,
92 'show_unit_cell': self.cell_widget.value
93 }
95 povray_settings = {
96 'display': self.show_output_widget.value,
97 'transparent': self.transparent.value,
98 'camera_type': self.camera_widget.value,
99 'camera_dist': self.camera_distance_widget.value,
100 'canvas_width': width,
101 'celllinewidth': self.linewidth_widget.value,
102 'exportconstraints': self.constraints_widget.value,
103 }
105 multiframe = bool(self.frames_widget.value)
106 if multiframe:
107 assert len(self.gui.images) > 1
109 if multiframe:
110 frames = range(len(self.gui.images))
111 else:
112 frames = [self.gui.frame]
114 initial_frame = self.gui.frame
115 for frame in frames:
116 self.gui.set_frame(frame)
117 povray_settings['textures'] = self.get_textures()
118 povray_settings['colors'] = self.gui.get_colors(rgb=True)
119 atoms = self.gui.images.get_atoms(frame)
120 radii_scale = 1 # atom size multiplier
121 if self.gui.window['toggle-show-bonds']: # self.gui.config['show_bonds'] is always False
122 print(" | Building bonds")
123 povray_settings['bondatoms'] = get_bondpairs(atoms)
124 radii_scale = 0.65 # value from draw method of View class
125 filename = self.update_outputname()
126 print(" | Writing files for image", filename, "...")
127 plotting_var_settings['radii'] = radii_scale*self.gui.get_covalent_radii()
128 renderer = write_pov(
129 filename, atoms,
130 povray_settings=povray_settings,
131 **plotting_var_settings)
132 if self.run_povray_widget.value:
133 renderer.render(povray_executable=self.povray_executable.value, clean_up=False)
134 if not self.keep_files_widget.value:
135 print(" | Deleting temporary file ", filename)
136 unlink(filename)
137 filename = filename[:-4] + '.ini'
138 print(" | Deleting temporary file ", filename)
139 unlink(filename)
140 self.gui.set_frame(initial_frame)
141 self.update_outputname()
143 def update_outputname(self):
144 tokens = [self.basename_widget.value]
145 movielen = len(self.gui.images)
146 if movielen > 1:
147 ndigits = len(str(movielen))
148 token = ('{:0' + str(ndigits) + 'd}').format(self.gui.frame)
149 tokens.append(token)
150 tokens.append('pov')
151 fname = '.'.join(tokens)
152 self.outputname_widget.text = fname
153 return fname
154 #if self.movie.get_active():
155 # while len(movie_index) + len(str(self.iframe)) < len(
156 # str(self.nimages)):
157 # movie_index += '0'
158 # movie_index = '.' + movie_index + str(self.iframe)
159 #name = self.basename.get_text() + movie_index + '.pov'
160 #self.outputname.set_text(name)
162 def get_textures(self):
163 return [self.texture_widget.value] * len(self.gui.atoms)
164 #natoms = len(self.gui.atoms)
165 #textures = natoms * [
166 #self.texture_list[0] #self.default_texture.get_active()]
167 #]
168 #for mat in self.materials:
169 # sel = mat[1]
170 # t = self.finish_list[mat[2].get_active()]
171 # if mat[0]:
172 # for n, val in enumerate(sel):
173 # if val:
174 # textures[n] = t
175 #return textures