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
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-10 11:04 +0000
1from os import unlink
3import numpy as np
5import ase.gui.ui as ui
6from ase.gui.i18n import _
7from ase.io.pov import get_bondpairs, write_pov
9pack = error = Help = 42
12class Render:
13 texture_list = ['ase2', 'ase3', 'glass', 'simple', 'pale',
14 'intermediate', 'vmd', 'jmol']
15 cameras = ['orthographic', 'perspective', 'ultra_wide_angle']
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)))
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])
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'))])
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])
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()
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
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])
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')
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))
76 def get_guisize(self):
77 win = self.gui.window.win
78 return win.winfo_width(), win.winfo_height()
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
92 plotting_var_settings = {
93 'bbox': bbox,
94 'rotation': self.gui.axes,
95 'show_unit_cell': self.cell_widget.value
96 }
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 }
108 multiframe = bool(self.frames_widget.value)
109 if multiframe:
110 assert len(self.gui.images) > 1
112 if multiframe:
113 frames = range(len(self.gui.images))
114 else:
115 frames = [self.gui.frame]
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()
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)
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