Hide keyboard shortcuts

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

1""" 

2Output support for X3D and X3DOM file types. 

3See http://www.web3d.org/x3d/specifications/ 

4X3DOM outputs to html pages that should display 3-d manipulatable atoms in 

5modern web browsers. 

6""" 

7 

8from ase.data import covalent_radii 

9from ase.data.colors import jmol_colors 

10from ase.utils import writer 

11 

12 

13@writer 

14def write_x3d(fd, atoms, format='X3D'): 

15 """Writes to html using X3DOM. 

16 

17 Args: 

18 filename - str or file-like object, filename or output file object 

19 atoms - Atoms object to be rendered 

20 format - str, either 'X3DOM' for web-browser compatibility or 'X3D' 

21 to be readable by Blender. `None` to detect format based on file 

22 extension ('.html' -> 'X3DOM', '.x3d' -> 'X3D')""" 

23 X3D(atoms).write(fd, datatype=format) 

24 

25 

26@writer 

27def write_html(fd, atoms): 

28 """Writes to html using X3DOM. 

29 

30 Args: 

31 filename - str or file-like object, filename or output file object 

32 atoms - Atoms object to be rendered""" 

33 write_x3d(fd, atoms, format='X3DOM') 

34 

35 

36class X3D: 

37 """Class to write either X3D (readable by open-source rendering 

38 programs such as Blender) or X3DOM html, readable by modern web 

39 browsers. 

40 """ 

41 

42 def __init__(self, atoms): 

43 self._atoms = atoms 

44 

45 def write(self, fileobj, datatype): 

46 """Writes output to either an 'X3D' or an 'X3DOM' file, based on 

47 the extension. For X3D, filename should end in '.x3d'. For X3DOM, 

48 filename should end in '.html'. 

49 

50 Args: 

51 datatype - str, output format. 'X3D' or 'X3DOM'. 

52 """ 

53 

54 # Write the header 

55 w = WriteToFile(fileobj) 

56 if datatype == 'X3DOM': 

57 w(0, '<html>') 

58 w(1, '<head>') 

59 w(2, '<title>ASE atomic visualization</title>') 

60 w(2, '<link rel="stylesheet" type="text/css"') 

61 w(2, ' href="https://www.x3dom.org/x3dom/release/x3dom.css">') 

62 w(2, '</link>') 

63 w(2, '<script type="text/javascript"') 

64 w(2, ' src="https://www.x3dom.org/x3dom/release/x3dom.js">') 

65 w(2, '</script>') 

66 w(1, '</head>') 

67 w(1, '<body>') 

68 w(2, '<X3D>') 

69 elif datatype == 'X3D': 

70 w(0, '<?xml version="1.0" encoding="UTF-8"?>') 

71 w(0, '<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" ' 

72 '"http://www.web3d.org/specifications/x3d-3.2.dtd">') 

73 w(0, '<X3D profile="Interchange" version="3.2" ' 

74 'xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" ' 

75 'xsd:noNamespaceSchemaLocation=' 

76 '"http://www.web3d.org/specifications/x3d-3.2.xsd">') 

77 else: 

78 raise ValueError("datatype not supported: " + str(datatype)) 

79 

80 w(3, '<Scene>') 

81 

82 for atom in self._atoms: 

83 for indent, line in atom_lines(atom): 

84 w(4 + indent, line) 

85 

86 w(3, '</Scene>') 

87 

88 if datatype == 'X3DOM': 

89 w(2, '</X3D>') 

90 w(1, '</body>') 

91 w(0, '</html>') 

92 elif datatype == 'X3D': 

93 w(0, '</X3D>') 

94 

95 

96class WriteToFile: 

97 """Creates convenience function to write to a file.""" 

98 

99 def __init__(self, fileobj): 

100 self._f = fileobj 

101 

102 def __call__(self, indent, line): 

103 text = ' ' * indent 

104 print('%s%s\n' % (text, line), file=self._f) 

105 

106 

107def atom_lines(atom): 

108 """Generates a segment of X3D lines representing an atom.""" 

109 x, y, z = atom.position 

110 lines = [(0, '<Transform translation="%.2f %.2f %.2f">' % (x, y, z))] 

111 lines += [(1, '<Shape>')] 

112 lines += [(2, '<Appearance>')] 

113 color = tuple(jmol_colors[atom.number]) 

114 color = 'diffuseColor="%.3f %.3f %.3f"' % color 

115 lines += [(3, '<Material %s specularColor="0.5 0.5 0.5">' % color)] 

116 lines += [(3, '</Material>')] 

117 lines += [(2, '</Appearance>')] 

118 lines += [(2, '<Sphere radius="%.2f">' % covalent_radii[atom.number])] 

119 lines += [(2, '</Sphere>')] 

120 lines += [(1, '</Shape>')] 

121 lines += [(0, '</Transform>')] 

122 return lines